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 }