/**
 * Copyright (c) 2016-present, Facebook, Inc.
 *
 * This source code is licensed under the MIT license found in the
 * LICENSE file in the root directory of this source tree.
 */ import * as LazySequence from '../lazy-sequence' ; import * as Functor from '../functor' ; import * as Promise from '../promise' ; describe ( 'LazySequence' , function ( ) { describe ( 'Sequence' , function ( ) { it ( 'should return a future for an array of the sequnce when asked to ' + 'evalutate the lazy sequence' , function ( ) { const source = LazySequence . source < number > ( ) ; const sequence = source . getSequence ( ) ; const future = LazySequence . evaluate ( sequence ) ; var wasRun = false ; Promise . then ( function ( numbers ) { wasRun = true ; expect ( numbers ) . toEqualJSON ( [ 1 , 2 , 3 , 4 ] ) ; } , future ) ; source . nextValue ( 1 ) ; source . nextValue ( 2 ) ; source . nextValue ( 3 ) ; source . nextValue ( 4 ) ; source . finished ( ) ; expect ( wasRun ) . toBe ( true ) ; } ) ; it ( 'should allow a hook into each new value as it comes into the sequence' + 'as the values come in' , function ( ) { const source = LazySequence . source < number > ( ) ; const sequence = source . getSequence ( ) ; const future = LazySequence . evaluate ( sequence ) ; var wasRun = false ; const soFar = [ ] ; LazySequence . forEach ( function ( num ) { soFar . push ( num ) ; } , sequence ) ; Promise . then ( function ( numbers ) { wasRun = true ; expect ( numbers ) . toEqualJSON ( [ 1 , 2 , 3 , 4 ] ) ; } , future ) ; source . nextValue ( 1 ) ; expect ( soFar ) . toEqualJSON ( [ 1 ] ) ; source . nextValue ( 2 ) ; expect ( soFar ) . toEqualJSON ( [ 1 , 2 ] ) ; source . nextValue ( 3 ) ; expect ( soFar ) . toEqualJSON ( [ 1 , 2 , 3 ] ) ; source . nextValue ( 4 ) ; expect ( soFar ) . toEqualJSON ( [ 1 , 2 , 3 , 4 ] ) ; source . finished ( ) ; expect ( wasRun ) . toBe ( true ) ; } ) ; it ( 'should allow a hook into each new value as it comes into the sequence' + 'as the values come in but it does all the values so far when the ' + 'enumeration starts after the events start coming in' , function ( ) { const source = LazySequence . source < number > ( ) ; const sequence = source . getSequence ( ) ; const future = LazySequence . evaluate ( sequence ) ; var wasRun = false ; const soFar = [ ] ; Promise . then ( function ( numbers ) { wasRun = true ; expect ( numbers ) . toEqualJSON ( [ 1 , 2 , 3 , 4 ] ) ; } , future ) ; source . nextValue ( 1 ) ; expect ( soFar ) . toEqualJSON ( [ ] ) ; LazySequence . forEach ( function ( num ) { soFar . push ( num ) ; } , sequence ) ; source . nextValue ( 2 ) ; expect ( soFar ) . toEqualJSON ( [ 1 , 2 ] ) ; source . nextValue ( 3 ) ; expect ( soFar ) . toEqualJSON ( [ 1 , 2 , 3 ] ) ; source . nextValue ( 4 ) ; expect ( soFar ) . toEqualJSON ( [ 1 , 2 , 3 , 4 ] ) ; source . finished ( ) ; expect ( wasRun ) . toBe ( true ) ; } ) ; it ( 'should allow for evaluation to be called even after the sequence has ' + 'been completed' , function ( ) { const source = LazySequence . source < number > ( ) ; const sequence = source . getSequence ( ) ; var wasRun = false ; source . nextValue ( 1 ) ; source . nextValue ( 2 ) ; source . nextValue ( 3 ) ; source . nextValue ( 4 ) ; source . finished ( ) ; const future = LazySequence . evaluate ( sequence ) ; Promise . then ( function ( numbers ) { wasRun = true ; expect ( numbers ) . toEqualJSON ( [ 1 , 2 , 3 , 4 ] ) ; } , future ) ; expect ( wasRun ) . toBe ( true ) ; } ) ; it ( 'should error if calling nextValue after finished' , function ( ) { const source = LazySequence . source < number > ( ) ; source . nextValue ( 3 ) ; source . finished ( ) ; expect ( function ( ) { source . nextValue ( 3 ) ; } ) . toThrow ( ) ; } ) ; it ( 'should allow mapping to another lazy sequence and evaluating the ' + 'result' , function ( ) { const source = LazySequence . source < number > ( ) ; const sequence = source . getSequence ( ) ; const mappedSequence = LazySequence . map ( function ( num ) { return num . toString ( ) ; } , sequence ) ; var wasRun = false ; source . nextValue ( 1 ) ; source . nextValue ( 2 ) ; source . nextValue ( 3 ) ; source . nextValue ( 4 ) ; source . finished ( ) ; const future = LazySequence . evaluate ( mappedSequence ) ; Promise . then ( function ( numbers ) { wasRun = true ; expect ( numbers ) . toEqualJSON ( [ '1' , '2' , '3' , '4' ] ) ; } , future ) ; expect ( wasRun ) . toBe ( true ) ; } ) ; it ( 'should allow mapping to another lazy sequence and getting each of ' + 'the values as they come in' , function ( ) { const source = LazySequence . source < number > ( ) ; const sequence = source . getSequence ( ) ; const mappedSequence = LazySequence . map ( function ( num ) { return num . toString ( ) ; } , sequence ) ; var wasRun = false ; const soFar = [ ] ; LazySequence . forEach ( function ( str ) { soFar . push ( str ) ; } , mappedSequence ) ; source . nextValue ( 1 ) ; expect ( soFar ) . toEqualJSON ( [ '1' ] ) ; source . nextValue ( 2 ) ; expect ( soFar ) . toEqualJSON ( [ '1' , '2' ] ) ; source . nextValue ( 3 ) ; expect ( soFar ) . toEqualJSON ( [ '1' , '2' , '3' ] ) ; source . nextValue ( 4 ) ; expect ( soFar ) . toEqualJSON ( [ '1' , '2' , '3' , '4' ] ) ; source . finished ( ) ; const future = LazySequence . evaluate ( mappedSequence ) ; Promise . then ( function ( numbers ) { wasRun = true ; expect ( numbers ) . toEqualJSON ( [ '1' , '2' , '3' , '4' ] ) ; } , future ) ; expect ( wasRun ) . toBe ( true ) ; } ) ; it ( 'should allow mapping as a functor and getting each of ' + 'the values as they come in' , function ( ) { const source = LazySequence . source < number > ( ) ; const sequence = source . getSequence ( ) ; const mappedSequence = Functor . map ( function ( num ) { return num . toString ( ) ; } , sequence ) ; var wasRun = false ; const soFar = [ ] ; LazySequence . forEach ( function ( str ) { soFar . push ( str ) ; } , < LazySequence . Sequence < string > > mappedSequence ) ; source . nextValue ( 1 ) ; expect ( soFar ) . toEqualJSON ( [ '1' ] ) ; source . nextValue ( 2 ) ; expect ( soFar ) . toEqualJSON ( [ '1' , '2' ] ) ; source . nextValue ( 3 ) ; expect ( soFar ) . toEqualJSON ( [ '1' , '2' , '3' ] ) ; source . nextValue ( 4 ) ; expect ( soFar ) . toEqualJSON ( [ '1' , '2' , '3' , '4' ] ) ; source . finished ( ) ; const future = LazySequence . evaluate ( < LazySequence . Sequence < string > > mappedSequence ) ; Promise . then ( function ( numbers ) { wasRun = true ; expect ( numbers ) . toEqualJSON ( [ '1' , '2' , '3' , '4' ] ) ; } , future ) ; expect ( wasRun ) . toBe ( true ) ; } ) ; it ( 'should allow folding and getting each of the values as they come in' , function ( ) { const source = LazySequence . source < number > ( ) ; const sequence = source . getSequence ( ) ; const foldedSequence = LazySequence . foldl ( function ( soFar , num ) { if ( num % 2 === 0 ) { return soFar . concat ( num ) ; } else { return soFar ; } } , [ ] , sequence ) ; var wasRun = false ; source . nextValue ( 1 ) ; source . nextValue ( 2 ) ; source . nextValue ( 3 ) ; source . nextValue ( 4 ) ; source . finished ( ) ; Promise . then ( function ( numbers ) { wasRun = true ; expect ( numbers ) . toEqualJSON ( [ 2 , 4 ] ) ; } , foldedSequence ) ; expect ( wasRun ) . toBe ( true ) ; } ) ; } ) ; } ) ;