;;; basic-test.el -- Test Suite for basic.el ;; ;;; Copyright (C) 2008-2014 Kyle W T Sherman ;; ;; Author: Kyle W T Sherman <kylewsherman at gmail dot com> ;; Created: 2008-03-29 ;; Version: 0.1 ;; Keywords: basic compiler interpreter mode ;; ;; This file is not part of GNU Emacs. ;; ;; This is free software; you can redistribute it and/or modify it under the ;; terms of the GNU General Public License as published by the Free Software ;; Foundation; either version 2, or (at your option) any later version. ;; ;; This is distributed in the hope that it will be useful, but WITHOUT ANY ;; WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS ;; FOR A PARTICULAR PURPOSE. See the GNU General Public License for more ;; details. ;; ;; You should have received a copy of the GNU General Public License along ;; with GNU Emacs; see the file COPYING. If not, write to the Free Software ;; Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. ;; ;;; Commentary: ;; ;; Tests `basic.el' functionality. ;; ;;; Installation: ;; ;; Load `basic-test.el': ;; ;; (load "basic-test.el") ;; ;;; Usage: ;; ;; Run tests: ;; ;; (eval-buffer) ;;; Code: ;; basic (require 'basic) ;; assert (defun basic-test (program output &rest input) "Run PROGRAM through the BASIC compiler and compare its output to OUTPUT. \nAny optional INPUT parameters will be used to fill input prompts." (let ((basic-debug-log t)) (save-excursion (with-temp-buffer (insert program) (basic-run-test input)) (set-buffer "*basic-output*") (let ((buffer-str (buffer-substring-no-properties (point-min) (point-max)))) (when (> (length buffer-str) (length output)) (setq output (concat output "\n"))) (assert (string= buffer-str output))) ))) ;; (switch-to-buffer "*basic-debug*") ;; (goto-char (point-min)))) ;;; Unit Tests: Statements ;; remarks (basic-test " 10 REM Remark Test 20 REM `1234567890-= 30 REM ~!@#$%^&*()_+ 40 REM []\\;',./ 50 REM {}|:\"<>? " "") ;; math (basic-test " 10 REM BASIC Test: Math 20 PRINT \"BASIC Test: Math\": PRINT 30 A = -1 * 10 + 6 * 10 40 PRINT A 50 A = 10 * -1 + 6 * 10 60 PRINT A 70 A = -5 + 6 * 20 / 2 - 5 80 PRINT A 90 A = ((-1 + 6) * 20) / (5 - 3) 100 PRINT A " "BASIC Test: Math 50 50 50 50 ") ;; string concatenation (basic-test " 10 REM BASIC Test: Strings 20 PRINT \"BASIC Test: Strings\": PRINT 30 S$ = \"1\" 40 PRINT S$ 50 T$ = \"2\" 60 PRINT S$ + T$ 70 S$ = S$ + T$ + \"3\" 80 PRINT S$ " "BASIC Test: Strings 1 12 123 ") ;; undeclared variables (basic-test " 10 REM BASIC Test: Undeclared Vars 20 PRINT \"BASIC Test: Undeclared Vars\": PRINT 30 A = A + 1 40 PRINT A 50 S$ = S$ + \"1\" 60 PRINT S$ " "BASIC Test: Undeclared Vars 1 1 ") ;; data/read/restore (basic-test " 10 REM BASIC Test: DATA/READ/RESTORE 20 PRINT \"BASIC Test: DATA/READ/RESTORE\": PRINT 30 DATA 1, 2, 3 40 FOR I = 1 TO 3 50 READ A 60 PRINT \"#\" I \" = \" A 70 NEXT 80 FOR I = 4 TO 6 90 READ A 100 PRINT \"#\" I \" = \" A 110 NEXT 120 RESTORE 130 FOR I = 1 TO 6 140 READ A 150 PRINT \"#\" I \" = \" A 160 NEXT 170 DATA 4, 5, 6 " "BASIC Test: DATA/READ/RESTORE #1 = 1 #2 = 2 #3 = 3 #4 = 4 #5 = 5 #6 = 6 #1 = 1 #2 = 2 #3 = 3 #4 = 4 #5 = 5 #6 = 6 ") ;; def (basic-test " 10 REM BASIC Test: DEF 20 PRINT \"BASIC Test: DEF\": PRINT 30 DEF FNA(X)=X+1 40 PRINT STR$(FNA(1)) + \" + \" + STR$(FNA(2)) + \" = \" + STR$(FNA(1)+FNA(2)) 50 DEF FNB(Z)=2*Z+1 60 FOR I = 1 TO 5 70 Z=INT(10+FNB(I)-.5*I) 80 PRINT Z; 90 NEXT I 100 PRINT " "BASIC Test: DEF 2 + 3 = 5 1214151718 ") ;; dim (basic-test " 10 REM BASIC Test: DIM 20 PRINT \"BASIC Test: DIM\": PRINT 30 DIM A(10), B(10,10), C(10,10,10), S$(10), T$(10,10) 100 FOR I = 1 TO 10 110 A(I) = I 120 NEXT 130 FOR I = 6 TO 10 140 PRINT A(I-5) 150 NEXT 160 A = 100 170 PRINT A 180 PRINT A(10) 200 FOR I = 1 TO 10 210 S$(I) = CHR$(64+I) 220 NEXT 230 FOR I = 6 TO 10 240 PRINT S$(I-5) 250 NEXT 260 S$ = \"Z\" 270 PRINT S$ 280 PRINT S$(10) " "BASIC Test: DIM 1 2 3 4 5 100 10 A B C D E Z J ") ;; end (basic-test " 10 REM BASIC Test: END 20 PRINT \"BASIC Test: END\": PRINT 30 END 40 PRINT \"Error\" " "BASIC Test: END ") ;; for/next (basic-test " 10 REM BASIC Test: FOR/NEXT 20 PRINT \"BASIC Test: FOR/NEXT\": PRINT 30 LET C = 0 40 FOR I = 1 TO 100 50 C = C + I 60 NEXT 70 PRINT C 80 FOR I = 0 TO -50 STEP -1 90 C = C + I 100 NEXT I 110 PRINT C " "BASIC Test: FOR/NEXT 5050 3775 ") ;; goto (basic-test " 10 REM BASIC Test: GOTO 20 PRINT \"BASIC Test: GOTO\": PRINT 20 GOTO 70 30 PRINT \"Error\" 40 PRINT \"Test 2\" 50 END 60 PRINT \"Error\" 70 PRINT \"Test 1\" 80 GOTO 40 90 PRINT \"Error\" " "BASIC Test: GOTO Test 1 Test 2") ;; gosub/return (basic-test " 10 REM BASIC Test: GOSUB/RETURN 20 PRINT \"BASIC Test: GOSUB/RETURN\": PRINT 30 PRINT \"Pass 1\" 40 GOSUB 80 50 PRINT \"Pass 2\" 60 GOSUB 140 70 END 80 PRINT \"Test 1\" 90 GOSUB 140 100 RETURN 110 PRINT \"Test 3\" 120 GOSUB 170 130 RETURN 140 PRINT \"Test 2\" 150 GOSUB 110 160 RETURN 170 PRINT \"Test 4\" 180 RETURN 190 END " "BASIC Test: GOSUB/RETURN Pass 1 Test 1 Test 2 Test 3 Test 4 Pass 2 Test 2 Test 3 Test 4 ") ;; input (basic-test " 10 REM BASIC Test: INPUT 20 PRINT \"BASIC Test: INPUT\": PRINT 30 INPUT \"Input number: \", N 40 INPUT \"Input string: \"; S$ 50 PRINT \"Number = \", N, \", String = \", \"'\" + S$ + \"'\" " "BASIC Test: INPUT Input number: 1 Input string: test Number = 1 , String = 'test' " 1 "test") ;; let (basic-test " 10 REM BASIC Test: LET 20 PRINT \"BASIC Test: LET\": PRINT 30 LET A = 1 40 B = 2 50 PRINT \"A = \"; A; \", B = \"; B " "BASIC Test: LET A = 1, B = 2 ") ;; next (see for/next) ;; print (basic-test " 10 REM BASIC Test: PRINT 20 PRINT \"BASIC Test: PRINT\": PRINT 30 LET A = 1 40 LET B = 2 50 LET C$ = \"test\" 60 LET D$ = \"more\" 70 PRINT \"Print test, \"; A; \", \"; B; 80 PRINT \", \"; C$; 90 PRINT \", \"; D$ 100 PRINT \"Print test 2, \" + STR$(A) + \", \" + STR$(B); 110 PRINT \", \"+C$; 120 PRINT \", \"+D$ 130 PRINT \"Tab test:\" 140 PRINT TAB(5); \"*\"; TAB(10); \"*\"; TAB(15); \"*\"; TAB(20); \"*\"; TAB(25); \"*\"; TAB(30); \"*\" 150 PRINT \"123456789012345678901234567890\" " "BASIC Test: PRINT Print test, 1, 2, test, more Print test 2, 1, 2, test, more Tab test: * * * * * * 123456789012345678901234567890 ") ;; read (see data/read/restore) ;; rem (basic-test " 10 REM BASIC Test: REM 20 PRINT \"BASIC Test: REM\": PRINT 30 REM REM Test " "BASIC Test: REM ") ;; restore (see data/read/restore) ;; return (see gosub/return) ;; stop (basic-test " 10 REM BASIC Test: STOP 20 PRINT \"BASIC Test: STOP\": PRINT 30 STOP 40 PRINT \"Error\" " "BASIC Test: STOP ") ;;; Unit Tests: Reserved Words ;; reserved words (basic-test " 10 REM BASIC Test: Reserved Words 20 PRINT \"BASIC Test: Reserved Words\": PRINT 30 FOR I = 0 TO 100 STEP 2 40 IF I MOD 10 <> 0 THEN 70 50 IF (I <= 20 OR I >= 80) AND I <> 100 THEN 70 60 PRINT I 70 NEXT I " "BASIC Test: Reserved Words 30 40 50 60 70 100 ") ;;; Unit Tests: Functions ;; reserved words (basic-test " 10 REM BASIC Test: Functions 20 PRINT \"BASIC Test: Functions\": PRINT 30 PRINT \"ABS(10) = \"; ABS(10) 31 PRINT \"ABS(0) = \"; ABS(0) 32 PRINT \"ABS(-10) = \"; ABS(-10) 40 PRINT \"ASC('A') = \"; ASC(\"A\") 41 PRINT \"ASC('Z') = \"; ASC(\"Z\") 50 PRINT \"ATN(10) = \"; ATN(10) 51 PRINT \"ATN(0) = \"; ATN(0) 52 PRINT \"ATN(-10) = \"; ATN(-10) 60 PRINT \"CHR$(65) = \"; CHR$(65) 61 PRINT \"CHR$(90) = \"; CHR$(90) 70 PRINT \"COS(10) = \"; COS(10) 71 PRINT \"COS(0) = \"; COS(0) 72 PRINT \"COS(-10) = \"; COS(-10) 80 PRINT \"EXP(10) = \"; EXP(10) 81 PRINT \"EXP(0) = \"; EXP(0) 82 PRINT \"EXP(-10) = \"; EXP(-10) 90 PRINT \"INT(10.7) = \"; INT(10.7) 91 PRINT \"INT(0) = \"; INT(0) 92 PRINT \"INT(-10.2) = \"; INT(-10.2) 100 PRINT \"LEFT$('California', 2) = \"; LEFT$(\"California\", 2) 101 PRINT \"LEFT$('Minnesota', 3) = \"; LEFT$(\"Minnesota\", 3) 110 PRINT \"LEN('California') = \"; LEN(\"California\") 111 PRINT \"LEN('Minnesota') = \"; LEN(\"Minnesota\") 120 PRINT \"LOG(10) = \"; LOG(10) 121 PRINT \"LOG(0) = \"; LOG(0) 122 PRINT \"LOG(-10) = \"; LOG(-10) 130 PRINT \"MID$('California', 1) = \"; MID$(\"California\", 1) 130 PRINT \"MID$('California', 2, 3) = \"; MID$(\"California\", 2, 3) 130 PRINT \"MID$('California', 10) = \"; MID$(\"California\", 10) 130 PRINT \"MID$('California', 12) =\"; MID$(\"California\", 12) 131 PRINT \"MID$('Minnesota', 2) = \"; MID$(\"Minnesota\", 2) 131 PRINT \"MID$('Minnesota', 4, 5) = \"; MID$(\"Minnesota\", 4, 5) 131 PRINT \"MID$('Minnesota', 8) = \"; MID$(\"Minnesota\", 8) 131 PRINT \"MID$('Minnesota', 10) =\"; MID$(\"Minnesota\", 10) 140 PRINT \"RND(-10) = \"; RND(-10) 141 PRINT \"RND(0) = \"; RND(0) 150 PRINT \"RIGHT$('California', 2) = \"; RIGHT$(\"California\", 2) 151 PRINT \"RIGHT$('Minnesota', 3) = \"; RIGHT$(\"Minnesota\", 3) 160 PRINT \"SGN(10) = \"; SGN(10) 161 PRINT \"SGN(0) = \"; SGN(0) 162 PRINT \"SGN(-10) = \"; SGN(-10) 170 PRINT \"SIN(10) = \"; SIN(10) 171 PRINT \"SIN(0) = \"; SIN(0) 172 PRINT \"SIN(-10) = \"; SIN(-10) 180 PRINT \"SQR(10) = \"; SQR(10) 181 PRINT \"SQR(0) = \"; SQR(0) 182 PRINT \"SQR(-10) = \"; SQR(-10) 190 PRINT \"STR$(10) = \"; STR$(10) 191 PRINT \"STR$(0) = \"; STR$(0) 192 PRINT \"STR$(-10) = \"; STR$(-10) 200 PRINT \"TAB(1) =\"; TAB(1); \"Tabbed 1\" 201 PRINT \"TAB(5) =\"; TAB(5); \"Tabbed 5\" 202 PRINT \"TAB(10) =\"; TAB(10); \"Tabbed 10\" 203 PRINT \"TAB(20) = \"; TAB(20); \"Tabbed 20\" 210 PRINT \"TAN(10) = \"; TAN(10) 211 PRINT \"TAN(0) = \"; TAN(0) 212 PRINT \"TAN(-10) = \"; TAN(-10) 220 PRINT \"VAL('10') = \"; VAL(\"10\") 221 PRINT \"VAL('0') = \"; VAL(\"0\") 222 PRINT \"VAL('-10') = \"; VAL(\"-10\") " "BASIC Test: Functions ABS(10) = 10 ABS(0) = 0 ABS(-10) = 10 ASC('A') = 65 ASC('Z') = 90 ATN(10) = 1.4711276743037347 ATN(0) = 0.0 ATN(-10) = -1.4711276743037347 CHR$(65) = A CHR$(90) = Z COS(10) = -0.8390715290764524 COS(0) = 1.0 COS(-10) = -0.8390715290764524 EXP(10) = 22026.465794806718 EXP(0) = 1.0 EXP(-10) = 4.5399929762484854e-05 INT(10.7) = 10 INT(0) = 0 INT(-10.2) = -11 LEFT$('California', 2) = Ca LEFT$('Minnesota', 3) = Min LEN('California') = 10 LEN('Minnesota') = 9 LOG(10) = 2.302585092994046 LOG(0) = -1.0e+INF LOG(-10) = 0.0e+NaN MID$('California', 1) = California MID$('California', 2, 3) = ali MID$('California', 10) = a MID$('California', 12) = MID$('Minnesota', 2) = innesota MID$('Minnesota', 4, 5) = nesot MID$('Minnesota', 8) = ta MID$('Minnesota', 10) = RND(-10) = 0.18235988178869306 RND(0) = 0.18235988178869306 RIGHT$('California', 2) = ia RIGHT$('Minnesota', 3) = ota SGN(10) = 1 SGN(0) = 0 SGN(-10) = -1 SIN(10) = -0.5440211108893698 SIN(0) = 0.0 SIN(-10) = 0.5440211108893698 SQR(10) = 3.1622776601683795 SQR(0) = 0.0 SQR(-10) = -0.0e+NaN STR$(10) = 10 STR$(0) = 0 STR$(-10) = -10 TAB(1) = Tabbed 1 TAB(5) = Tabbed 5 TAB(10) =Tabbed 10 TAB(20) = Tabbed 20 TAN(10) = 0.6483608274590866 TAN(0) = 0.0 TAN(-10) = -0.6483608274590866 VAL('10') = 10 VAL('0') = 0 VAL('-10') = -10 ") ;;; Functional Tests ;; test 1 (basic-test " 10 REM BASIC Test 1 20 PRINT \"BASIC Test 1\": PRINT 30 PRINT \"Hello World\" 40 END " "BASIC Test 1 Hello World ") ;; test 2 (basic-test " 10 REM BASIC Test 2 20 PRINT \"BASIC Test 2\": PRINT 30 PRINT \"Summing the values between 1 and 100\" 40 LET total = 0 50 FOR I = 1 TO 100 60 LET total = total + I 70 NEXT I 80 PRINT \"The total of all digits between 1 and 100 is \" total 90 END " "BASIC Test 2 Summing the values between 1 and 100 The total of all digits between 1 and 100 is 5050 ") ;; test 3 (basic-test " 10 REM BASIC Test 3 20 PRINT \"BASIC Test 3\": PRINT 30 INPUT \"What's your age? \"; age 40 PRINT \"You are \" age * 7 \" in dog years!\" 50 END " "BASIC Test 3 What's your age? 35 You are 245 in dog years! " 35) ;; test 4 (basic-test " 10 REM BASIC Test 4 20 PRINT \"BASIC Test 4\": PRINT 30 A = 1: FOR I = A TO A+2 : PRINT I : NEXT 40 END " "BASIC Test 4 1 2 3 ") ;; done (basic-test " 10 REM BASIC Tests Completely Successfully 20 PRINT \"BASIC Tests Completely Successfully\" 30 END " "BASIC Tests Completely Successfully ") ;;; basic-test.el ends here