import { assert , } from "chai" ; import { suite , test , } from "mocha-typescript" ; import { clean } from "../src/clean" ; import { flatten } from "../src/flatten" ; import { IdentityDictionary } from "../src/IdentityDictionary" ; import { MultiMap } from "../src/MultiMap" ; import { TwoKeyMultiMap } from "../src/TwoKeyMultiMap" ; import * as typeAssertions from "../src/typedAssert" ; import { ObjectDictionary } from "../src/UtilityTypes" ; interface MultiMapKey1 { name : string ; } interface MultiMapKey2 { label : string ; } interface IdentityTest { key1 : string ; key2 : number ; other1 : string ; } @ suite ( "Utils" ) export class SimpleTemplateTest { @ test "type assertions" ( ) { let undef = ( true ) ? undefined : "apple" ; let defined = ( true ) ? "apple" : undefined ; let nil = ( true ) ? null : "apple" ; let notNull = ( true ) ? "pear" : null ; let nothing = ( true ) ? null : ( false ) ? "apple" : undefined ; let something = ( true ) ? "apple" : ( false ) ? null : undefined ; let apple = "apple" ; let pear = "pear" ; function isApple ( x ) { return x === "apple" ; } assert . throws ( ( ) => { typeAssertions . isDefined ( undef ) . and ( ( d ) => d ) ; } , "expected to be defined" ) ; let callbackInvoked = false ; typeAssertions . isDefined ( defined ) . and ( ( d ) => callbackInvoked = ! ! d ) ; assert ( callbackInvoked , "callback was not invoked." ) ; assert . throws ( ( ) => { typeAssertions . isNotNull ( nil ) . and ( ( d ) => d ) ; } , "expected to not be null" ) ; callbackInvoked = false ; typeAssertions . isNotNull ( notNull ) . and ( ( d ) => callbackInvoked = ! ! d ) ; assert ( callbackInvoked , "callback was not invoked." ) ; assert . throws ( ( ) => { typeAssertions . isExisting ( nil ) . and ( ( d ) => d ) ; } , "expected to exist" ) ; callbackInvoked = false ; typeAssertions . isExisting ( notNull ) . and ( ( d ) => callbackInvoked = ! ! d ) ; assert ( callbackInvoked , "callback was not invoked." ) ; assert . throws ( ( ) => { typeAssertions . isExisting ( undef ) . and ( ( d ) => d ) ; } , "expected to exist" ) ; callbackInvoked = false ; typeAssertions . isExisting ( defined ) . and ( ( d ) => callbackInvoked = ! ! d ) ; assert ( callbackInvoked , "callback was not invoked." ) ; assert . throws ( ( ) => { typeAssertions . isExisting ( nothing ) . and ( ( d ) => d ) ; } , "expected to exist" ) ; callbackInvoked = false ; typeAssertions . isExisting ( something ) . and ( ( d ) => callbackInvoked = ! ! d ) ; assert ( callbackInvoked , "callback was not invoked." ) ; assert . throws ( ( ) => { typeAssertions . isType ( isApple , pear ) . and ( ( d ) => d ) ; } , "expected" ) ; callbackInvoked = false ; typeAssertions . isType ( isApple , apple ) . and ( ( d ) => callbackInvoked = ! ! d ) ; assert ( callbackInvoked , "callback was not invoked." ) ; } @ test "clean" ( ) { assert . equal ( clean `
      foo    
        bar   
    baz
    ` , "foo\nbar\nbaz" ) ; } @ test "Object Dictionary" ( ) { let foo = { apple : 1 , orange : 3 , } ; assert . deepEqual ( foo , { apple : 1 , orange : 3 } ) ; } @ test "Identity Dictionary" ( ) { let dict = new IdentityDictionary < IdentityTest > ( ( it ) => `${ it . key1 }:${ it . key2 }` ) ; let one = { key1 : "apple" , key2 : 0 , other1 : "foo bar" , } ; let onePrime = { key1 : "apple" , key2 : 0 , other1 : "different" , } ; let two = { key1 : "orange" , key2 : 10 , other1 : "four score and twenty years ago" , } ; let addedOne = dict . add ( one ) ; assert . strictEqual ( addedOne , one ) ; let addedOnePrime = dict . add ( onePrime ) ; assert . strictEqual ( addedOnePrime , one ) ; let addedTwo = dict . add ( two ) ; assert . strictEqual ( addedTwo , two ) ; assert . equal ( dict . size ( ) , 2 ) ; dict . update ( one , ( instance ) => { assert . strictEqual ( instance , one ) ; instance . key1 = "green apple" ; } ) ; assert . equal ( dict . size ( ) , 2 ) ; assert . isFalse ( dict . has ( onePrime ) ) ; let oneReplacement = { key1 : "bad apple" , key2 : 100 , other1 : "" , } ; dict . update ( one , ( instance ) => { assert . strictEqual ( instance , one ) ; return oneReplacement ; } ) ; assert . equal ( dict . size ( ) , 2 ) ; assert . isTrue ( dict . has ( oneReplacement ) ) ; dict . update ( oneReplacement , ( instance ) => { assert . strictEqual ( instance , oneReplacement ) ; instance . key2 = 1000 ; return false ; } ) ; assert . equal ( dict . size ( ) , 2 ) ; assert . isFalse ( dict . has ( oneReplacement ) ) ; assert . isTrue ( dict . has ( { key1 : "bad apple" , key2 : 100 , other1 : "" , } ) ) ; } @ test "MultiMap" ( ) { let multiMap = new MultiMap < MultiMapKey1 , number > ( ) ; let key1 = { name : "key1" } ; multiMap . set ( key1 , 0 ) ; multiMap . set ( key1 , 1 , 2 ) ; let values = multiMap . get ( key1 ) ; assert . deepEqual ( values , [ 0 , 1 , 2 ] ) ; assert . strictEqual ( multiMap . size , 1 ) ; assert . strictEqual ( multiMap . sizeOfKeys , 1 ) ; assert . strictEqual ( multiMap . sizeOfValues , 3 ) ; let entries = new Array < [ MultiMapKey1 , number [ ] ] > ( ) ; for ( let entry of multiMap . entries ( ) ) { entries . push ( entry ) ; } assert . deepEqual ( entries , [ [ key1 , [ 0 , 1 , 2 ] ] ] ) ; let individualEntries = new Array < [ MultiMapKey1 , number ] > ( ) ; for ( let entry of multiMap . individualEntries ( ) ) { individualEntries . push ( entry ) ; } assert . deepEqual ( individualEntries , [ [ key1 , 0 ] , [ key1 , 1 ] , [ key1 , 2 ] ] ) ; multiMap . deleteValue ( key1 , 1 ) ; assert . deepEqual ( multiMap . get ( key1 ) , [ 0 , 2 ] ) ; assert . strictEqual ( multiMap . sizeOfKeys , 1 ) ; assert . strictEqual ( multiMap . sizeOfValues , 2 ) ; assert . deepEqual ( multiMap . deleteValue ( key1 , 0 , 2 , 3 ) , [ 0 , 2 ] ) ; assert . strictEqual ( multiMap . sizeOfKeys , 0 ) ; assert . strictEqual ( multiMap . sizeOfValues , 0 ) ; multiMap . set ( key1 , 1 , 1 , 1 ) ; assert . strictEqual ( multiMap . sizeOfKeys , 1 ) ; assert . strictEqual ( multiMap . sizeOfValues , 3 ) ; assert . deepEqual ( multiMap . deleteValue ( key1 , 1 ) , [ 1 , 1 , 1 ] ) ; assert . strictEqual ( multiMap . sizeOfKeys , 0 ) ; assert . strictEqual ( multiMap . sizeOfValues , 0 ) ; multiMap . set ( key1 , 0 , 1 , 2 ) ; multiMap . clear ( ) ; assert . strictEqual ( multiMap . size , 0 ) ; assert . strictEqual ( multiMap . sizeOfKeys , 0 ) ; assert . strictEqual ( multiMap . sizeOfValues , 0 ) ; multiMap . set ( key1 , 1 ) ; multiMap . set ( { name : "key1" } , 2 ) ; assert . strictEqual ( multiMap . sizeOfKeys , 2 ) ; assert . strictEqual ( multiMap . sizeOfValues , 2 ) ; multiMap . clear ( ) ; assert . deepEqual ( multiMap . get ( key1 ) , [ ] ) ; assert . deepEqual ( multiMap . has ( key1 ) , false ) ; let emptyValue = multiMap . get ( key1 ) ; emptyValue . push ( 2 ) ; assert . deepEqual ( multiMap . get ( key1 ) , [ ] ) ; multiMap . set ( key1 , 1 ) ; let existingValue = multiMap . get ( key1 ) ; existingValue . push ( 2 ) ; assert . deepEqual ( multiMap . get ( key1 ) , [ 1 ] ) ; for ( let [ , values ] of multiMap . entries ( ) ) { values . push ( 2 ) ; } assert . deepEqual ( multiMap . get ( key1 ) , [ 1 ] ) ; for ( let values of multiMap . values ( ) ) { values . push ( 2 ) ; } assert . deepEqual ( multiMap . get ( key1 ) , [ 1 ] ) ; multiMap . forEach ( ( values ) => { values . push ( 2 ) ; } ) ; assert . deepEqual ( multiMap . get ( key1 ) , [ 1 ] ) ; } @ test "MultiMap with unique values" ( ) { let multiMap = new MultiMap < MultiMapKey1 , number > ( false ) ; let key1 = { name : "key1" } ; multiMap . set ( key1 , 0 ) ; multiMap . set ( key1 , 1 , 2 ) ; let values = multiMap . get ( key1 ) ; assert . deepEqual ( values , [ 0 , 1 , 2 ] ) ; assert . strictEqual ( multiMap . size , 1 ) ; assert . strictEqual ( multiMap . sizeOfKeys , 1 ) ; assert . strictEqual ( multiMap . sizeOfValues , 3 ) ; let entries = new Array < [ MultiMapKey1 , number [ ] ] > ( ) ; for ( let entry of multiMap . entries ( ) ) { entries . push ( entry ) ; } assert . deepEqual ( entries , [ [ key1 , [ 0 , 1 , 2 ] ] ] ) ; let individualEntries = new Array < [ MultiMapKey1 , number ] > ( ) ; for ( let entry of multiMap . individualEntries ( ) ) { individualEntries . push ( entry ) ; } assert . deepEqual ( individualEntries , [ [ key1 , 0 ] , [ key1 , 1 ] , [ key1 , 2 ] ] ) ; multiMap . deleteValue ( key1 , 1 ) ; assert . deepEqual ( multiMap . get ( key1 ) , [ 0 , 2 ] ) ; assert . strictEqual ( multiMap . sizeOfKeys , 1 ) ; assert . strictEqual ( multiMap . sizeOfValues , 2 ) ; assert . deepEqual ( multiMap . deleteValue ( key1 , 0 , 2 , 3 ) , [ 0 , 2 ] ) ; assert . strictEqual ( multiMap . sizeOfKeys , 0 ) ; assert . strictEqual ( multiMap . sizeOfValues , 0 ) ; multiMap . set ( key1 , 1 , 1 , 1 ) ; assert . strictEqual ( multiMap . sizeOfKeys , 1 ) ; assert . strictEqual ( multiMap . sizeOfValues , 1 ) ; assert . deepEqual ( multiMap . deleteValue ( key1 , 1 ) , [ 1 ] ) ; assert . strictEqual ( multiMap . sizeOfKeys , 0 ) ; assert . strictEqual ( multiMap . sizeOfValues , 0 ) ; multiMap . set ( key1 , 0 , 1 , 2 ) ; multiMap . clear ( ) ; assert . strictEqual ( multiMap . size , 0 ) ; assert . strictEqual ( multiMap . sizeOfKeys , 0 ) ; assert . strictEqual ( multiMap . sizeOfValues , 0 ) ; multiMap . set ( key1 , 1 ) ; multiMap . set ( { name : "key1" } , 2 ) ; assert . strictEqual ( multiMap . sizeOfKeys , 2 ) ; assert . strictEqual ( multiMap . sizeOfValues , 2 ) ; multiMap . clear ( ) ; assert . deepEqual ( multiMap . get ( key1 ) , [ ] ) ; assert . deepEqual ( multiMap . has ( key1 ) , false ) ; let emptyValue = multiMap . get ( key1 ) ; emptyValue . push ( 2 ) ; assert . deepEqual ( multiMap . get ( key1 ) , [ ] ) ; multiMap . set ( key1 , 1 ) ; let existingValue = multiMap . get ( key1 ) ; existingValue . push ( 2 ) ; assert . deepEqual ( multiMap . get ( key1 ) , [ 1 ] ) ; for ( let [ , values ] of multiMap . entries ( ) ) { values . push ( 2 ) ; } assert . deepEqual ( multiMap . get ( key1 ) , [ 1 ] ) ; for ( let values of multiMap . values ( ) ) { values . push ( 2 ) ; } assert . deepEqual ( multiMap . get ( key1 ) , [ 1 ] ) ; multiMap . forEach ( ( values ) => { values . push ( 2 ) ; } ) ; assert . deepEqual ( multiMap . get ( key1 ) , [ 1 ] ) ; } @ test "TwoKeyMultiMap" ( ) { let multiMap = new TwoKeyMultiMap < MultiMapKey1 , MultiMapKey2 , number > ( ) ; let key1 = { name : "key1" } ; let key2 = { label : "key2" } ; multiMap . set ( key1 , key2 , 0 ) ; multiMap . set ( key1 , key2 , 1 , 2 ) ; let values = multiMap . get ( key1 , key2 ) ; assert . deepEqual ( values , [ 0 , 1 , 2 ] ) ; assert . strictEqual ( multiMap . size , 1 ) ; assert . strictEqual ( multiMap . sizeOfKeys , 1 ) ; assert . strictEqual ( multiMap . sizeOfValues , 3 ) ; let entries = new Array < [ MultiMapKey1 , MultiMapKey2 , number [ ] ] > ( ) ; for ( let entry of multiMap . entries ( ) ) { entries . push ( entry ) ; } assert . deepEqual ( entries , [ [ key1 , key2 , [ 0 , 1 , 2 ] ] ] ) ; let individualEntries = new Array < [ MultiMapKey1 , MultiMapKey2 , number ] > ( ) ; for ( let entry of multiMap . individualEntries ( ) ) { individualEntries . push ( entry ) ; } assert . deepEqual ( individualEntries , [ [ key1 , key2 , 0 ] , [ key1 , key2 , 1 ] , [ key1 , key2 , 2 ] ] ) ; multiMap . deleteValue ( key1 , key2 , 1 ) ; assert . deepEqual ( multiMap . get ( key1 , key2 ) , [ 0 , 2 ] ) ; assert . strictEqual ( multiMap . sizeOfKeys , 1 ) ; assert . strictEqual ( multiMap . sizeOfValues , 2 ) ; assert . deepEqual ( multiMap . deleteValue ( key1 , key2 , 0 , 2 , 3 ) , [ 0 , 2 ] ) ; assert . strictEqual ( multiMap . sizeOfKeys , 0 ) ; assert . strictEqual ( multiMap . sizeOfValues , 0 ) ; multiMap . set ( key1 , key2 , 1 , 1 , 1 ) ; assert . strictEqual ( multiMap . sizeOfKeys , 1 ) ; assert . strictEqual ( multiMap . sizeOfValues , 3 ) ; assert . deepEqual ( multiMap . deleteValue ( key1 , key2 , 1 ) , [ 1 , 1 , 1 ] ) ; assert . strictEqual ( multiMap . sizeOfKeys , 0 ) ; assert . strictEqual ( multiMap . sizeOfValues , 0 ) ; multiMap . set ( key1 , key2 , 0 , 1 , 2 ) ; multiMap . clear ( ) ; assert . strictEqual ( multiMap . size , 0 ) ; assert . strictEqual ( multiMap . sizeOfKeys , 0 ) ; assert . strictEqual ( multiMap . sizeOfValues , 0 ) ; multiMap . set ( key1 , key2 , 1 ) ; multiMap . set ( { name : "key1" } , { label : "key2" } , 2 ) ; assert . strictEqual ( multiMap . sizeOfKeys , 2 ) ; assert . strictEqual ( multiMap . sizeOfValues , 2 ) ; multiMap . clear ( ) ; assert . deepEqual ( multiMap . get ( key1 , key2 ) , [ ] ) ; assert . deepEqual ( multiMap . has ( key1 , key2 ) , false ) ; let emptyValue = multiMap . get ( key1 , key2 ) ; emptyValue . push ( 2 ) ; assert . deepEqual ( multiMap . get ( key1 , key2 ) , [ ] ) ; multiMap . set ( key1 , key2 , 1 ) ; let existingValue = multiMap . get ( key1 , key2 ) ; existingValue . push ( 2 ) ; assert . deepEqual ( multiMap . get ( key1 , key2 ) , [ 1 ] ) ; for ( let [ , , values ] of multiMap . entries ( ) ) { values . push ( 2 ) ; } assert . deepEqual ( multiMap . get ( key1 , key2 ) , [ 1 ] ) ; for ( let values of multiMap . values ( ) ) { values . push ( 2 ) ; } assert . deepEqual ( multiMap . get ( key1 , key2 ) , [ 1 ] ) ; multiMap . forEach ( ( values ) => { values . push ( 2 ) ; } ) ; assert . deepEqual ( multiMap . get ( key1 , key2 ) , [ 1 ] ) ; } @ test "TwoKeyMultiMap with distinct values" ( ) { let multiMap = new TwoKeyMultiMap < MultiMapKey1 , MultiMapKey2 , number > ( false ) ; let key1 = { name : "key1" } ; let key2 = { label : "key2" } ; multiMap . set ( key1 , key2 , 0 ) ; multiMap . set ( key1 , key2 , 1 , 2 ) ; let values = multiMap . get ( key1 , key2 ) ; assert . deepEqual ( values , [ 0 , 1 , 2 ] ) ; assert . strictEqual ( multiMap . size , 1 ) ; assert . strictEqual ( multiMap . sizeOfKeys , 1 ) ; assert . strictEqual ( multiMap . sizeOfValues , 3 ) ; let entries = new Array < [ MultiMapKey1 , MultiMapKey2 , number [ ] ] > ( ) ; for ( let entry of multiMap . entries ( ) ) { entries . push ( entry ) ; } assert . deepEqual ( entries , [ [ key1 , key2 , [ 0 , 1 , 2 ] ] ] ) ; let individualEntries = new Array < [ MultiMapKey1 , MultiMapKey2 , number ] > ( ) ; for ( let entry of multiMap . individualEntries ( ) ) { individualEntries . push ( entry ) ; } assert . deepEqual ( individualEntries , [ [ key1 , key2 , 0 ] , [ key1 , key2 , 1 ] , [ key1 , key2 , 2 ] ] ) ; multiMap . deleteValue ( key1 , key2 , 1 ) ; assert . deepEqual ( multiMap . get ( key1 , key2 ) , [ 0 , 2 ] ) ; assert . strictEqual ( multiMap . sizeOfKeys , 1 ) ; assert . strictEqual ( multiMap . sizeOfValues , 2 ) ; assert . deepEqual ( multiMap . deleteValue ( key1 , key2 , 0 , 2 , 3 ) , [ 0 , 2 ] ) ; assert . strictEqual ( multiMap . sizeOfKeys , 0 ) ; assert . strictEqual ( multiMap . sizeOfValues , 0 ) ; multiMap . set ( key1 , key2 , 1 , 1 , 1 ) ; assert . strictEqual ( multiMap . sizeOfKeys , 1 ) ; assert . strictEqual ( multiMap . sizeOfValues , 1 ) ; assert . deepEqual ( multiMap . deleteValue ( key1 , key2 , 1 ) , [ 1 ] ) ; assert . strictEqual ( multiMap . sizeOfKeys , 0 ) ; assert . strictEqual ( multiMap . sizeOfValues , 0 ) ; multiMap . set ( key1 , key2 , 0 , 1 , 2 ) ; multiMap . clear ( ) ; assert . strictEqual ( multiMap . size , 0 ) ; assert . strictEqual ( multiMap . sizeOfKeys , 0 ) ; assert . strictEqual ( multiMap . sizeOfValues , 0 ) ; multiMap . set ( key1 , key2 , 1 ) ; multiMap . set ( { name : "key1" } , { label : "key2" } , 2 ) ; assert . strictEqual ( multiMap . sizeOfKeys , 2 ) ; assert . strictEqual ( multiMap . sizeOfValues , 2 ) ; multiMap . clear ( ) ; assert . deepEqual ( multiMap . get ( key1 , key2 ) , [ ] ) ; assert . deepEqual ( multiMap . has ( key1 , key2 ) , false ) ; let emptyValue = multiMap . get ( key1 , key2 ) ; emptyValue . push ( 2 ) ; assert . deepEqual ( multiMap . get ( key1 , key2 ) , [ ] ) ; multiMap . set ( key1 , key2 , 1 ) ; let existingValue = multiMap . get ( key1 , key2 ) ; existingValue . push ( 2 ) ; assert . deepEqual ( multiMap . get ( key1 , key2 ) , [ 1 ] ) ; for ( let [ , , values ] of multiMap . entries ( ) ) { values . push ( 2 ) ; } assert . deepEqual ( multiMap . get ( key1 , key2 ) , [ 1 ] ) ; for ( let values of multiMap . values ( ) ) { values . push ( 2 ) ; } assert . deepEqual ( multiMap . get ( key1 , key2 ) , [ 1 ] ) ; multiMap . forEach ( ( values ) => { values . push ( 2 ) ; } ) ; assert . deepEqual ( multiMap . get ( key1 , key2 ) , [ 1 ] ) ; } @ test "flatten a flat array" ( ) { let arr = [ "hello" , "world" ] ; assert . equal ( flatten ( arr ) , arr ) ; } @ test "flatten a nested array" ( ) { assert . deepEqual ( flatten < string > ( [ [ "hello" , "world" ] ] ) , [ "hello" , "world" ] ) ; } @ test "flatten two nested arrays" ( ) { assert . deepEqual ( flatten < string > ( [ [ "hello" ] , [ "world" ] ] ) , [ "hello" , "world" ] ) ; } @ test "flatten some ridiculousness" ( ) { assert . deepEqual ( flatten < string | number > ( [ [ "a" ] , [ "b" , [ "c" , 1 ] ] , [ 2 , [ [ 3 ] ] ] ] ) , [ "a" , "b" , "c" , 1 , 2 , 3 ] ) ; } }