1+ {
2+ "status" : " fail" ,
3+ "tests" : [
4+ {
5+ "name" : " Forth > parsing and numbers > numbers just get pushed onto the stack" ,
6+ "status" : " pass" ,
7+ "message" : " " ,
8+ "output" : null ,
9+ "test_code" : " forth.evaluate('1 2 3 4 5');\n expect(forth.stack).toEqual([1, 2, 3, 4, 5]);"
10+ },
11+ {
12+ "name" : " Forth > parsing and numbers > pushes negative numbers onto the stack" ,
13+ "status" : " pass" ,
14+ "message" : " " ,
15+ "output" : null ,
16+ "test_code" : " forth.evaluate('-1 -2 -3 -4 -5');\n expect(forth.stack).toEqual([-1, -2, -3, -4, -5]);"
17+ },
18+ {
19+ "name" : " Forth > addition > can add two numbers" ,
20+ "status" : " pass" ,
21+ "message" : " " ,
22+ "output" : null ,
23+ "test_code" : " forth.evaluate('1 2 +');\n expect(forth.stack).toEqual([3]);"
24+ },
25+ {
26+ "name" : " Forth > addition > errors if there is nothing on the stack" ,
27+ "status" : " pass" ,
28+ "message" : " " ,
29+ "output" : null ,
30+ "test_code" : " expect(() => {\n forth.evaluate('+');\n }).toThrow(new Error('Stack empty'));"
31+ },
32+ {
33+ "name" : " Forth > addition > errors if there is only one value on the stack" ,
34+ "status" : " pass" ,
35+ "message" : " " ,
36+ "output" : null ,
37+ "test_code" : " expect(() => {\n forth.evaluate('1 +');\n }).toThrow(new Error('Only one value on the stack'));"
38+ },
39+ {
40+ "name" : " Forth > addition > more than two values on the stack" ,
41+ "status" : " pass" ,
42+ "message" : " " ,
43+ "output" : null ,
44+ "test_code" : " forth.evaluate('1 2 3 +');\n expect(forth.stack).toEqual([1, 5]);"
45+ },
46+ {
47+ "name" : " Forth > subtraction > can subtract two numbers" ,
48+ "status" : " pass" ,
49+ "message" : " " ,
50+ "output" : null ,
51+ "test_code" : " forth.evaluate('3 4 -');\n expect(forth.stack).toEqual([-1]);"
52+ },
53+ {
54+ "name" : " Forth > subtraction > errors if there is nothing on the stack" ,
55+ "status" : " pass" ,
56+ "message" : " " ,
57+ "output" : null ,
58+ "test_code" : " expect(() => {\n forth.evaluate('-');\n }).toThrow(new Error('Stack empty'));"
59+ },
60+ {
61+ "name" : " Forth > subtraction > errors if there is only one value on the stack" ,
62+ "status" : " pass" ,
63+ "message" : " " ,
64+ "output" : null ,
65+ "test_code" : " expect(() => {\n forth.evaluate('1 -');\n }).toThrow(new Error('Only one value on the stack'));"
66+ },
67+ {
68+ "name" : " Forth > subtraction > more than two values on the stack" ,
69+ "status" : " pass" ,
70+ "message" : " " ,
71+ "output" : null ,
72+ "test_code" : " forth.evaluate('1 12 3 -');\n expect(forth.stack).toEqual([1, 9]);"
73+ },
74+ {
75+ "name" : " Forth > multiplication > can multiply two numbers" ,
76+ "status" : " pass" ,
77+ "message" : " " ,
78+ "output" : null ,
79+ "test_code" : " forth.evaluate('2 4 *');\n expect(forth.stack).toEqual([8]);"
80+ },
81+ {
82+ "name" : " Forth > multiplication > errors if there is nothing on the stack" ,
83+ "status" : " pass" ,
84+ "message" : " " ,
85+ "output" : null ,
86+ "test_code" : " expect(() => {\n forth.evaluate('*');\n }).toThrow(new Error('Stack empty'));"
87+ },
88+ {
89+ "name" : " Forth > multiplication > errors if there is only one value on the stack" ,
90+ "status" : " pass" ,
91+ "message" : " " ,
92+ "output" : null ,
93+ "test_code" : " expect(() => {\n forth.evaluate('1 *');\n }).toThrow(new Error('Only one value on the stack'));"
94+ },
95+ {
96+ "name" : " Forth > multiplication > more than two values on the stack" ,
97+ "status" : " pass" ,
98+ "message" : " " ,
99+ "output" : null ,
100+ "test_code" : " forth.evaluate('1 2 3 *');\n expect(forth.stack).toEqual([1, 6]);"
101+ },
102+ {
103+ "name" : " Forth > division > can divide two numbers" ,
104+ "status" : " pass" ,
105+ "message" : " " ,
106+ "output" : null ,
107+ "test_code" : " forth.evaluate('12 3 /');\n expect(forth.stack).toEqual([4]);"
108+ },
109+ {
110+ "name" : " Forth > division > performs integer division" ,
111+ "status" : " pass" ,
112+ "message" : " " ,
113+ "output" : null ,
114+ "test_code" : " forth.evaluate('8 3 /');\n expect(forth.stack).toEqual([2]);"
115+ },
116+ {
117+ "name" : " Forth > division > errors if dividing by zero" ,
118+ "status" : " pass" ,
119+ "message" : " " ,
120+ "output" : null ,
121+ "test_code" : " expect(() => {\n forth.evaluate('4 0 /');\n }).toThrow(new Error('Division by zero'));"
122+ },
123+ {
124+ "name" : " Forth > division > errors if there is nothing on the stack" ,
125+ "status" : " pass" ,
126+ "message" : " " ,
127+ "output" : null ,
128+ "test_code" : " expect(() => {\n forth.evaluate('/');\n }).toThrow(new Error('Stack empty'));"
129+ },
130+ {
131+ "name" : " Forth > division > errors if there is only one value on the stack" ,
132+ "status" : " pass" ,
133+ "message" : " " ,
134+ "output" : null ,
135+ "test_code" : " expect(() => {\n forth.evaluate('1 /');\n }).toThrow(new Error('Only one value on the stack'));"
136+ },
137+ {
138+ "name" : " Forth > division > more than two values on the stack" ,
139+ "status" : " pass" ,
140+ "message" : " " ,
141+ "output" : null ,
142+ "test_code" : " forth.evaluate('1 12 3 /');\n expect(forth.stack).toEqual([1, 4]);"
143+ },
144+ {
145+ "name" : " Forth > combined arithmetic > addition and subtraction" ,
146+ "status" : " pass" ,
147+ "message" : " " ,
148+ "output" : null ,
149+ "test_code" : " forth.evaluate('1 2 + 4 -');\n expect(forth.stack).toEqual([-1]);"
150+ },
151+ {
152+ "name" : " Forth > combined arithmetic > multiplication and division" ,
153+ "status" : " pass" ,
154+ "message" : " " ,
155+ "output" : null ,
156+ "test_code" : " forth.evaluate('2 4 * 3 /');\n expect(forth.stack).toEqual([2]);"
157+ },
158+ {
159+ "name" : " Forth > combined arithmetic > multiplication and addition" ,
160+ "status" : " pass" ,
161+ "message" : " " ,
162+ "output" : null ,
163+ "test_code" : " forth.evaluate('1 3 4 * +');\n expect(forth.stack).toEqual([13]);"
164+ },
165+ {
166+ "name" : " Forth > combined arithmetic > addition and multiplication" ,
167+ "status" : " pass" ,
168+ "message" : " " ,
169+ "output" : null ,
170+ "test_code" : " forth.evaluate('1 3 4 + *');\n expect(forth.stack).toEqual([7]);"
171+ },
172+ {
173+ "name" : " Forth > dup > copies a value on the stack" ,
174+ "status" : " pass" ,
175+ "message" : " " ,
176+ "output" : null ,
177+ "test_code" : " forth.evaluate('1 dup');\n expect(forth.stack).toEqual([1, 1]);"
178+ },
179+ {
180+ "name" : " Forth > dup > copies the top value on the stack" ,
181+ "status" : " pass" ,
182+ "message" : " " ,
183+ "output" : null ,
184+ "test_code" : " forth.evaluate('1 2 dup');\n expect(forth.stack).toEqual([1, 2, 2]);"
185+ },
186+ {
187+ "name" : " Forth > dup > errors if there is nothing on the stack" ,
188+ "status" : " pass" ,
189+ "message" : " " ,
190+ "output" : null ,
191+ "test_code" : " expect(() => {\n forth.evaluate('dup');\n }).toThrow(new Error('Stack empty'));"
192+ },
193+ {
194+ "name" : " Forth > drop > removes the top value on the stack if it is the only one" ,
195+ "status" : " pass" ,
196+ "message" : " " ,
197+ "output" : null ,
198+ "test_code" : " forth.evaluate('1 drop');\n expect(forth.stack).toEqual([]);"
199+ },
200+ {
201+ "name" : " Forth > drop > removes the top value on the stack if it is not the only one" ,
202+ "status" : " pass" ,
203+ "message" : " " ,
204+ "output" : null ,
205+ "test_code" : " forth.evaluate('1 2 drop');\n expect(forth.stack).toEqual([1]);"
206+ },
207+ {
208+ "name" : " Forth > drop > errors if there is nothing on the stack" ,
209+ "status" : " pass" ,
210+ "message" : " " ,
211+ "output" : null ,
212+ "test_code" : " expect(() => {\n forth.evaluate('drop');\n }).toThrow(new Error('Stack empty'));"
213+ },
214+ {
215+ "name" : " Forth > swap > swaps the top two values on the stack if they are the only ones" ,
216+ "status" : " pass" ,
217+ "message" : " " ,
218+ "output" : null ,
219+ "test_code" : " forth.evaluate('1 2 swap');\n expect(forth.stack).toEqual([2, 1]);"
220+ },
221+ {
222+ "name" : " Forth > swap > swaps the top two values on the stack if they are not the only ones" ,
223+ "status" : " pass" ,
224+ "message" : " " ,
225+ "output" : null ,
226+ "test_code" : " forth.evaluate('1 2 3 swap');\n expect(forth.stack).toEqual([1, 3, 2]);"
227+ },
228+ {
229+ "name" : " Forth > swap > errors if there is nothing on the stack" ,
230+ "status" : " pass" ,
231+ "message" : " " ,
232+ "output" : null ,
233+ "test_code" : " expect(() => {\n forth.evaluate('swap');\n }).toThrow(new Error('Stack empty'));"
234+ },
235+ {
236+ "name" : " Forth > swap > errors if there is only one value on the stack" ,
237+ "status" : " pass" ,
238+ "message" : " " ,
239+ "output" : null ,
240+ "test_code" : " expect(() => {\n forth.evaluate('1 swap');\n }).toThrow(new Error('Only one value on the stack'));"
241+ },
242+ {
243+ "name" : " Forth > over > copies the second element if there are only two" ,
244+ "status" : " pass" ,
245+ "message" : " " ,
246+ "output" : null ,
247+ "test_code" : " forth.evaluate('1 2 over');\n expect(forth.stack).toEqual([1, 2, 1]);"
248+ },
249+ {
250+ "name" : " Forth > over > copies the second element if there are more than two" ,
251+ "status" : " pass" ,
252+ "message" : " " ,
253+ "output" : null ,
254+ "test_code" : " forth.evaluate('1 2 3 over');\n expect(forth.stack).toEqual([1, 2, 3, 2]);"
255+ },
256+ {
257+ "name" : " Forth > over > errors if there is nothing on the stack" ,
258+ "status" : " pass" ,
259+ "message" : " " ,
260+ "output" : null ,
261+ "test_code" : " expect(() => {\n forth.evaluate('over');\n }).toThrow(new Error('Stack empty'));"
262+ },
263+ {
264+ "name" : " Forth > over > errors if there is only one value on the stack" ,
265+ "status" : " pass" ,
266+ "message" : " " ,
267+ "output" : null ,
268+ "test_code" : " expect(() => {\n forth.evaluate('1 over');\n }).toThrow(new Error('Only one value on the stack'));"
269+ },
270+ {
271+ "name" : " Forth > user-defined words > can consist of built-in words" ,
272+ "status" : " fail" ,
273+ "message" : " TypeError: RegExp.escape is not a function\n at Forth.escape (<solution>/forth.js:56:43)" ,
274+ "output" : null ,
275+ "test_code" : " forth.evaluate(': dup-twice dup dup ;');\n forth.evaluate('1 dup-twice');\n expect(forth.stack).toEqual([1, 1, 1]);"
276+ },
277+ {
278+ "name" : " Forth > user-defined words > execute in the right order" ,
279+ "status" : " fail" ,
280+ "message" : " TypeError: RegExp.escape is not a function\n at Forth.escape (<solution>/forth.js:56:43)" ,
281+ "output" : null ,
282+ "test_code" : " forth.evaluate(': countup 1 2 3 ;');\n forth.evaluate('countup');\n expect(forth.stack).toEqual([1, 2, 3]);"
283+ },
284+ {
285+ "name" : " Forth > user-defined words > can override other user-defined words" ,
286+ "status" : " fail" ,
287+ "message" : " TypeError: RegExp.escape is not a function\n at Forth.escape (<solution>/forth.js:56:43)" ,
288+ "output" : null ,
289+ "test_code" : " forth.evaluate(': foo dup ;');\n forth.evaluate(': foo dup dup ;');\n forth.evaluate('1 foo');\n expect(forth.stack).toEqual([1, 1, 1]);"
290+ },
291+ {
292+ "name" : " Forth > user-defined words > can override built-in words" ,
293+ "status" : " fail" ,
294+ "message" : " TypeError: RegExp.escape is not a function\n at Forth.escape (<solution>/forth.js:56:43)" ,
295+ "output" : null ,
296+ "test_code" : " forth.evaluate(': swap dup ;');\n forth.evaluate('1 swap');\n expect(forth.stack).toEqual([1, 1]);"
297+ },
298+ {
299+ "name" : " Forth > user-defined words > can override built-in operators" ,
300+ "status" : " fail" ,
301+ "message" : " TypeError: RegExp.escape is not a function\n at Forth.escape (<solution>/forth.js:56:43)" ,
302+ "output" : null ,
303+ "test_code" : " forth.evaluate(': + * ;');\n forth.evaluate('3 4 +');\n expect(forth.stack).toEqual([12]);"
304+ },
305+ {
306+ "name" : " Forth > user-defined words > can use different words with the same name" ,
307+ "status" : " fail" ,
308+ "message" : " TypeError: RegExp.escape is not a function\n at Forth.escape (<solution>/forth.js:56:43)" ,
309+ "output" : null ,
310+ "test_code" : " forth.evaluate(': foo 5 ;');\n forth.evaluate(': bar foo ;');\n forth.evaluate(': foo 6 ;');\n forth.evaluate('bar foo');\n expect(forth.stack).toEqual([5, 6]);"
311+ },
312+ {
313+ "name" : " Forth > user-defined words > can define word that uses word with the same name" ,
314+ "status" : " fail" ,
315+ "message" : " TypeError: RegExp.escape is not a function\n at Forth.escape (<solution>/forth.js:56:43)" ,
316+ "output" : null ,
317+ "test_code" : " forth.evaluate(': foo 10 ;');\n forth.evaluate(': foo foo 1 + ;');\n forth.evaluate('foo');\n expect(forth.stack).toEqual([11]);"
318+ },
319+ {
320+ "name" : " Forth > user-defined words > cannot redefine non-negative numbers" ,
321+ "status" : " pass" ,
322+ "message" : " " ,
323+ "output" : null ,
324+ "test_code" : " expect(() => {\n forth.evaluate(': 1 2 ;');\n }).toThrow(new Error('Invalid definition'));"
325+ },
326+ {
327+ "name" : " Forth > user-defined words > cannot redefine negative numbers" ,
328+ "status" : " pass" ,
329+ "message" : " " ,
330+ "output" : null ,
331+ "test_code" : " expect(() => {\n forth.evaluate(': -1 2 ;');\n }).toThrow(new Error('Invalid definition'));"
332+ },
333+ {
334+ "name" : " Forth > user-defined words > errors if executing a non-existent word" ,
335+ "status" : " pass" ,
336+ "message" : " " ,
337+ "output" : null ,
338+ "test_code" : " expect(() => {\n forth.evaluate('foo');\n }).toThrow(new Error('Unknown command'));"
339+ },
340+ {
341+ "name" : " Forth > user-defined words > only defines locally" ,
342+ "status" : " fail" ,
343+ "message" : " TypeError: RegExp.escape is not a function\n at Forth.escape (<solution>/forth.js:56:43)" ,
344+ "output" : null ,
345+ "test_code" : " const first = new Forth();\n const second = new Forth();\n first.evaluate(': + - ;');\n first.evaluate('1 1 +');\n second.evaluate('1 1 +');\n expect(first.stack).toEqual([0]);\n expect(second.stack).toEqual([2]);"
346+ },
347+ {
348+ "name" : " Forth > case-insensitivity > DUP is case-insensitive" ,
349+ "status" : " pass" ,
350+ "message" : " " ,
351+ "output" : null ,
352+ "test_code" : " forth.evaluate('1 DUP Dup dup');\n expect(forth.stack).toEqual([1, 1, 1, 1]);"
353+ },
354+ {
355+ "name" : " Forth > case-insensitivity > DROP is case-insensitive" ,
356+ "status" : " pass" ,
357+ "message" : " " ,
358+ "output" : null ,
359+ "test_code" : " forth.evaluate('1 2 3 4 DROP Drop drop');\n expect(forth.stack).toEqual([1]);"
360+ },
361+ {
362+ "name" : " Forth > case-insensitivity > SWAP is case-insensitive" ,
363+ "status" : " pass" ,
364+ "message" : " " ,
365+ "output" : null ,
366+ "test_code" : " forth.evaluate('1 2 SWAP 3 Swap 4 swap');\n expect(forth.stack).toEqual([2, 3, 4, 1]);"
367+ },
368+ {
369+ "name" : " Forth > case-insensitivity > OVER is case-insensitive" ,
370+ "status" : " pass" ,
371+ "message" : " " ,
372+ "output" : null ,
373+ "test_code" : " forth.evaluate('1 2 OVER Over over');\n expect(forth.stack).toEqual([1, 2, 1, 2, 1]);"
374+ },
375+ {
376+ "name" : " Forth > case-insensitivity > user-defined words are case-insensitive" ,
377+ "status" : " fail" ,
378+ "message" : " TypeError: RegExp.escape is not a function\n at Forth.escape (<solution>/forth.js:56:43)" ,
379+ "output" : null ,
380+ "test_code" : " forth.evaluate(': foo dup ;');\n forth.evaluate('1 FOO Foo foo');\n expect(forth.stack).toEqual([1, 1, 1, 1]);"
381+ },
382+ {
383+ "name" : " Forth > case-insensitivity > definitions are case-insensitive" ,
384+ "status" : " fail" ,
385+ "message" : " TypeError: RegExp.escape is not a function\n at Forth.escape (<solution>/forth.js:56:43)" ,
386+ "output" : null ,
387+ "test_code" : " forth.evaluate(': SWAP DUP Dup dup ;');\n forth.evaluate('1 swap');\n expect(forth.stack).toEqual([1, 1, 1, 1]);"
388+ }
389+ ],
390+ "version" : 3
391+ }
0 commit comments