import { expect } from 'chai' ; import { ArrayExt } from '@lumino/algorithm' ; describe ( '@lumino/algorithm' , ( ) => { describe ( 'ArrayExt' , ( ) => { describe ( 'firstIndexOf()' , ( ) => { it ( 'should find the index of the first matching value' , ( ) => { let data = [ 'one' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . firstIndexOf ( data , 'one' ) ; expect ( i ) . to . equal ( 0 ) ; } ) ; it ( 'should return `-1` if there is no matching value' , ( ) => { let data = [ 'one' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . firstIndexOf ( data , 'red' ) ; expect ( i ) . to . equal ( - 1 ) ; } ) ; it ( 'should return `-1` if the array is empty' , ( ) => { let data = [ ] ; let i = ArrayExt . firstIndexOf ( data , 'one' ) ; expect ( i ) . to . equal ( - 1 ) ; } ) ; it ( 'should support searching from a start index' , ( ) => { let data = [ 'one' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . firstIndexOf ( data , 'one' , 2 ) ; expect ( i ) . to . equal ( 4 ) ; } ) ; it ( 'should support a negative start index' , ( ) => { let data = [ 'one' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . firstIndexOf ( data , 'one' , - 2 ) ; expect ( i ) . to . equal ( 4 ) ; } ) ; it ( 'should support searching within a range' , ( ) => { let data = [ 'one' , 'two' , 'one' , 'four' , 'one' ] ; let i = ArrayExt . firstIndexOf ( data , 'one' , 1 , 3 ) ; expect ( i ) . to . equal ( 2 ) ; } ) ; it ( 'should support a negative stop index' , ( ) => { let data = [ 'one' , 'two' , 'one' , 'four' , 'one' ] ; let i = ArrayExt . firstIndexOf ( data , 'one' , 1 , - 4 ) ; expect ( i ) . to . equal ( - 1 ) ; } ) ; it ( 'should wrap around if stop < start' , ( ) => { let data = [ 'one' , 'two' , 'one' , 'four' , 'one' ] ; let i = ArrayExt . firstIndexOf ( data , 'two' , 3 , 2 ) ; expect ( i ) . to . equal ( 1 ) ; } ) ; } ) ; describe ( 'lastIndexOf()' , ( ) => { it ( 'should find the index of the last matching value' , ( ) => { let data = [ 'one' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . lastIndexOf ( data , 'one' ) ; expect ( i ) . to . equal ( 4 ) ; } ) ; it ( 'should return `-1` if there is no matching value' , ( ) => { let data = [ 'one' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . lastIndexOf ( data , 'red' ) ; expect ( i ) . to . equal ( - 1 ) ; } ) ; it ( 'should return `-1` if the array is empty' , ( ) => { let data = [ ] ; let i = ArrayExt . lastIndexOf ( data , 'one' ) ; expect ( i ) . to . equal ( - 1 ) ; } ) ; it ( 'should support searching from a start index' , ( ) => { let data = [ 'one' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . lastIndexOf ( data , 'one' , 2 ) ; expect ( i ) . to . equal ( 0 ) ; } ) ; it ( 'should support a negative start index' , ( ) => { let data = [ 'one' , 'two' , 'one' , 'four' , 'one' ] ; let i = ArrayExt . lastIndexOf ( data , 'one' , - 2 ) ; expect ( i ) . to . equal ( 2 ) ; } ) ; it ( 'should support searching within a range' , ( ) => { let data = [ 'one' , 'two' , 'one' , 'four' , 'one' ] ; let i = ArrayExt . lastIndexOf ( data , 'one' , 3 , 1 ) ; expect ( i ) . to . equal ( 2 ) ; } ) ; it ( 'should support a negative stop index' , ( ) => { let data = [ 'one' , 'two' , 'one' , 'four' , 'one' ] ; let i = ArrayExt . lastIndexOf ( data , 'one' , 1 , - 4 ) ; expect ( i ) . to . equal ( - 1 ) ; } ) ; it ( 'should wrap around if start < stop' , ( ) => { let data = [ 'one' , 'two' , 'one' , 'four' , 'one' ] ; let i = ArrayExt . lastIndexOf ( data , 'four' , 2 , 3 ) ; expect ( i ) . to . equal ( 3 ) ; } ) ; } ) ; describe ( 'findFirstIndex()' , ( ) => { it ( 'should find the index of the first matching value' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let i = ArrayExt . findFirstIndex ( data , v => v % 2 === 0 ) ; expect ( i ) . to . equal ( 1 ) ; } ) ; it ( 'should return `-1` if there is no matching value' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let i = ArrayExt . findFirstIndex ( data , v => v % 7 === 0 ) ; expect ( i ) . to . equal ( - 1 ) ; } ) ; it ( 'should return `-1` if the array is empty' , ( ) => { let data = [ ] ; let i = ArrayExt . findFirstIndex ( data , v => v % 2 === 0 ) ; expect ( i ) . to . equal ( - 1 ) ; } ) ; it ( 'should support searching from a start index' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let i = ArrayExt . findFirstIndex ( data , v => v % 2 === 0 , 2 ) ; expect ( i ) . to . equal ( 3 ) ; } ) ; it ( 'should support a negative start index' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let i = ArrayExt . findFirstIndex ( data , v => v % 2 === 0 , - 3 ) ; expect ( i ) . to . equal ( 3 ) ; } ) ; it ( 'should support searching within a range' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let i = ArrayExt . findFirstIndex ( data , v => v % 2 === 0 , 2 , 4 ) ; expect ( i ) . to . equal ( 3 ) ; } ) ; it ( 'should support a negative stop index' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let i = ArrayExt . findFirstIndex ( data , v => v % 2 === 0 , 2 , - 2 ) ; expect ( i ) . to . equal ( 3 ) ; } ) ; it ( 'should wrap around if stop < start' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let i = ArrayExt . findFirstIndex ( data , v => v % 2 === 0 , 4 , 2 ) ; expect ( i ) . to . equal ( 1 ) ; } ) ; } ) ; describe ( 'findLastIndex()' , ( ) => { it ( 'should find the index of the last matching value' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let i = ArrayExt . findLastIndex ( data , v => v % 2 === 0 ) ; expect ( i ) . to . equal ( 3 ) ; } ) ; it ( 'should return `-1` if there is no matching value' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let i = ArrayExt . findLastIndex ( data , v => v % 7 === 0 ) ; expect ( i ) . to . equal ( - 1 ) ; } ) ; it ( 'should return `-1` if the array is empty' , ( ) => { let data = [ ] ; let i = ArrayExt . findLastIndex ( data , v => v % 2 === 0 ) ; expect ( i ) . to . equal ( - 1 ) ; } ) ; it ( 'should support searching from a start index' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let i = ArrayExt . findLastIndex ( data , v => v % 2 === 0 , 2 ) ; expect ( i ) . to . equal ( 1 ) ; } ) ; it ( 'should support a negative start index' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let i = ArrayExt . findLastIndex ( data , v => v % 2 === 0 , - 3 ) ; expect ( i ) . to . equal ( 1 ) ; } ) ; it ( 'should support searching within a range' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let i = ArrayExt . findLastIndex ( data , v => v % 2 === 0 , 4 , 2 ) ; expect ( i ) . to . equal ( 3 ) ; } ) ; it ( 'should support a negative stop index' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let i = ArrayExt . findLastIndex ( data , v => v % 2 === 0 , - 3 , 0 ) ; expect ( i ) . to . equal ( 1 ) ; } ) ; it ( 'should wrap around if start < stop' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let i = ArrayExt . findLastIndex ( data , v => v % 2 === 0 , 0 , 2 ) ; expect ( i ) . to . equal ( 3 ) ; } ) ; } ) ; describe ( 'findFirstValue()' , ( ) => { it ( 'should find the index of the first matching value' , ( ) => { let data = [ 'apple' , 'bottle' , 'cat' , 'dog' , 'egg' , 'blue' ] ; let i = ArrayExt . findFirstValue ( data , v => v [ 0 ] === 'b' ) ; expect ( i ) . to . equal ( 'bottle' ) ; } ) ; it ( 'should return `undefined` if there is no matching value' , ( ) => { let data = [ 'apple' , 'bottle' , 'cat' , 'dog' , 'egg' , 'fish' ] ; let i = ArrayExt . findFirstValue ( data , v => v [ 0 ] === 'z' ) ; expect ( i ) . to . equal ( undefined ) ; } ) ; it ( 'should return `undefined` if the array is empty' , ( ) => { let data = [ ] ; let i = ArrayExt . findFirstValue ( data , v => v [ 0 ] === 'b' ) ; expect ( i ) . to . equal ( undefined ) ; } ) ; it ( 'should support searching from a start index' , ( ) => { let data = [ 'apple' , 'eagle' , 'cat' , 'dog' , 'egg' , 'fish' ] ; let i = ArrayExt . findFirstValue ( data , v => v [ 0 ] === 'e' , 2 ) ; expect ( i ) . to . equal ( 'egg' ) ; } ) ; it ( 'should support a negative start index' , ( ) => { let data = [ 'apple' , 'eagle' , 'cat' , 'dog' , 'egg' , 'fish' ] ; let i = ArrayExt . findFirstValue ( data , v => v [ 0 ] === 'e' , - 3 ) ; expect ( i ) . to . equal ( 'egg' ) ; } ) ; it ( 'should support searching within a range' , ( ) => { let data = [ 'dark' , 'bottle' , 'cat' , 'dog' , 'egg' , 'dodge' ] ; let i = ArrayExt . findFirstValue ( data , v => v [ 0 ] === 'd' , 2 , 4 ) ; expect ( i ) . to . equal ( 'dog' ) ; } ) ; it ( 'should support a negative stop index' , ( ) => { let data = [ 'dark' , 'bottle' , 'cat' , 'dog' , 'egg' , 'dodge' ] ; let i = ArrayExt . findFirstValue ( data , v => v [ 0 ] === 'd' , 2 , - 2 ) ; expect ( i ) . to . equal ( 'dog' ) ; } ) ; it ( 'should wrap around if stop < start' , ( ) => { let data = [ 'dark' , 'bottle' , 'cat' , 'dog' , 'egg' , 'dodge' ] ; let i = ArrayExt . findFirstValue ( data , v => v [ 0 ] === 'b' , 4 , 2 ) ; expect ( i ) . to . equal ( 'bottle' ) ; } ) ; } ) ; describe ( 'findLastValue()' , ( ) => { it ( 'should find the index of the last matching value' , ( ) => { let data = [ 'apple' , 'bottle' , 'cat' , 'dog' , 'egg' , 'blue' ] ; let i = ArrayExt . findLastValue ( data , v => v [ 0 ] === 'b' ) ; expect ( i ) . to . equal ( 'blue' ) ; } ) ; it ( 'should return `undefined` if there is no matching value' , ( ) => { let data = [ 'apple' , 'bottle' , 'cat' , 'dog' , 'egg' , 'fish' ] ; let i = ArrayExt . findLastValue ( data , v => v [ 0 ] === 'z' ) ; expect ( i ) . to . equal ( undefined ) ; } ) ; it ( 'should return `undefined` if the array is empty' , ( ) => { let data = [ ] ; let i = ArrayExt . findLastValue ( data , v => v [ 0 ] === 'b' ) ; expect ( i ) . to . equal ( undefined ) ; } ) ; it ( 'should support searching from a start index' , ( ) => { let data = [ 'apple' , 'eagle' , 'cat' , 'dog' , 'egg' , 'fish' ] ; let i = ArrayExt . findLastValue ( data , v => v [ 0 ] === 'e' , 2 ) ; expect ( i ) . to . equal ( 'eagle' ) ; } ) ; it ( 'should support a negative start index' , ( ) => { let data = [ 'apple' , 'eagle' , 'cat' , 'dog' , 'egg' , 'fish' ] ; let i = ArrayExt . findLastValue ( data , v => v [ 0 ] === 'e' , - 3 ) ; expect ( i ) . to . equal ( 'eagle' ) ; } ) ; it ( 'should support searching within a range' , ( ) => { let data = [ 'dark' , 'bottle' , 'cat' , 'dog' , 'egg' , 'dodge' ] ; let i = ArrayExt . findLastValue ( data , v => v [ 0 ] === 'd' , 4 , 2 ) ; expect ( i ) . to . equal ( 'dog' ) ; } ) ; it ( 'should support a negative stop index' , ( ) => { let data = [ 'dark' , 'bottle' , 'cat' , 'dog' , 'egg' , 'dodge' ] ; let i = ArrayExt . findLastValue ( data , v => v [ 0 ] === 'd' , 4 , - 4 ) ; expect ( i ) . to . equal ( 'dog' ) ; } ) ; it ( 'should wrap around if start < stop' , ( ) => { let data = [ 'dark' , 'bottle' , 'cat' , 'dog' , 'egg' , 'dodge' ] ; let i = ArrayExt . findLastValue ( data , v => v [ 0 ] === 'e' , 2 , 4 ) ; expect ( i ) . to . equal ( 'egg' ) ; } ) ; } ) ; describe ( 'lowerBound()' , ( ) => { it ( 'should return the index of the first element `>=` a value' , ( ) => { let data = [ 1 , 2 , 2 , 3 , 3 , 4 , 5 , 5 ] ; let cmp = ( a , b ) => a - b ; let r1 = ArrayExt . lowerBound ( data , - 5 , cmp ) ; let r2 = ArrayExt . lowerBound ( data , 0 , cmp ) ; let r3 = ArrayExt . lowerBound ( data , 3 , cmp ) ; let r4 = ArrayExt . lowerBound ( data , 5 , cmp ) ; expect ( r1 ) . to . equal ( 0 ) ; expect ( r2 ) . to . equal ( 0 ) ; expect ( r3 ) . to . equal ( 3 ) ; expect ( r4 ) . to . equal ( 6 ) ; } ) ; it ( 'should return `length` if there is no matching value' , ( ) => { let data = [ 1 , 2 , 2 , 3 , 3 , 4 , 5 , 5 ] ; let cmp = ( a , b ) => a - b ; let r1 = ArrayExt . lowerBound ( data , 9 , cmp ) ; let r2 = ArrayExt . lowerBound ( data , 19 , cmp ) ; let r3 = ArrayExt . lowerBound ( data , 29 , cmp ) ; expect ( r1 ) . to . equal ( 8 ) ; expect ( r2 ) . to . equal ( 8 ) ; expect ( r3 ) . to . equal ( 8 ) ; } ) ; it ( 'should return `0` if the array is empty' , ( ) => { let data = [ ] ; let cmp = ( a , b ) => a - b ; let i = ArrayExt . lowerBound ( data , 0 , cmp ) ; expect ( i ) . to . equal ( 0 ) ; } ) ; it ( 'should support searching a range' , ( ) => { let data = [ 4 , 5 , 6 , 4 , 5 , 6 ] ; let cmp = ( a , b ) => a - b ; let r = ArrayExt . lowerBound ( data , 5 , cmp , 3 , 5 ) ; expect ( r ) . to . equal ( 4 ) ; } ) ; } ) ; describe ( 'upperBound()' , ( ) => { it ( 'should return the index of the first element `>` a value' , ( ) => { let data = [ 1 , 2 , 2 , 3 , 3 , 4 , 5 , 5 ] ; let cmp = ( a , b ) => a - b ; let r1 = ArrayExt . upperBound ( data , - 5 , cmp ) ; let r2 = ArrayExt . upperBound ( data , 0 , cmp ) ; let r3 = ArrayExt . upperBound ( data , 2 , cmp ) ; let r4 = ArrayExt . upperBound ( data , 3 , cmp ) ; expect ( r1 ) . to . equal ( 0 ) ; expect ( r2 ) . to . equal ( 0 ) ; expect ( r3 ) . to . equal ( 3 ) ; expect ( r4 ) . to . equal ( 5 ) ; } ) ; it ( 'should return `length` if there is no matching value' , ( ) => { let data = [ 1 , 2 , 2 , 3 , 3 , 4 , 5 , 5 ] ; let cmp = ( a , b ) => a - b ; let r1 = ArrayExt . upperBound ( data , 9 , cmp ) ; let r2 = ArrayExt . upperBound ( data , 19 , cmp ) ; let r3 = ArrayExt . upperBound ( data , 29 , cmp ) ; expect ( r1 ) . to . equal ( 8 ) ; expect ( r2 ) . to . equal ( 8 ) ; expect ( r3 ) . to . equal ( 8 ) ; } ) ; it ( 'should return `0` if the array is empty' , ( ) => { let data = [ ] ; let cmp = ( a , b ) => a - b ; let i = ArrayExt . upperBound ( data , 0 , cmp ) ; expect ( i ) . to . equal ( 0 ) ; } ) ; it ( 'should support searching a range' , ( ) => { let data = [ 4 , 5 , 6 , 4 , 5 , 6 ] ; let cmp = ( a , b ) => a - b ; let r = ArrayExt . upperBound ( data , 5 , cmp , 3 , 5 ) ; expect ( r ) . to . equal ( 5 ) ; } ) ; } ) ; describe ( 'move()' , ( ) => { it ( 'should move an element from one index to another' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; ArrayExt . move ( data , 1 , 3 ) ; ArrayExt . move ( data , 4 , 0 ) ; expect ( data ) . to . deep . equal ( [ 5 , 1 , 3 , 4 , 2 ] ) ; } ) ; it ( 'should be a no-op for equal indices' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; ArrayExt . move ( data , 2 , 2 ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 3 , 4 , 5 ] ) ; } ) ; it ( 'should be a no-op for an array length `<= 1`' , ( ) => { let data1 = [ 1 ] ; let data2 = [ ] ; ArrayExt . move ( data1 , 0 , 0 ) ; ArrayExt . move ( data2 , 0 , 0 ) ; expect ( data1 ) . to . deep . equal ( [ 1 ] ) ; expect ( data2 ) . to . deep . equal ( [ ] ) ; } ) ; } ) ; describe ( 'reverse()' , ( ) => { it ( 'should reverse an array in-place' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; ArrayExt . reverse ( data ) ; expect ( data ) . to . deep . equal ( [ 5 , 4 , 3 , 2 , 1 ] ) ; } ) ; it ( 'should support reversing a section of an array' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; ArrayExt . reverse ( data , 2 ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 5 , 4 , 3 ] ) ; ArrayExt . reverse ( data , 0 , 3 ) ; expect ( data ) . to . deep . equal ( [ 4 , 5 , 2 , 1 , 3 ] ) ; } ) ; it ( 'should be a no-op if `start >= stop`' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; ArrayExt . reverse ( data , 2 , 2 ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 3 , 4 , 5 ] ) ; ArrayExt . reverse ( data , 4 , 2 ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 3 , 4 , 5 ] ) ; } ) ; it ( 'should be a no-op for an array length `<= 1`' , ( ) => { let data1 = [ 1 ] ; let data2 = [ ] ; ArrayExt . reverse ( data1 ) ; ArrayExt . reverse ( data2 ) ; expect ( data1 ) . to . deep . equal ( [ 1 ] ) ; expect ( data2 ) . to . deep . equal ( [ ] ) ; } ) ; } ) ; describe ( 'rotate()' , ( ) => { it ( 'should rotate the elements left by a positive delta' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; ArrayExt . rotate ( data , 2 ) ; expect ( data ) . to . deep . equal ( [ 3 , 4 , 5 , 1 , 2 ] ) ; ArrayExt . rotate ( data , 12 ) ; expect ( data ) . to . deep . equal ( [ 5 , 1 , 2 , 3 , 4 ] ) ; } ) ; it ( 'should rotate the elements right by a negative delta' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; ArrayExt . rotate ( data , - 2 ) ; expect ( data ) . to . deep . equal ( [ 4 , 5 , 1 , 2 , 3 ] ) ; ArrayExt . rotate ( data , - 12 ) ; expect ( data ) . to . deep . equal ( [ 2 , 3 , 4 , 5 , 1 ] ) ; } ) ; it ( 'should be a no-op for a zero delta' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; ArrayExt . rotate ( data , 0 ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 3 , 4 , 5 ] ) ; } ) ; it ( 'should be a no-op for a array length `<= 1`' , ( ) => { let data1 = [ 1 ] ; let data2 = [ ] ; ArrayExt . rotate ( data1 , 1 ) ; ArrayExt . rotate ( data2 , 1 ) ; expect ( data1 ) . to . deep . equal ( [ 1 ] ) ; expect ( data2 ) . to . deep . equal ( [ ] ) ; } ) ; it ( 'should rotate a section of the array' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; ArrayExt . rotate ( data , 2 , 1 , 3 ) ; expect ( data ) . to . deep . equal ( [ 1 , 4 , 2 , 3 , 5 ] ) ; ArrayExt . rotate ( data , - 2 , 0 , 3 ) ; expect ( data ) . to . deep . equal ( [ 2 , 3 , 1 , 4 , 5 ] ) ; } ) ; it ( 'should be a no-op if `start >= stop`' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; ArrayExt . rotate ( data , 2 , 5 , 4 ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 3 , 4 , 5 ] ) ; } ) ; } ) ; describe ( 'fill()' , ( ) => { it ( 'should fill an array with a static value' , ( ) => { let data = [ 0 , 0 , 0 , 0 , 0 ] ; ArrayExt . fill ( data , 1 ) ; expect ( data ) . to . deep . equal ( [ 1 , 1 , 1 , 1 , 1 ] ) ; } ) ; it ( 'should fill a section of the array' , ( ) => { let data = [ 0 , 0 , 0 , 0 , 0 ] ; ArrayExt . fill ( data , 1 , 1 , 3 ) ; expect ( data ) . to . deep . equal ( [ 0 , 1 , 1 , 1 , 0 ] ) ; } ) ; it ( 'should wrap around if `stop < start`' , ( ) => { let data = [ 0 , 0 , 0 , 0 , 0 ] ; ArrayExt . fill ( data , 1 , 3 , 1 ) ; expect ( data ) . to . deep . equal ( [ 1 , 1 , 0 , 1 , 1 ] ) ; } ) ; } ) ; describe ( 'insert()' , ( ) => { it ( 'should insert a value at the specified index' , ( ) => { let data = [ ] ; ArrayExt . insert ( data , 0 , 9 ) ; expect ( data ) . to . deep . equal ( [ 9 ] ) ; ArrayExt . insert ( data , 0 , 8 ) ; expect ( data ) . to . deep . equal ( [ 8 , 9 ] ) ; ArrayExt . insert ( data , 0 , 7 ) ; expect ( data ) . to . deep . equal ( [ 7 , 8 , 9 ] ) ; ArrayExt . insert ( data , - 2 , 6 ) ; expect ( data ) . to . deep . equal ( [ 7 , 6 , 8 , 9 ] ) ; ArrayExt . insert ( data , 2 , 5 ) ; expect ( data ) . to . deep . equal ( [ 7 , 6 , 5 , 8 , 9 ] ) ; ArrayExt . insert ( data , - 5 , 4 ) ; expect ( data ) . to . deep . equal ( [ 4 , 7 , 6 , 5 , 8 , 9 ] ) ; } ) ; it ( 'should clamp the index to the bounds of the vector' , ( ) => { let data = [ ] ; ArrayExt . insert ( data , - 10 , 9 ) ; expect ( data ) . to . deep . equal ( [ 9 ] ) ; ArrayExt . insert ( data , - 5 , 8 ) ; expect ( data ) . to . deep . equal ( [ 8 , 9 ] ) ; ArrayExt . insert ( data , - 1 , 7 ) ; expect ( data ) . to . deep . equal ( [ 8 , 7 , 9 ] ) ; ArrayExt . insert ( data , 13 , 6 ) ; expect ( data ) . to . deep . equal ( [ 8 , 7 , 9 , 6 ] ) ; ArrayExt . insert ( data , 8 , 4 ) ; expect ( data ) . to . deep . equal ( [ 8 , 7 , 9 , 6 , 4 ] ) ; } ) ; } ) ; describe ( 'removeAt()' , ( ) => { it ( 'should remove the value at a specified index' , ( ) => { let data = [ 7 , 4 , 8 , 5 , 9 , 6 ] ; expect ( ArrayExt . removeAt ( data , 1 ) ) . to . equal ( 4 ) ; expect ( data ) . to . deep . equal ( [ 7 , 8 , 5 , 9 , 6 ] ) ; expect ( ArrayExt . removeAt ( data , 2 ) ) . to . equal ( 5 ) ; expect ( data ) . to . deep . equal ( [ 7 , 8 , 9 , 6 ] ) ; expect ( ArrayExt . removeAt ( data , - 2 ) ) . to . equal ( 9 ) ; expect ( data ) . to . deep . equal ( [ 7 , 8 , 6 ] ) ; expect ( ArrayExt . removeAt ( data , 0 ) ) . to . equal ( 7 ) ; expect ( data ) . to . deep . equal ( [ 8 , 6 ] ) ; expect ( ArrayExt . removeAt ( data , - 1 ) ) . to . equal ( 6 ) ; expect ( data ) . to . deep . equal ( [ 8 ] ) ; expect ( ArrayExt . removeAt ( data , 0 ) ) . to . equal ( 8 ) ; expect ( data ) . to . deep . equal ( [ ] ) ; } ) ; it ( 'should return `undefined` if the index is out of range' , ( ) => { let data = [ 7 , 4 , 8 , 5 , 9 , 6 ] ; expect ( ArrayExt . removeAt ( data , 10 ) ) . to . equal ( undefined ) ; expect ( data ) . to . deep . equal ( [ 7 , 4 , 8 , 5 , 9 , 6 ] ) ; expect ( ArrayExt . removeAt ( data , - 12 ) ) . to . equal ( undefined ) ; expect ( data ) . to . deep . equal ( [ 7 , 4 , 8 , 5 , 9 , 6 ] ) ; } ) ; } ) ; describe ( 'removeFirstOf()' , ( ) => { it ( 'should remove the first occurrence of a value' , ( ) => { let data = [ 'one' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . removeFirstOf ( data , 'one' ) ; expect ( i ) . to . equal ( 0 ) ; expect ( data ) . to . deep . equal ( [ 'two' , 'three' , 'four' , 'one' ] ) ; } ) ; it ( 'should return `-1` if there is no matching value' , ( ) => { let data = [ 'one' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . removeFirstOf ( data , 'five' ) ; expect ( i ) . to . equal ( - 1 ) ; expect ( data ) . to . deep . equal ( [ 'one' , 'two' , 'three' , 'four' , 'one' ] ) ; } ) ; it ( 'should return `-1` if the array is empty' , ( ) => { let data = [ ] ; let i = ArrayExt . removeFirstOf ( data , 'five' ) ; expect ( i ) . to . equal ( - 1 ) ; expect ( data ) . to . deep . equal ( [ ] ) ; } ) ; it ( 'should support searching from a start index' , ( ) => { let data = [ 'one' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . removeFirstOf ( data , 'one' , 2 ) ; expect ( i ) . to . equal ( 4 ) ; expect ( data ) . to . deep . equal ( [ 'one' , 'two' , 'three' , 'four' ] ) ; } ) ; it ( 'should support a negative start index' , ( ) => { let data = [ 'one' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . removeFirstOf ( data , 'one' , - 2 ) ; expect ( i ) . to . equal ( 4 ) ; expect ( data ) . to . deep . equal ( [ 'one' , 'two' , 'three' , 'four' ] ) ; } ) ; it ( 'should support searching within a range' , ( ) => { let data = [ 'three' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . removeFirstOf ( data , 'three' , 1 , 3 ) ; expect ( i ) . to . equal ( 2 ) ; expect ( data ) . to . deep . equal ( [ 'three' , 'two' , 'four' , 'one' ] ) ; } ) ; it ( 'should support a negative stop index' , ( ) => { let data = [ 'three' , 'two' , 'three' , 'four' , 'three' ] ; let i = ArrayExt . removeFirstOf ( data , 'three' , 1 , - 2 ) ; expect ( i ) . to . equal ( 2 ) ; expect ( data ) . to . deep . equal ( [ 'three' , 'two' , 'four' , 'three' ] ) ; } ) ; it ( 'should wrap around if stop < start' , ( ) => { let data = [ 'one' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . removeFirstOf ( data , 'two' , 3 , 1 ) ; expect ( i ) . to . equal ( 1 ) ; expect ( data ) . to . deep . equal ( [ 'one' , 'three' , 'four' , 'one' ] ) ; } ) ; } ) ; describe ( 'removeLastOf()' , ( ) => { it ( 'should remove the last occurrence of a value' , ( ) => { let data = [ 'one' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . removeLastOf ( data , 'one' ) ; expect ( i ) . to . equal ( 4 ) ; expect ( data ) . to . deep . equal ( [ 'one' , 'two' , 'three' , 'four' ] ) ; } ) ; it ( 'should return `-1` if there is no matching value' , ( ) => { let data = [ 'one' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . removeLastOf ( data , 'five' ) ; expect ( i ) . to . equal ( - 1 ) ; expect ( data ) . to . deep . equal ( [ 'one' , 'two' , 'three' , 'four' , 'one' ] ) ; } ) ; it ( 'should return `-1` if the array is empty' , ( ) => { let data = [ ] ; let i = ArrayExt . removeLastOf ( data , 'five' ) ; expect ( i ) . to . equal ( - 1 ) ; expect ( data ) . to . deep . equal ( [ ] ) ; } ) ; it ( 'should support searching from a start index' , ( ) => { let data = [ 'one' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . removeLastOf ( data , 'one' , 2 ) ; expect ( i ) . to . equal ( 0 ) ; expect ( data ) . to . deep . equal ( [ 'two' , 'three' , 'four' , 'one' ] ) ; } ) ; it ( 'should support a negative start index' , ( ) => { let data = [ 'one' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . removeLastOf ( data , 'one' , - 2 ) ; expect ( i ) . to . equal ( 0 ) ; expect ( data ) . to . deep . equal ( [ 'two' , 'three' , 'four' , 'one' ] ) ; } ) ; it ( 'should support searching within a range' , ( ) => { let data = [ 'three' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . removeLastOf ( data , 'three' , 3 , 1 ) ; expect ( i ) . to . equal ( 2 ) ; expect ( data ) . to . deep . equal ( [ 'three' , 'two' , 'four' , 'one' ] ) ; } ) ; it ( 'should support a negative stop index' , ( ) => { let data = [ 'three' , 'two' , 'three' , 'four' , 'three' ] ; let i = ArrayExt . removeLastOf ( data , 'three' , 3 , - 4 ) ; expect ( i ) . to . equal ( 2 ) ; expect ( data ) . to . deep . equal ( [ 'three' , 'two' , 'four' , 'three' ] ) ; } ) ; it ( 'should wrap around if start < stop' , ( ) => { let data = [ 'one' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . removeLastOf ( data , 'two' , 3 , 1 ) ; expect ( i ) . to . equal ( 1 ) ; expect ( data ) . to . deep . equal ( [ 'one' , 'three' , 'four' , 'one' ] ) ; } ) ; } ) ; describe ( 'removeAllOf()' , ( ) => { it ( 'should remove all occurrences of a value' , ( ) => { let data = [ 'one' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . removeAllOf ( data , 'one' ) ; expect ( i ) . to . equal ( 2 ) ; expect ( data ) . to . deep . equal ( [ 'two' , 'three' , 'four' ] ) ; } ) ; it ( 'should return `0` if there is no matching value' , ( ) => { let data = [ 'one' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . removeAllOf ( data , 'five' ) ; expect ( i ) . to . equal ( 0 ) ; expect ( data ) . to . deep . equal ( [ 'one' , 'two' , 'three' , 'four' , 'one' ] ) ; } ) ; it ( 'should return `0` if the array is empty' , ( ) => { let data = [ ] ; let i = ArrayExt . removeAllOf ( data , 'five' ) ; expect ( i ) . to . equal ( 0 ) ; expect ( data ) . to . deep . equal ( [ ] ) ; } ) ; it ( 'should support searching from a start index' , ( ) => { let data = [ 'one' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . removeAllOf ( data , 'one' , 2 ) ; expect ( i ) . to . equal ( 1 ) ; expect ( data ) . to . deep . equal ( [ 'one' , 'two' , 'three' , 'four' ] ) ; } ) ; it ( 'should support a negative start index' , ( ) => { let data = [ 'one' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . removeAllOf ( data , 'one' , - 2 ) ; expect ( i ) . to . equal ( 1 ) ; expect ( data ) . to . deep . equal ( [ 'one' , 'two' , 'three' , 'four' ] ) ; } ) ; it ( 'should support searching within a range' , ( ) => { let data = [ 'three' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . removeAllOf ( data , 'three' , 1 , 3 ) ; expect ( i ) . to . equal ( 1 ) ; expect ( data ) . to . deep . equal ( [ 'three' , 'two' , 'four' , 'one' ] ) ; } ) ; it ( 'should support a negative stop index' , ( ) => { let data = [ 'three' , 'two' , 'three' , 'four' , 'three' ] ; let i = ArrayExt . removeAllOf ( data , 'three' , 1 , - 2 ) ; expect ( i ) . to . equal ( 1 ) ; expect ( data ) . to . deep . equal ( [ 'three' , 'two' , 'four' , 'three' ] ) ; } ) ; it ( 'should wrap around if start < stop' , ( ) => { let data = [ 'one' , 'two' , 'three' , 'four' , 'one' ] ; let i = ArrayExt . removeAllOf ( data , 'one' , 3 , 1 ) ; expect ( i ) . to . equal ( 2 ) ; expect ( data ) . to . deep . equal ( [ 'two' , 'three' , 'four' ] ) ; } ) ; } ) ; describe ( 'removeFirstWhere()' , ( ) => { it ( 'should remove the first occurrence of a value' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let result = ArrayExt . removeFirstWhere ( data , v => v % 2 === 0 ) ; expect ( result . index ) . to . equal ( 1 ) ; expect ( result . value ) . to . equal ( 2 ) ; expect ( data ) . to . deep . equal ( [ 1 , 3 , 4 , 5 ] ) ; } ) ; it ( 'should return `-1` if there is no matching value' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let result = ArrayExt . removeFirstWhere ( data , v => v % 7 === 0 ) ; expect ( result . index ) . to . equal ( - 1 ) ; expect ( result . value ) . to . equal ( undefined ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 3 , 4 , 5 ] ) ; } ) ; it ( 'should return `-1` if the array is empty' , ( ) => { let data = [ ] ; let result = ArrayExt . removeFirstWhere ( data , v => v % 7 === 0 ) ; expect ( result . index ) . to . equal ( - 1 ) ; expect ( result . value ) . to . equal ( undefined ) ; expect ( data ) . to . deep . equal ( [ ] ) ; } ) ; it ( 'should support searching from a start index' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let result = ArrayExt . removeFirstWhere ( data , v => v % 2 === 0 , 2 ) ; expect ( result . index ) . to . equal ( 3 ) ; expect ( result . value ) . to . equal ( 4 ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 3 , 5 ] ) ; } ) ; it ( 'should support a negative start index' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let result = ArrayExt . removeFirstWhere ( data , v => v % 2 === 0 , - 3 ) ; expect ( result . index ) . to . equal ( 3 ) ; expect ( result . value ) . to . equal ( 4 ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 3 , 5 ] ) ; } ) ; it ( 'should support searching within a range' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let result = ArrayExt . removeFirstWhere ( data , v => v % 2 === 0 , 2 , 4 ) ; expect ( result . index ) . to . equal ( 3 ) ; expect ( result . value ) . to . equal ( 4 ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 3 , 5 ] ) ; } ) ; it ( 'should support a negative stop index' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let result = ArrayExt . removeFirstWhere ( data , v => v % 2 === 0 , 2 , - 2 ) ; expect ( result . index ) . to . equal ( 3 ) ; expect ( result . value ) . to . equal ( 4 ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 3 , 5 ] ) ; } ) ; it ( 'should wrap around if stop < start' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let result = ArrayExt . removeFirstWhere ( data , v => v % 2 === 0 , 4 , 2 ) ; expect ( result . index ) . to . equal ( 1 ) ; expect ( result . value ) . to . equal ( 2 ) ; expect ( data ) . to . deep . equal ( [ 1 , 3 , 4 , 5 ] ) ; } ) ; } ) ; describe ( 'removeLastWhere()' , ( ) => { it ( 'should remove the last occurrence of a value' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let result = ArrayExt . removeLastWhere ( data , v => v % 2 === 0 ) ; expect ( result . index ) . to . equal ( 3 ) ; expect ( result . value ) . to . equal ( 4 ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 3 , 5 ] ) ; } ) ; it ( 'should return `-1` if there is no matching value' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let result = ArrayExt . removeLastWhere ( data , v => v % 7 === 0 ) ; expect ( result . index ) . to . equal ( - 1 ) ; expect ( result . value ) . to . equal ( undefined ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 3 , 4 , 5 ] ) ; } ) ; it ( 'should return `-1` if the array is empty' , ( ) => { let data = [ ] ; let result = ArrayExt . removeLastWhere ( data , v => v % 7 === 0 ) ; expect ( result . index ) . to . equal ( - 1 ) ; expect ( result . value ) . to . equal ( undefined ) ; expect ( data ) . to . deep . equal ( [ ] ) ; } ) ; it ( 'should support searching from a start index' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let result = ArrayExt . removeLastWhere ( data , v => v % 2 === 0 , 2 ) ; expect ( result . index ) . to . equal ( 1 ) ; expect ( result . value ) . to . equal ( 2 ) ; expect ( data ) . to . deep . equal ( [ 1 , 3 , 4 , 5 ] ) ; } ) ; it ( 'should support a negative start index' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let result = ArrayExt . removeLastWhere ( data , v => v % 2 === 0 , - 3 ) ; expect ( result . index ) . to . equal ( 1 ) ; expect ( result . value ) . to . equal ( 2 ) ; expect ( data ) . to . deep . equal ( [ 1 , 3 , 4 , 5 ] ) ; } ) ; it ( 'should support searching within a range' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let result = ArrayExt . removeLastWhere ( data , v => v % 2 === 0 , 4 , 2 ) ; expect ( result . index ) . to . equal ( 3 ) ; expect ( result . value ) . to . equal ( 4 ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 3 , 5 ] ) ; } ) ; it ( 'should support a negative stop index' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let result = ArrayExt . removeLastWhere ( data , v => v % 2 === 0 , 4 , - 4 ) ; expect ( result . index ) . to . equal ( 3 ) ; expect ( result . value ) . to . equal ( 4 ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 3 , 5 ] ) ; } ) ; it ( 'should wrap around if start < stop' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 5 ] ; let result = ArrayExt . removeLastWhere ( data , v => v % 2 === 0 , 0 , 2 ) ; expect ( result . index ) . to . equal ( 3 ) ; expect ( result . value ) . to . equal ( 4 ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 3 , 5 ] ) ; } ) ; } ) ; describe ( 'removeAllWhere()' , ( ) => { it ( 'should remove all occurrences of a value' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 3 , 5 , 1 ] ; let count = ArrayExt . removeAllWhere ( data , v => v % 3 === 0 ) ; expect ( count ) . to . equal ( 2 ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 4 , 5 , 1 ] ) ; } ) ; it ( 'should return `0` if there is no matching value' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 3 , 5 , 1 ] ; let count = ArrayExt . removeAllWhere ( data , v => v % 7 === 0 ) ; expect ( count ) . to . equal ( 0 ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 3 , 4 , 3 , 5 , 1 ] ) ; } ) ; it ( 'should return `0` if the array is empty' , ( ) => { let data = [ ] ; let count = ArrayExt . removeAllWhere ( data , v => v % 7 === 0 ) ; expect ( count ) . to . equal ( 0 ) ; expect ( data ) . to . deep . equal ( [ ] ) ; } ) ; it ( 'should support searching from a start index' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 3 , 5 , 1 ] ; let count = ArrayExt . removeAllWhere ( data , v => v % 3 === 0 , 3 ) ; expect ( count ) . to . equal ( 1 ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 3 , 4 , 5 , 1 ] ) ; } ) ; it ( 'should support a negative start index' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 3 , 5 , 1 ] ; let count = ArrayExt . removeAllWhere ( data , v => v % 3 === 0 , - 4 ) ; expect ( count ) . to . equal ( 1 ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 3 , 4 , 5 , 1 ] ) ; } ) ; it ( 'should support searching within a range' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 3 , 5 , 1 ] ; let count = ArrayExt . removeAllWhere ( data , v => v % 3 === 0 , 3 , 5 ) ; expect ( count ) . to . equal ( 1 ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 3 , 4 , 5 , 1 ] ) ; } ) ; it ( 'should support a negative stop index' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 3 , 5 , 1 ] ; let count = ArrayExt . removeAllWhere ( data , v => v % 3 === 0 , 3 , - 2 ) ; expect ( count ) . to . equal ( 1 ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 3 , 4 , 5 , 1 ] ) ; } ) ; it ( 'should wrap around if start < stop' , ( ) => { let data = [ 1 , 2 , 3 , 4 , 3 , 5 , 1 ] ; let count = ArrayExt . removeAllWhere ( data , v => v % 3 === 0 , 5 , 3 ) ; expect ( count ) . to . equal ( 1 ) ; expect ( data ) . to . deep . equal ( [ 1 , 2 , 4 , 3 , 5 , 1 ] ) ; } ) ; } ) ; } ) ; } ) ;