import { expect } from 'chai' ; import { DisposableDelegate , DisposableSet , IDisposable , ObservableDisposableDelegate , ObservableDisposableSet } from '@lumino/disposable' ; class TestDisposable implements IDisposable { count = 0 ; get isDisposed ( ) : boolean { return this . count > 0 ; } dispose ( ) { this . count ++ ; } } describe ( '@lumino/disposable' , ( ) => { describe ( 'DisposableDelegate' , ( ) => { describe ( '#constructor()' , ( ) => { it ( 'should accept a callback' , ( ) => { let delegate = new DisposableDelegate ( ( ) => { } ) ; expect ( delegate ) . to . be . an . instanceof ( DisposableDelegate ) ; } ) ; } ) ; describe ( '#isDisposed' , ( ) => { it ( 'should be `false` before object is disposed' , ( ) => { let delegate = new DisposableDelegate ( ( ) => { } ) ; expect ( delegate . isDisposed ) . to . equal ( false ) ; } ) ; it ( 'should be `true` after object is disposed' , ( ) => { let delegate = new DisposableDelegate ( ( ) => { } ) ; delegate . dispose ( ) ; expect ( delegate . isDisposed ) . to . equal ( true ) ; } ) ; } ) ; describe ( '#dispose()' , ( ) => { it ( 'should invoke a callback when disposed' , ( ) => { let called = false ; let delegate = new DisposableDelegate ( ( ) => ( called = true ) ) ; expect ( called ) . to . equal ( false ) ; delegate . dispose ( ) ; expect ( called ) . to . equal ( true ) ; } ) ; it ( 'should ignore multiple calls to `dispose`' , ( ) => { let count = 0 ; let delegate = new DisposableDelegate ( ( ) => count ++ ) ; expect ( count ) . to . equal ( 0 ) ; delegate . dispose ( ) ; delegate . dispose ( ) ; delegate . dispose ( ) ; expect ( count ) . to . equal ( 1 ) ; } ) ; } ) ; } ) ; describe ( 'ObservableDisposableDelegate' , ( ) => { describe ( '#disposed' , ( ) => { it ( 'should be emitted when the delegate is disposed' , ( ) => { let called = false ; let delegate = new ObservableDisposableDelegate ( ( ) => { } ) ; delegate . disposed . connect ( ( ) => { called = true ; } ) ; delegate . dispose ( ) ; expect ( called ) . to . equal ( true ) ; } ) ; } ) ; } ) ; describe ( 'DisposableSet' , ( ) => { describe ( '#constructor()' , ( ) => { it ( 'should accept no arguments' , ( ) => { let set = new DisposableSet ( ) ; expect ( set ) . to . be . an . instanceof ( DisposableSet ) ; } ) ; } ) ; describe ( '#isDisposed' , ( ) => { it ( 'should be `false` before object is disposed' , ( ) => { let set = new DisposableSet ( ) ; expect ( set . isDisposed ) . to . equal ( false ) ; } ) ; it ( 'should be `true` after object is disposed' , ( ) => { let set = new DisposableSet ( ) ; set . dispose ( ) ; expect ( set . isDisposed ) . to . equal ( true ) ; } ) ; } ) ; describe ( '#dispose()' , ( ) => { it ( 'should dispose all items in the set' , ( ) => { let item1 = new TestDisposable ( ) ; let item2 = new TestDisposable ( ) ; let item3 = new TestDisposable ( ) ; let set = DisposableSet . from ( [ item1 , item2 , item3 ] ) ; expect ( item1 . count ) . to . equal ( 0 ) ; expect ( item2 . count ) . to . equal ( 0 ) ; expect ( item3 . count ) . to . equal ( 0 ) ; set . dispose ( ) ; expect ( item1 . count ) . to . equal ( 1 ) ; expect ( item2 . count ) . to . equal ( 1 ) ; expect ( item3 . count ) . to . equal ( 1 ) ; } ) ; it ( 'should dipose items in the order they were added' , ( ) => { let values = [ ] ; let item1 = new DisposableDelegate ( ( ) => values . push ( 0 ) ) ; let item2 = new DisposableDelegate ( ( ) => values . push ( 1 ) ) ; let item3 = new DisposableDelegate ( ( ) => values . push ( 2 ) ) ; let set = DisposableSet . from ( [ item1 , item2 , item3 ] ) ; expect ( values ) . to . deep . equal ( [ ] ) ; set . dispose ( ) ; expect ( values ) . to . deep . equal ( [ 0 , 1 , 2 ] ) ; } ) ; it ( 'should ignore multiple calls to `dispose`' , ( ) => { let item1 = new TestDisposable ( ) ; let item2 = new TestDisposable ( ) ; let item3 = new TestDisposable ( ) ; let set = DisposableSet . from ( [ item1 , item2 , item3 ] ) ; expect ( item1 . count ) . to . equal ( 0 ) ; expect ( item2 . count ) . to . equal ( 0 ) ; expect ( item3 . count ) . to . equal ( 0 ) ; set . dispose ( ) ; set . dispose ( ) ; set . dispose ( ) ; expect ( item1 . count ) . to . equal ( 1 ) ; expect ( item2 . count ) . to . equal ( 1 ) ; expect ( item3 . count ) . to . equal ( 1 ) ; } ) ; } ) ; describe ( '#add()' , ( ) => { it ( 'should add items to the set' , ( ) => { let item1 = new TestDisposable ( ) ; let item2 = new TestDisposable ( ) ; let item3 = new TestDisposable ( ) ; let set = new DisposableSet ( ) ; set . add ( item1 ) ; set . add ( item2 ) ; set . add ( item3 ) ; expect ( item1 . count ) . to . equal ( 0 ) ; expect ( item2 . count ) . to . equal ( 0 ) ; expect ( item3 . count ) . to . equal ( 0 ) ; set . dispose ( ) ; expect ( item1 . count ) . to . equal ( 1 ) ; expect ( item2 . count ) . to . equal ( 1 ) ; expect ( item3 . count ) . to . equal ( 1 ) ; } ) ; it ( 'should maintain insertion order' , ( ) => { let values = [ ] ; let item1 = new DisposableDelegate ( ( ) => values . push ( 0 ) ) ; let item2 = new DisposableDelegate ( ( ) => values . push ( 1 ) ) ; let item3 = new DisposableDelegate ( ( ) => values . push ( 2 ) ) ; let set = DisposableSet . from ( [ item1 ] ) ; set . add ( item2 ) ; set . add ( item3 ) ; expect ( values ) . to . deep . equal ( [ ] ) ; set . dispose ( ) ; expect ( values ) . to . deep . equal ( [ 0 , 1 , 2 ] ) ; } ) ; it ( 'should ignore duplicate items' , ( ) => { let values = [ ] ; let item1 = new DisposableDelegate ( ( ) => values . push ( 0 ) ) ; let item2 = new DisposableDelegate ( ( ) => values . push ( 1 ) ) ; let item3 = new DisposableDelegate ( ( ) => values . push ( 2 ) ) ; let set = DisposableSet . from ( [ item1 ] ) ; set . add ( item2 ) ; set . add ( item3 ) ; set . add ( item3 ) ; set . add ( item2 ) ; set . add ( item1 ) ; expect ( values ) . to . deep . equal ( [ ] ) ; set . dispose ( ) ; expect ( values ) . to . deep . equal ( [ 0 , 1 , 2 ] ) ; } ) ; } ) ; describe ( '#remove()' , ( ) => { it ( 'should remove items from the set' , ( ) => { let item1 = new TestDisposable ( ) ; let item2 = new TestDisposable ( ) ; let item3 = new TestDisposable ( ) ; let set = DisposableSet . from ( [ item1 , item2 , item3 ] ) ; expect ( item1 . count ) . to . equal ( 0 ) ; expect ( item2 . count ) . to . equal ( 0 ) ; expect ( item3 . count ) . to . equal ( 0 ) ; set . remove ( item2 ) ; set . dispose ( ) ; expect ( item1 . count ) . to . equal ( 1 ) ; expect ( item2 . count ) . to . equal ( 0 ) ; expect ( item3 . count ) . to . equal ( 1 ) ; } ) ; it ( 'should maintain insertion order' , ( ) => { let values = [ ] ; let item1 = new DisposableDelegate ( ( ) => values . push ( 0 ) ) ; let item2 = new DisposableDelegate ( ( ) => values . push ( 1 ) ) ; let item3 = new DisposableDelegate ( ( ) => values . push ( 2 ) ) ; let set = DisposableSet . from ( [ item1 , item2 , item3 ] ) ; expect ( values ) . to . deep . equal ( [ ] ) ; set . remove ( item1 ) ; set . dispose ( ) ; expect ( values ) . to . deep . equal ( [ 1 , 2 ] ) ; } ) ; it ( 'should ignore missing items' , ( ) => { let values = [ ] ; let item1 = new DisposableDelegate ( ( ) => values . push ( 0 ) ) ; let item2 = new DisposableDelegate ( ( ) => values . push ( 1 ) ) ; let item3 = new DisposableDelegate ( ( ) => values . push ( 2 ) ) ; let set = DisposableSet . from ( [ item1 , item2 ] ) ; expect ( values ) . to . deep . equal ( [ ] ) ; set . remove ( item3 ) ; set . dispose ( ) ; expect ( values ) . to . deep . equal ( [ 0 , 1 ] ) ; } ) ; } ) ; describe ( '#clear()' , ( ) => { it ( 'remove all items from the set' , ( ) => { let item1 = new TestDisposable ( ) ; let item2 = new TestDisposable ( ) ; let item3 = new TestDisposable ( ) ; let set = DisposableSet . from ( [ item1 , item2 , item3 ] ) ; expect ( item1 . count ) . to . equal ( 0 ) ; expect ( item2 . count ) . to . equal ( 0 ) ; expect ( item3 . count ) . to . equal ( 0 ) ; set . clear ( ) ; set . dispose ( ) ; expect ( item1 . count ) . to . equal ( 0 ) ; expect ( item2 . count ) . to . equal ( 0 ) ; expect ( item3 . count ) . to . equal ( 0 ) ; } ) ; } ) ; describe ( '.from()' , ( ) => { it ( 'should accept an iterable of disposable items' , ( ) => { let item1 = new TestDisposable ( ) ; let item2 = new TestDisposable ( ) ; let item3 = new TestDisposable ( ) ; let set = DisposableSet . from ( [ item1 , item2 , item3 ] ) ; expect ( set ) . to . be . an . instanceof ( DisposableSet ) ; } ) ; } ) ; } ) ; describe ( 'ObservableDisposableSet' , ( ) => { describe ( '#disposed' , ( ) => { it ( 'should be emitted when the set is disposed' , ( ) => { let called = false ; let set = new ObservableDisposableSet ( ) ; let item1 = new TestDisposable ( ) ; let item2 = new TestDisposable ( ) ; let item3 = new TestDisposable ( ) ; set . add ( item1 ) ; set . add ( item2 ) ; set . add ( item3 ) ; set . disposed . connect ( ( ) => { expect ( set . contains ( item1 ) ) . to . equal ( false ) ; expect ( set . contains ( item2 ) ) . to . equal ( false ) ; expect ( set . contains ( item3 ) ) . to . equal ( false ) ; expect ( item1 . isDisposed ) . to . equal ( true ) ; expect ( item2 . isDisposed ) . to . equal ( true ) ; expect ( item3 . isDisposed ) . to . equal ( true ) ; called = true ; } ) ; set . dispose ( ) ; expect ( called ) . to . equal ( true ) ; } ) ; } ) ; describe ( '.from()' , ( ) => { it ( 'should accept an iterable of disposable items' , ( ) => { let item1 = new TestDisposable ( ) ; let item2 = new TestDisposable ( ) ; let item3 = new TestDisposable ( ) ; let set = ObservableDisposableSet . from ( [ item1 , item2 , item3 ] ) ; expect ( set ) . to . be . an . instanceof ( ObservableDisposableSet ) ; } ) ; } ) ; } ) ; } ) ;