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 }