001    // Copyright 2007 Waterken Inc. under the terms of the MIT X license
002    // found at http://www.opensource.org/licenses/mit-license.html
003    package org.waterken.serial;
004    
005    import static org.ref_send.promise.Eventual.ref;
006    import static org.ref_send.test.Logic.join;
007    import static org.ref_send.test.Logic.was;
008    
009    import org.joe_e.array.ConstArray;
010    import org.ref_send.list.List;
011    import org.ref_send.promise.Eventual;
012    import org.ref_send.promise.Promise;
013    
014    /**
015     * Eventual invocation tests.
016     * <p>
017     * This class provides an introduction to eventual operations by using them to
018     * test the elements of a series that isn't produced until later. Within these
019     * lines, time and space are not just curved, they're bent. You should also
020     * probably save this example until later.
021     * </p>
022     */
023    public final class
024    PopPushN {
025        private PopPushN() {}
026        
027        /**
028         * Runs a unit test.
029         * @param _ eventual operator
030         * @param n number of test iterations
031         */
032        static public Promise<?>
033        make(final Eventual _, final int n) {
034            final Series<Integer> x = Serial.make(_);
035            
036            /*
037             * Check that the first n integers in the series will be the
038             * numbers from 0 through n.
039             */
040            final ConstArray.Builder<Promise<?>> r = ConstArray.builder();
041            for (int i = 0; i != n; ++i) {
042                r.append(_.when(x.consume(), was(i)));
043            }
044            
045            /*
046             * Append the numbers 0 through n to the series.
047             */
048            for (int i = 0; i != n; ++i) {
049                x.produce(ref(i));
050            }
051            
052            return join(_, r.snapshot().toArray(new Object[0]));
053        }
054        
055        // Command line interface
056    
057        /**
058         * Executes the test.
059         * @param args  argument string
060         * @throws Exception    test failed
061         */
062        static public void
063        main(final String[] args) throws Exception {
064            final int n = args.length > 0 ? Integer.parseInt(args[0]) : 4;
065            
066            final List<Promise<?>> work = List.list();
067            final Promise<?> result = make(new Eventual(work.appender()), n);
068            while (!work.isEmpty()) { work.pop().call(); }
069            result.call();
070        }
071    }