1TestAbstractFunction : UnitTest {
2
3	test_rest_binop_return {
4		var args = [[1, Rest(1)], [Rest(1), 1], [Rest(1), Rest(1)], [1, Rest()], [Rest(), Rest()]];
5		var funcs = [
6			{ |a, b| a * b },
7			{ |a, b| a + b },
8			{ |a, b| a - b },
9			{ |a, b| a / b }
10		];
11
12		funcs.do { |func|
13			var passed = args.every { |pair|
14				var res = func.valueArray(pair);
15				var ok = res.isKindOf(Rest);
16				if(ok.not) {
17					this.failed(thisMethod, "Calling % on % should return a Rest instance".format(func, pair));
18				};
19				ok
20			};
21
22			this.assert(passed, "Rest should combine to Rest with objects and other Rest instances under binary ops");
23		}
24
25	}
26
27
28	test_rest_binop_values {
29		var args = [[2, Rest(3)], [Rest(2), 3], [Rest(2), Rest(3)]];
30		var funcs = [
31			{ |a, b| a * b },
32			{ |a, b| a + b },
33			{ |a, b| a - b },
34			{ |a, b| a / b }
35		];
36
37		funcs.do { |func|
38			var passed = args.every { |pair|
39				var res = func.valueArray(pair);
40				var res2 = func.valueArray(pair.collect(_.value));
41				var ok = res.value == res2;
42				if(ok.not) {
43					this.failed(thisMethod, "Calling % on % should have the same result as its values wold have".format(func, pair));
44				};
45				ok
46			};
47
48			this.assert(passed, "Rest should combine under binary ops to the same values as the values would");
49		}
50
51	}
52
53	test_rest_comparisons {
54
55		var func = { |op, a, b| a.perform(op, b) == a.value.perform(op, b.value) };
56		var all = [(0..2), (0..2).collect(Rest(_))].allTuples;
57		all = all ++ all.collect(_.reverse);
58		['<', '>', '<=', '>='].do { |op|
59			all.do { |args|
60				this.assert(func.(op, *args), "% should return a boolean for %".format(args, op));
61			}
62		}
63	}
64
65	test_rest_event_delta {
66
67		this.assertEquals(Rest(),  Rest(1), "Rest default value should be 1");
68
69		this.assertEquals(
70			(degree: Rest(0), parent: Event.default.parent).use { ~freq.value },
71			Rest(60.midicps),
72			"rest passes through event calculations"
73		);
74
75		this.assertEquals(
76			(degree: Rest(7), octave: Rest(4), parent: Event.default.parent).delta,
77			1,
78			"delta is not touched by venet calculations"
79		);
80
81		this.assertEquals((dur: 1).delta, 1, "delta matches dur");
82
83		this.assertEquals((dur: Rest(1)).delta, 1, "delta matches dur with rest");
84
85		this.assertEquals((dur: Rest(1), degree: Rest(7)).delta, 1, "delta matches dur with rest if other keys are rest, too");
86
87
88		this.assertEquals((dur: 1, stretch: 2).delta, 2, "delta matches dur when stretched");
89
90		this.assertEquals((dur: Rest(1)).delta, 1, "delta matches dur with rest");
91
92		this.assertEquals((dur: 1, stretch: Rest(2)).delta, 2, "delta matches dur with rest when stretched with number");
93
94		this.assertEquals((dur: Rest(1), stretch: Rest(2)).delta, 2, "delta matches dur with rest when stretched with rest");
95
96		this.assertEquals((dur: 1, stretch: Rest(2)).delta, 2, "delta number matches dur when stretched with rest");
97
98		this.assertEquals((delta: Rest(1)).delta, 1, "delta matches dur with rest");
99
100		this.assert((dur: nil).delta.isNil, "event delta matches dur value when dur is nil");
101
102		this.assert((delta: nil).delta.isNil, "event delta matches delta value when dur is nil");
103
104		this.assertEquals((delta: Rest(1), stretch: 2).delta, 1,  "stretch applies to dur, not delta");
105
106
107
108		try { (delta: Point(0, 0)).delta } { |err|
109			this.assert(err.isKindOf(PrimitiveFailedError) and: { err.what == "Wrong type." },
110				"using a Point for delta should fail")
111		};
112
113
114
115		try { (dur: Point(0, 0)).delta } { |err|
116			this.assert(err.isKindOf(PrimitiveFailedError) and: { err.what == "Wrong type." },
117				"using a Point for dur should fail")
118		};
119
120
121
122		try { (delta: Rest("boo!")).delta } { |err|
123			this.assert(err.isKindOf(PrimitiveFailedError) and: { err.what == "Wrong type." },
124				"using a Rest with a string for delta should fail")
125		};
126
127
128
129		try { (dur: Rest("boo!")).delta } { |err|
130			this.assert(err.isKindOf(PrimitiveFailedError) and: { err.what == "Wrong type." },
131				"using a Rest with a string for dur should fail")
132		};
133	}
134
135	test_rest_event_isRest {
136
137		this.assertEquals((dur: 1).isRest, false, "event with dur = 1 should return false for isRest");
138
139		this.assertEquals((dur: Rest(1)).isRest, true, "event with dur = Rest(1) should return true for isRest");
140
141		this.assertEquals((type: \rest).isRest, true, "event with dur = \rest should return true for isRest");
142
143		this.assertEquals((degree: \).isRest, true, "event with an empty symbol as dur should return true for isRest");
144
145		this.assertEquals((x: \).isRest, true, "event with an empty symbol in arbitrary key should return true for isRest");
146
147		this.assertEquals((x: \r).isRest, true, "event with an 'r' symbol in arbitrary key should return true for isRest");
148
149		this.assertEquals((x: \rest).isRest, true, "event with an 'rest' symbol in arbitrary key should return true for isRest");
150
151		this.assertEquals((isRest: true).isRest, true, "event[\\isRest] == true is detected as a rest");
152
153		this.assertEquals((isRest: false, dur: Rest(1)).isRest, true, "event[\\isRest] == false does not cancel other entries' Rest status");
154
155		#[\dur, \degree, \paraplui, \type].do { |key|
156			var a, b, c, f;
157
158			a = Pbind(key, Pseries());
159			b = Pcollect({ |e| e[key] = Rest(e[key]) }, a);
160			c = Pbindf(b, key, Pfunc { |e| e[key].value });
161
162			f = { |p| Pevent(Pmul(key, 2, p)) };
163
164			this.assert(Pevent(b).asStream.nextN(8).every(_.isRest), "a rest in key '%' should be a rest".format(key));
165			this.assertEquals(f.(a).asStream.nextN(8), f.(c).asStream.nextN(8),
166				"rest values remain intact for key '%' after binary op".format(key));
167		};
168
169	}
170
171}
172
173