converted first y-array test to funlib/testing
This commit is contained in:
		
							parent
							
								
									c5cc403a29
								
							
						
					
					
						commit
						93ee4ee287
					
				
							
								
								
									
										5167
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										5167
									
								
								package-lock.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							@ -79,11 +79,7 @@
 | 
			
		||||
    "rollup-plugin-uglify-es": "0.0.1",
 | 
			
		||||
    "rollup-watch": "^4.3.1",
 | 
			
		||||
    "standard": "^11.0.1",
 | 
			
		||||
    "tui-jsdoc-template": "^1.2.2",
 | 
			
		||||
    "y-codemirror": "*"
 | 
			
		||||
    "tui-jsdoc-template": "^1.2.2"
 | 
			
		||||
  },
 | 
			
		||||
  "dependencies": {
 | 
			
		||||
    "funlib": "file:../funlib",
 | 
			
		||||
    "y-protocols": "file:../y-protocols"
 | 
			
		||||
  }
 | 
			
		||||
  "dependencies": {}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -13,7 +13,7 @@ const customModules = new Set([
 | 
			
		||||
])
 | 
			
		||||
const customLibModules = new Set([
 | 
			
		||||
  // 'funlib',
 | 
			
		||||
  'y-protocols'
 | 
			
		||||
  // 'y-protocols'
 | 
			
		||||
])
 | 
			
		||||
const debugResolve = {
 | 
			
		||||
  resolveId (importee) {
 | 
			
		||||
 | 
			
		||||
@ -21,7 +21,7 @@ export { YXmlElement as XmlElement, YXmlFragment as XmlFragment } from './types/
 | 
			
		||||
 | 
			
		||||
export { getRelativePosition, fromRelativePosition, equal as equalRelativePosition } from './utils/relativePosition.js'
 | 
			
		||||
 | 
			
		||||
export { ID, createID, RootFakeUserID } from './utils/ID.js'
 | 
			
		||||
export { ID, createID, RootFakeUserID, RootID } from './utils/ID.js'
 | 
			
		||||
export { DeleteStore, DSNode } from './utils/DeleteStore.js'
 | 
			
		||||
export { deleteItemRange } from './utils/structManipulation.js'
 | 
			
		||||
export { integrateRemoteStruct, integrateRemoteStructs } from './utils/integrateRemoteStructs.js'
 | 
			
		||||
 | 
			
		||||
@ -51,10 +51,10 @@ export const testDeleteStore = tc => {
 | 
			
		||||
  t.compareArrays(dsToArray(ds), [null, 1, 1, 1, 1, 1])
 | 
			
		||||
  ds.mark(ID.createID(0, 0), 3, false)
 | 
			
		||||
  t.compareArrays(dsToArray(ds), [0, 0, 0, 1, 1, 1])
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  t.describe('Random tests')
 | 
			
		||||
export const testRepeatDeleteStoreTests = tc => {
 | 
			
		||||
  const gen = tc.prng
 | 
			
		||||
  for (let i = 0; i < tc.repititions; i++) {
 | 
			
		||||
  const ds = new DeleteStore()
 | 
			
		||||
  const dsArray = []
 | 
			
		||||
  for (let i = 0; i < 200; i++) {
 | 
			
		||||
@ -84,4 +84,3 @@ export const testDeleteStore = tc => {
 | 
			
		||||
  }
 | 
			
		||||
  t.assert(size === ds.length, 'DS sizes match')
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -1,10 +1,11 @@
 | 
			
		||||
 | 
			
		||||
import { runTests } from 'funlib/testing.js'
 | 
			
		||||
import * as deleteStore from './DeleteStore.tests.js'
 | 
			
		||||
import { isBrowser } from 'funlib/environment.js'
 | 
			
		||||
import * as log from 'funlib/logging.js'
 | 
			
		||||
import * as deleteStoreTest from './DeleteStore.tests.js'
 | 
			
		||||
import * as arrayTest from './y-array.tests.js'
 | 
			
		||||
 | 
			
		||||
if (isBrowser) {
 | 
			
		||||
  log.createVConsole(document.body)
 | 
			
		||||
}
 | 
			
		||||
runTests({ deleteStore })
 | 
			
		||||
runTests({ deleteStoreTest, arrayTest })
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										351
									
								
								tests/testHelper.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										351
									
								
								tests/testHelper.js
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,351 @@
 | 
			
		||||
import * as Y from '../src/index.js'
 | 
			
		||||
import * as t from 'funlib/testing.js'
 | 
			
		||||
import * as prng from 'funlib/prng.js'
 | 
			
		||||
import { createMutex } from 'funlib/mutex.js'
 | 
			
		||||
import * as encoding from 'funlib/encoding.js'
 | 
			
		||||
import * as decoding from 'funlib/decoding.js'
 | 
			
		||||
import * as syncProtocol from 'y-protocols/sync.js'
 | 
			
		||||
import { defragmentItemContent } from '../src/utils/defragmentItemContent.js'
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @param {TestYInstance} y
 | 
			
		||||
 * @param {Y.Transaction} transaction
 | 
			
		||||
 */
 | 
			
		||||
const afterTransaction = (y, transaction) => {
 | 
			
		||||
  y.mMux(() => {
 | 
			
		||||
    if (transaction.encodedStructsLen > 0) {
 | 
			
		||||
      const encoder = encoding.createEncoder()
 | 
			
		||||
      syncProtocol.writeUpdate(encoder, transaction.encodedStructsLen, transaction.encodedStructs)
 | 
			
		||||
      broadcastMessage(y, encoding.toBuffer(encoder))
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * @param {TestYInstance} y // publish message created by `y` to all other online clients
 | 
			
		||||
 * @param {ArrayBuffer} m
 | 
			
		||||
 */
 | 
			
		||||
const broadcastMessage = (y, m) => {
 | 
			
		||||
  if (y.tc.onlineConns.has(y)) {
 | 
			
		||||
    y.tc.onlineConns.forEach(remoteYInstance => {
 | 
			
		||||
      if (remoteYInstance !== y) {
 | 
			
		||||
        remoteYInstance._receive(m, y)
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export class TestYInstance extends Y.Y {
 | 
			
		||||
  /**
 | 
			
		||||
   * @param {TestConnector} testConnector
 | 
			
		||||
   */
 | 
			
		||||
  constructor (testConnector, clientID) {
 | 
			
		||||
    super()
 | 
			
		||||
    this.userID = clientID // overwriting clientID
 | 
			
		||||
    /**
 | 
			
		||||
     * @type {TestConnector}
 | 
			
		||||
     */
 | 
			
		||||
    this.tc = testConnector
 | 
			
		||||
    /**
 | 
			
		||||
     * @type {Map<TestYInstance, Array<ArrayBuffer>>}
 | 
			
		||||
     */
 | 
			
		||||
    this.receiving = new Map()
 | 
			
		||||
    /**
 | 
			
		||||
     * Message mutex
 | 
			
		||||
     * @type {Function}
 | 
			
		||||
     */
 | 
			
		||||
    this.mMux = createMutex()
 | 
			
		||||
    testConnector.allConns.add(this)
 | 
			
		||||
    // set up observe on local model
 | 
			
		||||
    this.on('afterTransaction', afterTransaction)
 | 
			
		||||
    this.connect()
 | 
			
		||||
  }
 | 
			
		||||
  /**
 | 
			
		||||
   * Disconnect from TestConnector.
 | 
			
		||||
   */
 | 
			
		||||
  disconnect () {
 | 
			
		||||
    this.receiving = new Map()
 | 
			
		||||
    this.tc.onlineConns.delete(this)
 | 
			
		||||
  }
 | 
			
		||||
  /**
 | 
			
		||||
   * Append yourself to the list of known Y instances in testconnector.
 | 
			
		||||
   * Also initiate sync with all clients.
 | 
			
		||||
   */
 | 
			
		||||
  connect () {
 | 
			
		||||
    if (!this.tc.onlineConns.has(this)) {
 | 
			
		||||
      this.tc.onlineConns.add(this)
 | 
			
		||||
      const encoder = encoding.createEncoder()
 | 
			
		||||
      syncProtocol.writeSyncStep1(encoder, this)
 | 
			
		||||
      // publish SyncStep1
 | 
			
		||||
      broadcastMessage(this, encoding.toBuffer(encoder))
 | 
			
		||||
      this.tc.onlineConns.forEach(remoteYInstance => {
 | 
			
		||||
        if (remoteYInstance !== this) {
 | 
			
		||||
          // remote instance sends instance to this instance
 | 
			
		||||
          const encoder = encoding.createEncoder()
 | 
			
		||||
          syncProtocol.writeSyncStep1(encoder, remoteYInstance)
 | 
			
		||||
          this._receive(encoding.toBuffer(encoder), remoteYInstance)
 | 
			
		||||
        }
 | 
			
		||||
      })
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
  /**
 | 
			
		||||
   * Receive a message from another client. This message is only appended to the list of receiving messages.
 | 
			
		||||
   * TestConnector decides when this client actually reads this message.
 | 
			
		||||
   *
 | 
			
		||||
   * @param {ArrayBuffer} message
 | 
			
		||||
   * @param {TestYInstance} remoteClient
 | 
			
		||||
   */
 | 
			
		||||
  _receive (message, remoteClient) {
 | 
			
		||||
    let messages = this.receiving.get(remoteClient)
 | 
			
		||||
    if (messages === undefined) {
 | 
			
		||||
      messages = []
 | 
			
		||||
      this.receiving.set(remoteClient, messages)
 | 
			
		||||
    }
 | 
			
		||||
    messages.push(message)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Keeps track of TestYInstances.
 | 
			
		||||
 *
 | 
			
		||||
 * The TestYInstances add/remove themselves from the list of connections maintained in this object.
 | 
			
		||||
 * I think it makes sense. Deal with it.
 | 
			
		||||
 */
 | 
			
		||||
export class TestConnector {
 | 
			
		||||
  constructor (gen) {
 | 
			
		||||
    /**
 | 
			
		||||
     * @type {Set<TestYInstance>}
 | 
			
		||||
     */
 | 
			
		||||
    this.allConns = new Set()
 | 
			
		||||
    /**
 | 
			
		||||
     * @type {Set<TestYInstance>}
 | 
			
		||||
     */
 | 
			
		||||
    this.onlineConns = new Set()
 | 
			
		||||
    /**
 | 
			
		||||
     * @type {prng.PRNG}
 | 
			
		||||
     */
 | 
			
		||||
    this.prng = gen
 | 
			
		||||
  }
 | 
			
		||||
  /**
 | 
			
		||||
   * Create a new Y instance and add it to the list of connections
 | 
			
		||||
   * @param {number} clientID
 | 
			
		||||
   */
 | 
			
		||||
  createY (clientID) {
 | 
			
		||||
    return new TestYInstance(this, clientID)
 | 
			
		||||
  }
 | 
			
		||||
  /**
 | 
			
		||||
   * Choose random connection and flush a random message from a random sender.
 | 
			
		||||
   *
 | 
			
		||||
   * If this function was unable to flush a message, because there are no more messages to flush, it returns false. true otherwise.
 | 
			
		||||
   * @return {boolean}
 | 
			
		||||
   */
 | 
			
		||||
  flushRandomMessage () {
 | 
			
		||||
    const gen = this.prng
 | 
			
		||||
    const conns = Array.from(this.onlineConns).filter(conn => conn.receiving.size > 0)
 | 
			
		||||
    if (conns.length > 0) {
 | 
			
		||||
      const receiver = prng.oneOf(gen, conns)
 | 
			
		||||
      const [sender, messages] = prng.oneOf(gen, Array.from(receiver.receiving))
 | 
			
		||||
      const m = messages.shift()
 | 
			
		||||
      if (messages.length === 0) {
 | 
			
		||||
        receiver.receiving.delete(sender)
 | 
			
		||||
      }
 | 
			
		||||
      if (m === undefined) {
 | 
			
		||||
        return this.flushRandomMessage()
 | 
			
		||||
      }
 | 
			
		||||
      const encoder = encoding.createEncoder()
 | 
			
		||||
      receiver.mMux(() => {
 | 
			
		||||
        console.log('receive (' + sender.userID + '->' + receiver.userID + '):\n', syncProtocol.stringifySyncMessage(decoding.createDecoder(m), receiver))
 | 
			
		||||
        // do not publish data created when this function is executed (could be ss2 or update message)
 | 
			
		||||
        syncProtocol.readSyncMessage(decoding.createDecoder(m), encoder, receiver)
 | 
			
		||||
      })
 | 
			
		||||
      if (encoding.length(encoder) > 0) {
 | 
			
		||||
        // send reply message
 | 
			
		||||
        sender._receive(encoding.toBuffer(encoder), receiver)
 | 
			
		||||
      }
 | 
			
		||||
      return true
 | 
			
		||||
    }
 | 
			
		||||
    return false
 | 
			
		||||
  }
 | 
			
		||||
  /**
 | 
			
		||||
   * @return {boolean} True iff this function actually flushed something
 | 
			
		||||
   */
 | 
			
		||||
  flushAllMessages () {
 | 
			
		||||
    let didSomething = false
 | 
			
		||||
    while (this.flushRandomMessage()) {
 | 
			
		||||
      didSomething = true
 | 
			
		||||
    }
 | 
			
		||||
    return didSomething
 | 
			
		||||
  }
 | 
			
		||||
  reconnectAll () {
 | 
			
		||||
    this.allConns.forEach(conn => conn.connect())
 | 
			
		||||
  }
 | 
			
		||||
  disconnectAll () {
 | 
			
		||||
    this.allConns.forEach(conn => conn.disconnect())
 | 
			
		||||
  }
 | 
			
		||||
  syncAll () {
 | 
			
		||||
    this.reconnectAll()
 | 
			
		||||
    this.flushAllMessages()
 | 
			
		||||
  }
 | 
			
		||||
  /**
 | 
			
		||||
   * @return {boolean} Whether it was possible to disconnect a randon connection.
 | 
			
		||||
   */
 | 
			
		||||
  disconnectRandom () {
 | 
			
		||||
    if (this.onlineConns.size === 0) {
 | 
			
		||||
      return false
 | 
			
		||||
    }
 | 
			
		||||
    prng.oneOf(this.prng, Array.from(this.onlineConns)).disconnect()
 | 
			
		||||
    return true
 | 
			
		||||
  }
 | 
			
		||||
  /**
 | 
			
		||||
   * @return {boolean} Whether it was possible to reconnect a random connection.
 | 
			
		||||
   */
 | 
			
		||||
  reconnectRandom () {
 | 
			
		||||
    const reconnectable = []
 | 
			
		||||
    this.allConns.forEach(conn => {
 | 
			
		||||
      if (!this.onlineConns.has(conn)) {
 | 
			
		||||
        reconnectable.push(conn)
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
    if (reconnectable.length === 0) {
 | 
			
		||||
      return false
 | 
			
		||||
    }
 | 
			
		||||
    prng.oneOf(this.prng, reconnectable).connect()
 | 
			
		||||
    return true
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export const init = (tc, { users = 5 } = {}) => {
 | 
			
		||||
  /**
 | 
			
		||||
   * @type {Object<string,any>}
 | 
			
		||||
   */
 | 
			
		||||
  const result = {
 | 
			
		||||
    users: []
 | 
			
		||||
  }
 | 
			
		||||
  const gen = tc.prng
 | 
			
		||||
  const testConnector = new TestConnector(gen)
 | 
			
		||||
  result.testConnector = testConnector
 | 
			
		||||
  for (let i = 0; i < users; i++) {
 | 
			
		||||
    const y = testConnector.createY(i)
 | 
			
		||||
    result.users.push(y)
 | 
			
		||||
    result['array' + i] = y.define('array', Y.Array)
 | 
			
		||||
    result['map' + i] = y.define('map', Y.Map)
 | 
			
		||||
    result['xml' + i] = y.define('xml', Y.XmlElement)
 | 
			
		||||
    result['text' + i] = y.define('text', Y.Text)
 | 
			
		||||
  }
 | 
			
		||||
  testConnector.syncAll()
 | 
			
		||||
  return result
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Convert DS to a proper DeleteSet of Map.
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Y.Y} y
 | 
			
		||||
 * @return {Object<number, Array<[number, number, boolean]>>}
 | 
			
		||||
 */
 | 
			
		||||
const getDeleteSet = y => {
 | 
			
		||||
  /**
 | 
			
		||||
   * @type {Object<number, Array<[number, number, boolean]>}
 | 
			
		||||
   */
 | 
			
		||||
  var ds = {}
 | 
			
		||||
  y.ds.iterate(null, null, n => {
 | 
			
		||||
    var user = n._id.user
 | 
			
		||||
    var counter = n._id.clock
 | 
			
		||||
    var len = n.len
 | 
			
		||||
    var gc = n.gc
 | 
			
		||||
    var dv = ds[user]
 | 
			
		||||
    if (dv === void 0) {
 | 
			
		||||
      dv = []
 | 
			
		||||
      ds[user] = dv
 | 
			
		||||
    }
 | 
			
		||||
    dv.push([counter, len, gc])
 | 
			
		||||
  })
 | 
			
		||||
  return ds
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const customOSCompare = (constructor, a, b, path, next) => {
 | 
			
		||||
  switch (constructor) {
 | 
			
		||||
    case Y.ID:
 | 
			
		||||
    case Y.RootID:
 | 
			
		||||
      if (a.equals(b)) {
 | 
			
		||||
        return true
 | 
			
		||||
      } else {
 | 
			
		||||
        return false
 | 
			
		||||
      }
 | 
			
		||||
  }
 | 
			
		||||
  return next(constructor, a, b, path, next)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * 1. reconnect and flush all
 | 
			
		||||
 * 2. user 0 gc
 | 
			
		||||
 * 3. get type content
 | 
			
		||||
 * 4. disconnect & reconnect all (so gc is propagated)
 | 
			
		||||
 * 5. compare os, ds, ss
 | 
			
		||||
 *
 | 
			
		||||
 * @param {Array<TestYInstance>} users
 | 
			
		||||
 */
 | 
			
		||||
export const compare = users => {
 | 
			
		||||
  users.forEach(u => u.connect())
 | 
			
		||||
  while (users[0].tc.flushAllMessages()) {}
 | 
			
		||||
  var userArrayValues = users.map(u => u.define('array', Y.Array).toJSON().map(val => JSON.stringify(val)))
 | 
			
		||||
  var userMapValues = users.map(u => u.define('map', Y.Map).toJSON())
 | 
			
		||||
  var userXmlValues = users.map(u => u.define('xml', Y.XmlElement).toString())
 | 
			
		||||
  var userTextValues = users.map(u => u.define('text', Y.Text).toDelta())
 | 
			
		||||
  var data = users.map(u => {
 | 
			
		||||
    defragmentItemContent(u)
 | 
			
		||||
    var data = {}
 | 
			
		||||
    let ops = []
 | 
			
		||||
    u.os.iterate(null, null, op => {
 | 
			
		||||
      let json
 | 
			
		||||
      if (op.constructor === Y.GC) {
 | 
			
		||||
        json = {
 | 
			
		||||
          type: 'GC',
 | 
			
		||||
          id: op._id,
 | 
			
		||||
          length: op._length,
 | 
			
		||||
          content: null
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        json = {
 | 
			
		||||
          id: op._id,
 | 
			
		||||
          left: op._left === null ? null : op._left._lastId,
 | 
			
		||||
          right: op._right === null ? null : op._right._id,
 | 
			
		||||
          length: op._length,
 | 
			
		||||
          deleted: op._deleted,
 | 
			
		||||
          parent: op._parent._id,
 | 
			
		||||
          content: null
 | 
			
		||||
        }
 | 
			
		||||
      }
 | 
			
		||||
      if (op instanceof Y.ItemJSON || op instanceof Y.ItemString) {
 | 
			
		||||
        json.content = op._content
 | 
			
		||||
      }
 | 
			
		||||
      ops.push(json)
 | 
			
		||||
    })
 | 
			
		||||
    data.os = ops
 | 
			
		||||
    data.ds = getDeleteSet(u)
 | 
			
		||||
    const ss = {}
 | 
			
		||||
    u.ss.state.forEach((clock, user) => {
 | 
			
		||||
      ss[user] = clock
 | 
			
		||||
    })
 | 
			
		||||
    data.ss = ss
 | 
			
		||||
    return data
 | 
			
		||||
  })
 | 
			
		||||
  for (var i = 0; i < data.length - 1; i++) {
 | 
			
		||||
    t.describe(`Comparing user${i} with user${i + 1}`)
 | 
			
		||||
    t.compare(userArrayValues[i].length, users[i].get('array').length, 'array length correctly computed')
 | 
			
		||||
    t.compare(userArrayValues[i], userArrayValues[i + 1], 'array types')
 | 
			
		||||
    t.compare(userMapValues[i], userMapValues[i + 1], 'map types')
 | 
			
		||||
    t.compare(userXmlValues[i], userXmlValues[i + 1], 'xml types')
 | 
			
		||||
    t.compare(userTextValues[i].map(a => a.insert).join('').length, users[i].get('text').length, 'text length correctly computed')
 | 
			
		||||
    t.compare(userTextValues[i], userTextValues[i + 1], 'text types')
 | 
			
		||||
    t.compare(data[i].os, data[i + 1].os, 'os', customOSCompare)
 | 
			
		||||
    t.compare(data[i].ds, data[i + 1].ds, 'ds', customOSCompare)
 | 
			
		||||
    t.compare(data[i].ss, data[i + 1].ss, 'ss', customOSCompare)
 | 
			
		||||
  }
 | 
			
		||||
  users.forEach(user => {
 | 
			
		||||
    if (user._missingStructs.size !== 0) {
 | 
			
		||||
      t.fail('missing structs should be empty!')
 | 
			
		||||
    }
 | 
			
		||||
  })
 | 
			
		||||
  users.map(u => u.destroy())
 | 
			
		||||
}
 | 
			
		||||
@ -1,15 +1,11 @@
 | 
			
		||||
import { initArrays, compareUsers, applyRandomTests } from './helper.js'
 | 
			
		||||
import { init, compare } from './testHelper.js'
 | 
			
		||||
import * as Y from '../src/index.js'
 | 
			
		||||
import { test, proxyConsole } from 'cutest'
 | 
			
		||||
import * as random from 'funlib/prng/prng.js'
 | 
			
		||||
 | 
			
		||||
proxyConsole()
 | 
			
		||||
test('basic spec', async function array0 (t) {
 | 
			
		||||
  let { users, array0 } = await initArrays(t, { users: 2 })
 | 
			
		||||
import * as t from 'funlib/testing.js'
 | 
			
		||||
 | 
			
		||||
export const testDeleteInsert = tc => {
 | 
			
		||||
  let { users, array0 } = init(tc, { users: 2 })
 | 
			
		||||
  array0.delete(0, 0)
 | 
			
		||||
  t.assert(true, 'Does not throw when deleting zero elements with position 0')
 | 
			
		||||
 | 
			
		||||
  let throwInvalidPosition = false
 | 
			
		||||
  try {
 | 
			
		||||
    array0.delete(1, 1)
 | 
			
		||||
@ -17,13 +13,13 @@ test('basic spec', async function array0 (t) {
 | 
			
		||||
    throwInvalidPosition = true
 | 
			
		||||
  }
 | 
			
		||||
  t.assert(throwInvalidPosition, 'Throws when deleting with an invalid position')
 | 
			
		||||
 | 
			
		||||
  array0.insert(0, ['A'])
 | 
			
		||||
  array0.delete(1, 0)
 | 
			
		||||
  t.assert(true, 'Does not throw when deleting zero elements with valid position 1')
 | 
			
		||||
  compare(users)
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
  await compareUsers(t, users)
 | 
			
		||||
})
 | 
			
		||||
/*
 | 
			
		||||
 | 
			
		||||
test('insert three elements, try re-get property', async function array1 (t) {
 | 
			
		||||
  var { testConnector, users, array0, array1 } = initArrays(t, { users: 2 })
 | 
			
		||||
@ -333,3 +329,4 @@ test('y-array: Random tests (1000)', async function randomArray1000 (t) {
 | 
			
		||||
test('y-array: Random tests (1800)', async function randomArray1800 (t) {
 | 
			
		||||
  await applyRandomTests(t, arrayTransactions, 2000)
 | 
			
		||||
})
 | 
			
		||||
*/
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user