Initial checkin of Pika from heckimp
This commit is contained in:
179
plug-ins/script-fu/test/tests/TS/atom2string.scm
Normal file
179
plug-ins/script-fu/test/tests/TS/atom2string.scm
Normal file
@ -0,0 +1,179 @@
|
||||
|
||||
; test atom->string function
|
||||
|
||||
; atom->string is not R5RS
|
||||
; Instead, it is TinyScheme specific.
|
||||
|
||||
; atom->string works for atoms of type: number, char, string, byte, symbol.
|
||||
; This is not the usual definition of atom.
|
||||
; Others define atom as anything but list and pair.
|
||||
|
||||
; For atom of type number,
|
||||
; accepts an optional second arg: <base> in [2,8,10,16]
|
||||
; Meaning arithmetic base binary, octal, decimal, hexadecimal.
|
||||
; For atoms of other types, passing a base returns an error.
|
||||
|
||||
|
||||
; The REPL uses an internal C function atom2str()
|
||||
; which is not exposed in the TS language.
|
||||
; It *DOES* represent every object (all atoms) as strings.
|
||||
; But the representation is sometimes a string that can
|
||||
; be turned around and evaluated,
|
||||
; which is not the same string as atom->string produces.
|
||||
|
||||
; !!! Note readstring() internal function
|
||||
; accepts and reduces C "escaped" string representations
|
||||
; i.e. \x07 or \t for tab.
|
||||
; Thus in a test, a double-quoted string enclosing
|
||||
; an escape sequence can be equivalent to a
|
||||
; string for a char atom.
|
||||
|
||||
|
||||
|
||||
; normal tests (without error)
|
||||
|
||||
|
||||
; number
|
||||
|
||||
; number, integer aka fixnum
|
||||
(assert `(string=? (atom->string 1)
|
||||
"1"))
|
||||
|
||||
; number, float aka flonum
|
||||
(assert `(string=? (atom->string 1.0)
|
||||
"1.0"))
|
||||
|
||||
; FIXME the above is known to fail in German:
|
||||
; currently prints 1,0.
|
||||
; To test, set locale to German and retest.
|
||||
|
||||
; There are no other numeric types in TinyScheme.
|
||||
; Refer to discussions of "Lisp numeric tower"
|
||||
|
||||
|
||||
|
||||
; char
|
||||
|
||||
; ASCII, i.e. fits in 8-bit byte
|
||||
|
||||
; char, ASCII, printing and visible
|
||||
(assert `(string=? (atom->string 'a)
|
||||
"a"))
|
||||
|
||||
; char, ASCII, non-printing, whitespace
|
||||
(assert `(string=? (atom->string #\space)
|
||||
" "))
|
||||
|
||||
; Note the char between quotes is a tab char
|
||||
; whose display when viewing this source depends on editor.
|
||||
; Some editors will show just a single white glyph.
|
||||
;
|
||||
; Note also that the SF Console will print "\t"
|
||||
; i.e. this is not a test of the REPL.
|
||||
(assert `(string=? (atom->string #\tab)
|
||||
" "))
|
||||
; Note the char between quotes is a newline char
|
||||
(assert `(string=? (atom->string #\newline)
|
||||
"
|
||||
"))
|
||||
; Note between quotes is an escaped return char,
|
||||
; which readstring() converts to a single char
|
||||
; decimal 13, hex 0d
|
||||
(assert `(string=? (atom->string #\return)
|
||||
"\x0d"))
|
||||
|
||||
; char, ASCII, non-printing control
|
||||
(assert `(string=? (atom->string #\x7)
|
||||
""))
|
||||
; !!! This also passes, because readstring converts
|
||||
; the \x.. escape sequence to a char.
|
||||
(assert `(string=? (atom->string #\x7)
|
||||
"\x07"))
|
||||
; !!! Note the REPL for (atom->string #\x7)
|
||||
; yields "\x07" which is not a sharp char expr wrapped in quotes
|
||||
; but is a string that can be turned around and evaluated
|
||||
; to a string containing one character.
|
||||
|
||||
|
||||
|
||||
; multi-byte UTF-8 encoded chars
|
||||
|
||||
; see more tests in sharp-expr-unichar.scm
|
||||
|
||||
; char, unichar outside the ASCII range
|
||||
(assert `(string=? (atom->string #\λ)
|
||||
"λ"))
|
||||
|
||||
|
||||
|
||||
; symbol
|
||||
(assert `(string=? (atom->string 'pika-message)
|
||||
"pika-message"))
|
||||
; symbol having multibyte char
|
||||
(assert `(string=? (atom->string 'λ)
|
||||
"λ"))
|
||||
|
||||
; string
|
||||
(assert `(string=? (atom->string "foo")
|
||||
"foo"))
|
||||
; string having multibyte char
|
||||
(assert `(string=? (atom->string "λ")
|
||||
"λ"))
|
||||
|
||||
|
||||
; byte
|
||||
|
||||
; Note that readstring() accepts and reduces \x.. notation.
|
||||
|
||||
; Test against a glyph
|
||||
(assert `(string=? (atom->string (integer->byte 31))
|
||||
""))
|
||||
;Test for equivalence to reduced string
|
||||
(assert `(string=? (atom->string (integer->byte 1))
|
||||
"\x01"))
|
||||
(assert `(string=? (atom->string (integer->byte 255))
|
||||
"\xff"))
|
||||
; integer->byte truncates a number that does not fit in 8-bits
|
||||
(assert `(string=? (atom->string (integer->byte 256))
|
||||
"\xff"))
|
||||
|
||||
; Note some TinyScheme C code uses printf ("%lu", var) where var is unsigned char,
|
||||
; and that prints unsigned char in this format.
|
||||
; The above tests are not a test of that code path.
|
||||
|
||||
|
||||
; test optional base arg for numeric atom
|
||||
|
||||
; binary, octal, decimal, hexadecimal
|
||||
(assert `(string=? (atom->string 15 2)
|
||||
"1111"))
|
||||
(assert `(string=? (atom->string 15 8)
|
||||
"17"))
|
||||
(assert `(string=? (atom->string 15 10)
|
||||
"15"))
|
||||
(assert `(string=? (atom->string 15 16)
|
||||
"f"))
|
||||
|
||||
; passing <base> arg for non-numeric atom is error
|
||||
(assert-error `(atom->string (integer->byte 255) 2)
|
||||
"atom->string: bad base:")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; tests of abnormality i.e. error messages
|
||||
|
||||
; atom->string does not work for [#t, nil, closure, port, list, vector, foreign function]
|
||||
|
||||
; foreign function
|
||||
(assert-error `(atom->string pika-message)
|
||||
"atom->string: not an atom:")
|
||||
; nil aka '()
|
||||
(assert-error `(atom->string '() )
|
||||
"atom->string: not an atom:")
|
||||
; #t
|
||||
(assert-error `(atom->string #t )
|
||||
"atom->string: not an atom:")
|
||||
|
||||
; TODO port etc.
|
78
plug-ins/script-fu/test/tests/TS/cond-expand.scm
Normal file
78
plug-ins/script-fu/test/tests/TS/cond-expand.scm
Normal file
@ -0,0 +1,78 @@
|
||||
|
||||
; Test cases for cond-expand in ScriptFu interpreter of PIKA app.
|
||||
|
||||
; cond-expand is SRFI-0
|
||||
; https://www.gnu.org/software/mit-scheme/documentation/stable/mit-scheme-ref/cond_002dexpand-_0028SRFI-0_0029.html
|
||||
|
||||
; ScriptFu cond-expand is defined in the tail of script-fu.init
|
||||
|
||||
; This tests existing ScriptFu code, which is not a full implementation of cond-expand.
|
||||
; ScriptFu omits "else" clause.
|
||||
; PIKA issue #9729 proposes an enhancement that adds else clause to cond-expand, etc.
|
||||
|
||||
|
||||
; *features* is a defined symbol that names features of language
|
||||
(assert '(equal?
|
||||
*features*
|
||||
'(srfi-0 tinyscheme)))
|
||||
|
||||
; srfi-0 is not a defined symbol
|
||||
(assert-error '(srfi-0)
|
||||
"eval: unbound variable:")
|
||||
; Note that *error-hook* erroneously omits tail of error message
|
||||
|
||||
|
||||
|
||||
; simple condition on one supported feature
|
||||
(assert '(equal?
|
||||
(cond-expand (tinyscheme "implements tinyscheme"))
|
||||
"implements tinyscheme"))
|
||||
|
||||
; simple clause on one unsupported feature
|
||||
; Since the condition fails there is no expansion.
|
||||
; Since there is no 'else clause', there is no expansion for false condition.
|
||||
; The cond-expand doc says:
|
||||
; "It either expands into the body of one of its clauses or signals an error during syntactic processing."
|
||||
; Yielding #t is not "signals an error" so is not correct.
|
||||
; This documents what ScriptFu does, until we decide whether and how to fix it.
|
||||
(assert '(equal?
|
||||
(cond-expand (srfi-38 "implements srfi-38"))
|
||||
#t))
|
||||
|
||||
; multiple clauses
|
||||
(assert '(equal?
|
||||
(cond-expand
|
||||
(srfi-38 "implements srfi-38")
|
||||
((not srfi-38) "not implements srfi-38"))
|
||||
"not implements srfi-38"))
|
||||
|
||||
|
||||
; clauses start with 'and', 'or', or 'not'
|
||||
|
||||
; 'not clause'
|
||||
(assert '(equal?
|
||||
(cond-expand ((not srfi-38) "not implements srfi-38"))
|
||||
"not implements srfi-38"))
|
||||
|
||||
; 'and clause' having two logical conditions that are true
|
||||
(assert '(equal?
|
||||
(cond-expand ((and tinyscheme srfi-0) "implements both tinyscheme and srfi-0"))
|
||||
"implements both tinyscheme and srfi-0"))
|
||||
|
||||
; 'or clause' having two logical conditions, one of which is false
|
||||
(assert '(equal?
|
||||
(cond-expand ((or tinyscheme srfi-38) "implements tinyscheme or srfi-38"))
|
||||
"implements tinyscheme or srfi-38"))
|
||||
|
||||
|
||||
; nested logical clauses
|
||||
(assert '(equal?
|
||||
(cond-expand ((or srfi-38 (and tinyscheme srfi-0)) "implements srfi-38 or tinyscheme and srfi-0"))
|
||||
"implements srfi-38 or tinyscheme and srfi-0"))
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
106
plug-ins/script-fu/test/tests/TS/integer2char.scm
Normal file
106
plug-ins/script-fu/test/tests/TS/integer2char.scm
Normal file
@ -0,0 +1,106 @@
|
||||
; test integer->char function
|
||||
|
||||
; Is R5RS, but ScriptFu supports unicode
|
||||
|
||||
; Also test the inverse operation: char->integer
|
||||
|
||||
; TinyScheme does not implement some char functions in MIT Scheme.
|
||||
; For example char->name char->digit
|
||||
|
||||
; TODO test char=? char-upcase
|
||||
|
||||
; General test strategy:
|
||||
; Generate char atom using integer->char.
|
||||
; Convert each such char atom to string.
|
||||
; In all cases where it was possible to create such a string, test length is 1.
|
||||
|
||||
; See also number->string which is similar to (atom->string (integer->char <foo>) <base>)
|
||||
|
||||
|
||||
; integer->char takes only unsigned (positive or zero) codepoints
|
||||
; -1 in twos complement is out of range of UTF-8
|
||||
(assert-error `(integer->char -1)
|
||||
"integer->char: argument 1 must be: non-negative integer")
|
||||
|
||||
|
||||
|
||||
; ASCII NUL character.
|
||||
|
||||
; 0 is a valid codepoint.
|
||||
; But ASCII null terminates the string early, so to speak.
|
||||
|
||||
; Since null byte terminates string early
|
||||
; the repr in the REPL of codepoint 0 is #\
|
||||
|
||||
; re-test
|
||||
; (integer->char 0)
|
||||
; #\
|
||||
|
||||
(assert (= (char->integer (integer->char 0))
|
||||
0))
|
||||
|
||||
; codepoint zero equals its sharp char hex repr
|
||||
(assert (equal? (integer->char 0)
|
||||
#\x0))
|
||||
|
||||
; Converting the atom to string yields an empty string
|
||||
(assert `(string=? (atom->string (integer->char 0))
|
||||
""))
|
||||
|
||||
; You can also represent as escaped hex "x\00"
|
||||
(assert `(string=? "\x00"
|
||||
""))
|
||||
|
||||
; Escaped hex must have more than one hex digit.
|
||||
; Testing framework can't test: (assert-error `(string? "\x0") "Error reading string ")
|
||||
|
||||
; re-test REPL
|
||||
; (null? "\x0")
|
||||
; Error: Error reading string
|
||||
|
||||
|
||||
; the first non-ASCII character (often the euro sign)
|
||||
|
||||
(assert (integer->char 128))
|
||||
|
||||
; converted string is equivalent to a string literal that displays
|
||||
(assert `(string=? (atom->string (integer->char 128))
|
||||
""))
|
||||
|
||||
; first Unicode character outside the 8-bit range
|
||||
|
||||
; evaluates without complaint
|
||||
(assert (integer->char 256))
|
||||
|
||||
(assert (= (char->integer (integer->char 256))
|
||||
256))
|
||||
|
||||
; length of converted string is 1
|
||||
; The length is count of characters, not the count of bytes.
|
||||
(assert `(= (string-length (atom->string (integer->char 256)))
|
||||
1))
|
||||
|
||||
; converted string is equivalent to a string literal that displays
|
||||
(assert `(string=? (atom->string (integer->char 256))
|
||||
"Ā"))
|
||||
|
||||
|
||||
; first Unicode character outside the Basic Multilingual Plane
|
||||
(assert (integer->char 65536))
|
||||
|
||||
(assert (= (char->integer (integer->char 65536))
|
||||
65536))
|
||||
|
||||
(assert `(= (string-length (atom->string (integer->char 65536)))
|
||||
1))
|
||||
|
||||
; The usual glyph in some editors is a wide box with these digits inside:
|
||||
; 010
|
||||
; 000
|
||||
; Other editors may display a small empty box.
|
||||
(assert `(string=? (atom->string (integer->char 65536))
|
||||
"𐀀"))
|
||||
|
||||
; re-test REPL yields a sharp char expr
|
||||
; (integer->char 65536)
|
||||
; #\𐀀
|
55
plug-ins/script-fu/test/tests/TS/no-memory.scm
Normal file
55
plug-ins/script-fu/test/tests/TS/no-memory.scm
Normal file
@ -0,0 +1,55 @@
|
||||
; test memory limits in TS
|
||||
|
||||
; TS is known to be non-robust in face of memory exhaustion.
|
||||
; See Manual.txt which says "TinyScheme is known to misbehave when memory is exhausted."
|
||||
|
||||
; numeric constants from tinyscheme-private.h
|
||||
|
||||
; There is no document (only the source code itself)
|
||||
; explaining the limits.
|
||||
; The limits here are from experiments.
|
||||
|
||||
; These only test the limits.
|
||||
; Methods on the objects (string, vector, etc.) are tested elsewhere.
|
||||
|
||||
; Symbol limits
|
||||
|
||||
; There is no defined limit on count of symbols.
|
||||
; The objlist is a hash table, entries allocated from cells.
|
||||
; The lists in the hash table are practically unlimited.
|
||||
|
||||
|
||||
; String limits
|
||||
|
||||
; Strings are malloced.
|
||||
; Limit on string size derives from OS malloc limits.
|
||||
; No practical limit in ScriptFu.
|
||||
|
||||
; Seems to work
|
||||
; (make-string 260000 #\A)
|
||||
|
||||
|
||||
; Vector limits.
|
||||
|
||||
; A vector is contiguous cells.
|
||||
; TS allocates in segments.
|
||||
|
||||
|
||||
; A vector can be no larger than two segments?
|
||||
|
||||
; succeeds
|
||||
(assert '(make-vector 25000))
|
||||
; REPL shows as #(() () ... ()) i.e. a vector of NIL, not initialized
|
||||
|
||||
; might not crash?
|
||||
(define testVector (make-vector 25001))
|
||||
|
||||
; ????
|
||||
(assert `(vector-fill! ,testVector 1))
|
||||
|
||||
; seems to hang
|
||||
; (assert '(make-vector 50001))
|
||||
|
||||
; seems to crash
|
||||
; (assert '(make-vector 200000))
|
||||
|
233
plug-ins/script-fu/test/tests/TS/sharp-expr-char.scm
Normal file
233
plug-ins/script-fu/test/tests/TS/sharp-expr-char.scm
Normal file
@ -0,0 +1,233 @@
|
||||
; Tests of sharp char expressions in ScriptFu
|
||||
|
||||
; This only tests:
|
||||
; "sharp character" #\<c>
|
||||
; "sharp character hex" #\x<hex digits>
|
||||
; sharp expressions for whitespace
|
||||
; See also:
|
||||
; sharp-expr.scm
|
||||
; sharp-expr-number.scm
|
||||
|
||||
; This also only tests a subset: the ASCII subset.
|
||||
; See also: sharp-expr-unichar.scm
|
||||
|
||||
; #\<char> denotes a character constant where <char> is one character
|
||||
; The one character may be multiple bytes in UTF-8,
|
||||
; but should appear in the display as a single glyph,
|
||||
; but may appear as a box glyph for unichar chars outside ASCII.
|
||||
|
||||
; #\x<x> denotes a character constant where <x> is a sequence of hex digits
|
||||
; See mk_sharp_const()
|
||||
|
||||
; #\space #\newline #\return and #\tab also denote character constants.
|
||||
|
||||
; sharp backslash space "#\ " parses as a token and yields a char atom.
|
||||
; See the code, there is a space here: " tfodxb\\"
|
||||
; See the test below.
|
||||
|
||||
; #U+<x> notation for unichar character constants is not in ScriptFu
|
||||
|
||||
; Any sharp character followed by characters not described above
|
||||
; MAY optionally be a sharp expression when a program
|
||||
; uses the "sharp hook" by defining symbol *sharp-hook* .
|
||||
|
||||
|
||||
|
||||
|
||||
; sharp constants for whitespace
|
||||
|
||||
; codepoints tab 9, newline 10, return 13, space 32 (aka whitespace)
|
||||
; TinyScheme and ScriptFu prints these solitary unichars by a string representation,
|
||||
; but only when they are not in a string!
|
||||
; This subset of codepoints are ignored by the parser as whitespace.
|
||||
; It is common for older scripts to use sharp expression constants for these codepoints.
|
||||
(assert '(equal? (integer->char 9) #\tab))
|
||||
(assert '(equal? (integer->char 10) #\newline))
|
||||
(assert '(equal? (integer->char 13) #\return))
|
||||
(assert '(equal? (integer->char 32) #\space))
|
||||
|
||||
|
||||
|
||||
; sharp constant character
|
||||
|
||||
; Unicode codepoints in range [33, 126]
|
||||
; e.g. the letter A, ASCII 65
|
||||
(assert '(equal? (integer->char 65) #\A))
|
||||
(assert '(char? #\A))
|
||||
(assert '(atom? #\A))
|
||||
|
||||
; Tests of functions using a non-printing, control character ASCII
|
||||
; Codepoint BEL \x7
|
||||
(assert '(equal? (integer->char 7) #\))
|
||||
(assert '(char? #\))
|
||||
(assert '(atom? #\))
|
||||
; string function takes sequence of chars
|
||||
(assert (equal? (string #\) ""))
|
||||
|
||||
; Unicode codepoints [0-8][11-12][14-31]
|
||||
; (less than 32 excepting tab 9, newline 10, return 13)
|
||||
; The "non-printing" characters
|
||||
; e.g. 7, the character that in ancient times rang a bell sound
|
||||
|
||||
; Upstream TinyScheme prints these differently from ScriptFu, as a string repr of the char.
|
||||
; since TinyScheme default compiles with option "USE_ASCII_NAMES"
|
||||
;>(integer->char 7)
|
||||
;#\bel
|
||||
;>(integer->char 127)
|
||||
;#\del
|
||||
|
||||
; ScriptFu prints solitary Unichars
|
||||
; for codepoints below 32 and also 127 differently than upstream TinyScheme.
|
||||
; Except ScriptFu is same as TinyScheme for tab, space, newline, return codepoints.
|
||||
; ScriptFu shows a glyph that is a box with a hex number.
|
||||
; Formerly (before the fixes for this test plan) Scriptfu printed these like TinyScheme,
|
||||
; by a sharp constant hex e.g. #\x1f for 31
|
||||
|
||||
|
||||
; Edge codepoint tests
|
||||
; Tests of edge cases, near a code slightly different
|
||||
|
||||
; Codepoint US Unit Separator, edge case to 32, space
|
||||
(assert '(equal? (integer->char 31) #\))
|
||||
(assert '(equal? #\ #\x1f))
|
||||
|
||||
; codepoint 127 x7f (DEL), edge case to 128
|
||||
(assert '(equal? (integer->char 127) #\x7f))
|
||||
|
||||
|
||||
|
||||
|
||||
; sharp constant hex character
|
||||
|
||||
; Sharp char expr hex denotes char atom
|
||||
; But not the REPL printed representation of characters.
|
||||
|
||||
; is-a char
|
||||
(assert '(char? #\x65))
|
||||
; equals a sharp character: lower case e
|
||||
(assert '(equal? #\x65 #\e))
|
||||
|
||||
; sharp char hex notation accepts a single hex digit
|
||||
(assert '(char? #\x3))
|
||||
; sharp char hex notation accepts two hex digits
|
||||
(assert '(char? #\x33))
|
||||
|
||||
; edge case, max hex that fits in 8-bits
|
||||
(assert '(char? #\xff))
|
||||
|
||||
; sharp car expr hex accepts three digits
|
||||
; when they are leading zeroes
|
||||
(assert '(char? #\x033))
|
||||
|
||||
; Otherwise, three digits not leading zeros
|
||||
; are unicode.
|
||||
|
||||
|
||||
; codepoint x3bb is a valid character (greek lambda)
|
||||
; but is outside ASCII range.
|
||||
; See sharp-expr-unichar.scm
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
; sharp constant hex character: invalid unichar
|
||||
|
||||
; Unicode has a range, but sparsely populated with valid codes.
|
||||
; Unicode is unsigned, range is [0,x10FFF]
|
||||
; Greatest valid codepoint is x10FFFF (to match UTF-16)
|
||||
; Sparsely populated: some codepoints in range are not valid
|
||||
; because they are incorrectly encoded using UTF-8 algorithm.
|
||||
; (This is a paraphrase: please consult the standard.)
|
||||
|
||||
; These tests are not a complete test of UTF-8 compliance !!!
|
||||
|
||||
; Edge case: max valid codepoint
|
||||
(assert (equal? #\x10FFFF #\))
|
||||
|
||||
; Edge case: zero is considered a valid codepoint
|
||||
; !!! Although also a string terminator.
|
||||
(assert '(equal?
|
||||
(integer->char 0)
|
||||
#\x0))
|
||||
|
||||
|
||||
; sharp constants for delimiter characters
|
||||
|
||||
; These test the sharp constant notation for characters space and parens
|
||||
; These are in the ASCII range
|
||||
|
||||
|
||||
; !!! A space char in a sharp constant expr
|
||||
(assert (char? #\ ))
|
||||
; Whose representation is a space character.
|
||||
(assert (string=? (atom->string #\ )
|
||||
" "))
|
||||
|
||||
; !!! A right paren char in a sharp constant expr
|
||||
; Note that backslash captures the first right paren:
|
||||
; the parens do not appear to match.
|
||||
(assert (char? #\)))
|
||||
; Ditto for left paren
|
||||
(assert (char? #\())
|
||||
; !!! But easy for author to confuse the parser
|
||||
; assert-error can't catch syntax errors.
|
||||
; So can only test in the REPL.
|
||||
; > (char? #\)
|
||||
; Error: syntax error: expected right paren, found EOF"
|
||||
|
||||
; #\# is the sharp or pound sign char
|
||||
(assert (char? #\#))
|
||||
(assert (string=? (atom->string #\# )
|
||||
"#"))
|
||||
; #\x is lower case x
|
||||
(assert (char? #\x))
|
||||
(assert (string=? (atom->string #\x )
|
||||
"x"))
|
||||
|
||||
|
||||
|
||||
; see also integer2char.scm
|
||||
|
||||
|
||||
|
||||
; Common misunderstandings or typos
|
||||
|
||||
; #\t is a character, lower case t
|
||||
|
||||
; It is not the denotation for truth.
|
||||
(assert `(not (equal? #\t #t)))
|
||||
|
||||
; It is not the denotation for #\tab.
|
||||
(assert `(not (equal? #\t #\tab)))
|
||||
|
||||
; It is a char
|
||||
(assert `(char? #\t))
|
||||
|
||||
; Its string representation is lower case t character
|
||||
(assert `(string=? (atom->string #\t)
|
||||
"t"))
|
||||
|
||||
|
||||
|
||||
; a number converted to string that is representation in base 16
|
||||
; !!! This is not creating a Unichar.
|
||||
; It is printing the hex representation of decimal 955, without a leading "\x"
|
||||
(assert `(string=? (number->string 955 16)
|
||||
"3bb"))
|
||||
|
||||
|
||||
; Untestable sharp constant hex character
|
||||
|
||||
; Test framework can't test, these cases are syntax errors.
|
||||
; These cases yield "syntax: illegal sharp constant expression" in REPL
|
||||
|
||||
; sharp constant hex having non-hex digit is an error
|
||||
; z is not in [a-f0-9]
|
||||
; > #\xz
|
||||
; Error: syntax: illegal sharp constant expression
|
||||
; Also prints warning "Hex literal has invalid digits" in stderr
|
||||
|
||||
|
||||
|
162
plug-ins/script-fu/test/tests/TS/sharp-expr-unichar.scm
Normal file
162
plug-ins/script-fu/test/tests/TS/sharp-expr-unichar.scm
Normal file
@ -0,0 +1,162 @@
|
||||
; Test cases for sharp char expr for unicode chars outside ASCII range
|
||||
|
||||
; See sharp-expr-char.scm for sharp char expr inside ASCII range.
|
||||
|
||||
; See unichar.scm for tests of unichar without using sharp char expr
|
||||
|
||||
; This file also documents cases that the testing framework can't test
|
||||
; since they are syntax errors
|
||||
; or otherwise throw error in way that testing framework can't catch.
|
||||
; Such cases are documented with pairs of comments in re-test format:
|
||||
; First line starting with "; (" and next line "; <expected REPL display>"
|
||||
|
||||
; This is NOT a test of the REPL: ScriptFu Console.
|
||||
; A REPL displays using obj2str,
|
||||
; or internal atom2str() which this doesn't test.
|
||||
|
||||
; ScriptFu Console (the REPL) displays a "sharp char expression" to represent
|
||||
; all atoms which are characters, e.g. #\a .
|
||||
; A "sharp hex char expression" also
|
||||
; represents a character, e.g. #\x32.
|
||||
; But the REPL does not display that representation.
|
||||
|
||||
|
||||
; conversion from number to character equal sharp char expr unicode
|
||||
(assert `(equal? (integer->char 955) #\λ))
|
||||
; char=? also works
|
||||
(assert `(char=? (integer->char 955) #\λ))
|
||||
|
||||
; a sharp char expr unicode is-a char
|
||||
(assert (char? #\λ))
|
||||
|
||||
; sharp char hex expr is same as sharp char expr
|
||||
(assert (equal? #\x3bb #\λ))
|
||||
; sharp char hex expr is-a char
|
||||
(assert '(char? #\x3bb))
|
||||
|
||||
; Unichar extracted from string equals sharp char expr unicode
|
||||
(assert (equal? (string-ref "λ" 0) #\λ))
|
||||
|
||||
|
||||
|
||||
; Edge cases for sharp char expressions: hex: Unicode
|
||||
|
||||
; see also integer2char.scm
|
||||
; where same cases are tested
|
||||
|
||||
|
||||
; extended ASCII 128-255
|
||||
|
||||
; 128 the euro sign
|
||||
(assert #\x80)
|
||||
; 255
|
||||
(assert #\xff)
|
||||
|
||||
; 159 \xao is non-breaking space, not visible in most editors
|
||||
|
||||
; 256, does not fit in one byte
|
||||
(assert #\x100)
|
||||
|
||||
|
||||
; outside the Basic Multilingual Plane
|
||||
; won't fit in two bytes
|
||||
|
||||
; Least outside: 65536
|
||||
(assert #\x10000)
|
||||
|
||||
; max valid codepoint #\x10ffff
|
||||
(assert #\x10ffff)
|
||||
|
||||
; Any 32-bit value greater than x10ffff yields a syntax error:
|
||||
; syntax: illegal sharp constant expression
|
||||
; and not testable in testing framework
|
||||
|
||||
|
||||
|
||||
; extra tests of sharp char expr in other constructed expressions
|
||||
|
||||
; sharp char expr unicode passed to string function
|
||||
(assert (string=? (string #\λ) "λ"))
|
||||
|
||||
; sharp char expr unicode in a list
|
||||
(assert (equal? (list (string-ref "λ" 0)) '(#\λ)))
|
||||
|
||||
; sharp char expr unicode in vector
|
||||
(assert (equal? (vector (string-ref "λ" 0)) '#(#\λ)))
|
||||
|
||||
; atom->string
|
||||
(assert `(string=? (atom->string #\λ)
|
||||
"λ"))
|
||||
|
||||
|
||||
|
||||
; Quoted unichar
|
||||
|
||||
; quoted unichar is not type char
|
||||
(assert `(not (char? 'λ)))
|
||||
; quoted unichar is type symbol
|
||||
(assert `(symbol? 'λ))
|
||||
|
||||
|
||||
|
||||
|
||||
; unichar tested in REPL
|
||||
|
||||
; What follows are tests that can't be tested by the "testing" framework
|
||||
; but can be tested by the "re-test" framework
|
||||
; Testing framework can't test side effects on display.
|
||||
|
||||
|
||||
|
||||
; re-test display unichar
|
||||
; (display (string-ref "λ" 0))
|
||||
; λ#t
|
||||
|
||||
; re-test
|
||||
; (begin (display "Unicode lambda char: ") (string-ref "λ" 0))
|
||||
; Unicode lambda char: #\λ
|
||||
|
||||
|
||||
|
||||
; Unicode character can be passed to error function and displayed
|
||||
|
||||
; Seems to be flaw in testing framework,
|
||||
; this can't be tested:
|
||||
;(assert-error `(error "Error λ")
|
||||
; "Error: Error λ")
|
||||
|
||||
; re-test
|
||||
; (error "Error λ")
|
||||
; Error: Error: λ
|
||||
|
||||
|
||||
|
||||
; syntax errors in sharp char hex expr
|
||||
|
||||
; Syntax errors are not testable in testing framework.
|
||||
|
||||
|
||||
; exceeding max range of int 32 codepoint
|
||||
; longer than 8 hex digits \xf87654321
|
||||
; > (assert '#\xf87654321
|
||||
|
||||
; re-test
|
||||
; (null? #\xf87654321 )
|
||||
; syntax: illegal sharp constant expression
|
||||
; Also prints warning "Hex literal larger than 32-bit" to stderr
|
||||
|
||||
|
||||
; A codepoint that fits in 32 bits but invalid UTF-8 encoding
|
||||
|
||||
; re-test
|
||||
; (null? '#\xd800)
|
||||
; syntax: illegal sharp constant expression
|
||||
; Also prints warning "Failed make character from invalid codepoint." to stderr
|
||||
|
||||
|
||||
; Edge error case: first invalid codepoint greater than max valid
|
||||
|
||||
; re-test
|
||||
; (null? '#\x110000)
|
||||
; syntax: illegal sharp constant expression
|
||||
; Also prints warning "Failed make character from invalid codepoint." to stderr
|
85
plug-ins/script-fu/test/tests/TS/sharp-expr.scm
Normal file
85
plug-ins/script-fu/test/tests/TS/sharp-expr.scm
Normal file
@ -0,0 +1,85 @@
|
||||
; Tests of sharp expressions in ScriptFu
|
||||
|
||||
; This only tests:
|
||||
; miscellaneous sharp expressions
|
||||
; See also:
|
||||
; sharp-expr-char.scm
|
||||
; sharp-expr-number.scm
|
||||
|
||||
; Some "sharp expressions" e.g. #t and #f might not be explicitly tested,
|
||||
; but tested "driveby" by other tests.
|
||||
|
||||
; Terminology:
|
||||
; The code says "sharp constant expression".
|
||||
; A "sharp expression" is text in the language that denotes a "sharp constant."
|
||||
; A constant is an atom of various types: char, byte, number.
|
||||
; The expression is distinct from the thing it denotes.
|
||||
|
||||
; A "sharp expression" is *recognized* by the interpreter.
|
||||
; But also *printed* by the interpreter REPL.
|
||||
; Mostly these are tests of recognition.
|
||||
; The testing framework cannot test the REPL.
|
||||
|
||||
; See scheme.c, the token() function, about line 2000
|
||||
; and the mk_sharp_constant() function, for sharp character constant
|
||||
|
||||
; #( token denotes start of a vector
|
||||
|
||||
; #! token denotes start of a comment terminated by newline
|
||||
; aka shebang or hashbang, a notation that OS shells read
|
||||
|
||||
; #t denotes true
|
||||
; #f denotes false
|
||||
|
||||
; #odxb<x> denotes a numeric constant in octal, decimal, hex, binary base
|
||||
; where <x> are digits of that base
|
||||
|
||||
; #\<char> denotes a character constant where <char> is one character
|
||||
; The one character may be multiple bytes in UTF-8,
|
||||
; but should appear in the display as a single glyph,
|
||||
; but may appear as a box glyph for unichar chars outside ASCII.
|
||||
|
||||
; #\x<x> denotes a character constant where <x> is a sequence of hex digits
|
||||
; See mk_sharp_const()
|
||||
|
||||
; #\space #\newline #\return and #\tab also denote character constants.
|
||||
|
||||
; Note: sharp backslash followed by space/blank parses as a token,
|
||||
|
||||
; #U+<x> notation for unichar character constants is not in ScriptFu
|
||||
|
||||
; Any sharp character followed by characters not described above
|
||||
; MAY optionally be a sharp expression when a program
|
||||
; uses the "sharp hook" by defining symbol *sharp-hook* .
|
||||
|
||||
|
||||
; block quote parses
|
||||
; Seems only testable in REPL?
|
||||
; Note there is a newline after foo
|
||||
;(assert '#! foo
|
||||
; )
|
||||
; but is not testable by the framework
|
||||
|
||||
; #t denotes truth
|
||||
(assert #t)
|
||||
|
||||
; #t denotes an atom
|
||||
(assert (atom? #t))
|
||||
|
||||
; #t is type boolean
|
||||
(assert (boolean? #t))
|
||||
; #t is neither type number or symbol
|
||||
(assert (not (number? #t)))
|
||||
(assert (not (symbol? #t)))
|
||||
|
||||
; #t denotes constant, and constant means immutable
|
||||
; You cannot redefine #t
|
||||
(assert-error `(define #t 1)
|
||||
"variable is not a symbol")
|
||||
; You cannot set #t
|
||||
(assert-error `(set! #t 1)
|
||||
"set!: unbound variable:")
|
||||
; error-hook omits suffix: #t
|
||||
|
||||
; There is no predicate immutable? in Scheme language?
|
||||
|
56
plug-ins/script-fu/test/tests/TS/string-port.scm
Normal file
56
plug-ins/script-fu/test/tests/TS/string-port.scm
Normal file
@ -0,0 +1,56 @@
|
||||
; Test cases for string ports
|
||||
|
||||
; a string port is-a port (having read and write methods).
|
||||
; a string port stores its contents in memory (unlike device ports).
|
||||
; A read returns contents previously written.
|
||||
; A string port is practically infinite.
|
||||
|
||||
; a string port is like a string
|
||||
; a sequence of writes are like a sequence of appends to a string
|
||||
|
||||
|
||||
; Note that each assert is in its own environment,
|
||||
; so we can't define a global port outside????
|
||||
; Why shouldn't this work?
|
||||
; (define aStringPort (open-output-string))
|
||||
; (assert `(port? aStringPort))
|
||||
|
||||
|
||||
; open-output-string yields a port
|
||||
(assert '(port? (open-output-string)))
|
||||
|
||||
; string read from port equals string written to port
|
||||
; !!! with escaped double quote
|
||||
(assert '(string=?
|
||||
(let* ((aStringPort (open-output-string)))
|
||||
(write "foo" aStringPort)
|
||||
(get-output-string aStringPort))
|
||||
"\"foo\""))
|
||||
|
||||
; string read from port equals string repr of symbol written to port
|
||||
; !!! without escaped double quote
|
||||
(assert '(string=?
|
||||
(let* ((aStringPort (open-output-string)))
|
||||
; !!! 'foo is-a symbol whose repr is three characters: foo
|
||||
; write to a port writes the repr
|
||||
(write 'foo aStringPort)
|
||||
(get-output-string aStringPort))
|
||||
(symbol->string 'foo)))
|
||||
|
||||
; What is read equals the string written.
|
||||
; For edge case: writing more than 256 characters in two tranches
|
||||
; where second write crosses end boundary of 256 char buffer.
|
||||
|
||||
; issue #9495
|
||||
; Failing
|
||||
;(assert '(string=?
|
||||
; (let* ((aStringPort (open-output-string)))
|
||||
; (write (string->symbol (make-string 250 #\A)) aStringPort)
|
||||
; (write (string->symbol (make-string 7 #\B)) aStringPort)
|
||||
; (get-output-string aStringPort))
|
||||
; (string-append
|
||||
; (make-string 250 #\A)
|
||||
; (make-string 7 #\B))))
|
||||
|
||||
|
||||
|
52
plug-ins/script-fu/test/tests/TS/testing.scm
Normal file
52
plug-ins/script-fu/test/tests/TS/testing.scm
Normal file
@ -0,0 +1,52 @@
|
||||
; test the testing framework
|
||||
|
||||
; assert stmt
|
||||
|
||||
|
||||
; a result that is #t passes
|
||||
(assert #t)
|
||||
|
||||
; other truthy results pass
|
||||
(assert 1)
|
||||
|
||||
; 0 is truthy and passes
|
||||
(assert 0)
|
||||
|
||||
; If you really want to assert that exactly #t is the result,
|
||||
; you should eval a topmost predicate that yields only #t or #f
|
||||
; For example, where eq? is equality of pointers:
|
||||
(assert '(not (eq? 0 #t)))
|
||||
|
||||
; a symbol defined outside an assert is visible
|
||||
; when you backquote and unquote it.
|
||||
(define aTrue #t)
|
||||
(assert `,aTrue)
|
||||
|
||||
; Here
|
||||
; backquote passes the following expression as data without evaluating it
|
||||
; singlequote makes a list literal instead of a function call
|
||||
; unquote i.e. comma evaluates the following symbol before backquote passes expression as data
|
||||
(assert `(car '(,aTrue)))
|
||||
|
||||
|
||||
|
||||
; assert-error statment
|
||||
|
||||
; assert-error tests for error messages
|
||||
; assert-error omits the "Error: " prefix printed by the REPL
|
||||
|
||||
; case: Error1 called with pointer to errant atom
|
||||
; symbol aFalse is not bound
|
||||
(assert-error 'aFalse
|
||||
"eval: unbound variable:")
|
||||
|
||||
; assert-error currently omits the suffix <repr of errant code>
|
||||
; printed by the usual error mechanism.
|
||||
; (Since I think error hook mechanism is broken.)
|
||||
|
||||
; case: Error0 called with null pointer
|
||||
; numeric literal 1 is not a function
|
||||
(assert-error '(1)
|
||||
"illegal function")
|
||||
|
||||
|
36
plug-ins/script-fu/test/tests/TS/tinyscheme.scm
Normal file
36
plug-ins/script-fu/test/tests/TS/tinyscheme.scm
Normal file
@ -0,0 +1,36 @@
|
||||
; Complete test of TinyScheme
|
||||
|
||||
; This does NOT KNOW the directory organization of the test files in repo.
|
||||
|
||||
; When you add a test file, also add it to meson.build,
|
||||
; which DOES KNOW the dirs of the repo, but flattens into /test.
|
||||
|
||||
; Name clash must be avoided on the leaf filenames.
|
||||
|
||||
|
||||
; test the testing framework itself
|
||||
(testing:load-test "testing.scm")
|
||||
|
||||
(testing:load-test "cond-expand.scm")
|
||||
(testing:load-test "atom2string.scm")
|
||||
(testing:load-test "integer2char.scm")
|
||||
|
||||
(testing:load-test "string-port.scm")
|
||||
|
||||
(testing:load-test "sharp-expr.scm")
|
||||
(testing:load-test "sharp-expr-char.scm")
|
||||
(testing:load-test "sharp-expr-unichar.scm")
|
||||
|
||||
; test unichar without using sharp char expr
|
||||
(testing:load-test "unichar.scm")
|
||||
|
||||
(testing:load-test "vector.scm")
|
||||
|
||||
(testing:load-test "no-memory.scm")
|
||||
|
||||
; report the result
|
||||
(testing:report)
|
||||
|
||||
; yield the session result
|
||||
(testing:all-passed?)
|
||||
|
58
plug-ins/script-fu/test/tests/TS/unichar.scm
Normal file
58
plug-ins/script-fu/test/tests/TS/unichar.scm
Normal file
@ -0,0 +1,58 @@
|
||||
; Test cases for unicode chars outside ASCII range
|
||||
|
||||
; !!! These tests don't use sharp char expr, but the chars themselves.
|
||||
; See sharp-expr-unichar.scm for sharp char expr denoting unichars
|
||||
; outside ASCII range.
|
||||
|
||||
; History: we avoid sharp char expr for unicode here
|
||||
; because of bug #9660.
|
||||
; Loosely speaking, ScriptFu was handling unichars,
|
||||
; but not sharp char expr for them.
|
||||
|
||||
; Most test cases are for atoms that are type "char",
|
||||
; meaning a component of a string.
|
||||
; ScriptFu implementation uses a C type: gunichar,
|
||||
; which holds a UTF-8 encoding of any Unicode code point.)
|
||||
; A unichar is as many as four bytes, not always one byte.
|
||||
|
||||
; This is NOT a test of the REPL: ScriptFu Console.
|
||||
; A REPL displays using obj2str,
|
||||
; or internal atom2str() which this doesn't test.
|
||||
|
||||
; ScriptFu Console (the REPL) displays a "sharp char expression" to represent
|
||||
; all atoms of type char, e.g. #\a .
|
||||
; A "sharp hex char expression" also
|
||||
; represents a character, e.g. #\x32.
|
||||
; But the REPL does not display that representation.
|
||||
|
||||
|
||||
; conversion from number to character equal sharp char
|
||||
(assert `(equal? (integer->char 955)
|
||||
(string-ref "λ" 0)))
|
||||
|
||||
|
||||
; Unichar itself (a wide character) can be in the script
|
||||
; but is unbound
|
||||
(assert-error `(eval λ) "eval: unbound variable:")
|
||||
; Note the error message is currently omitting the errant symbol
|
||||
|
||||
|
||||
; Unichar in a string
|
||||
(assert (string=? (string (string-ref "λ" 0)) "λ"))
|
||||
|
||||
|
||||
; Omitted: a test of REPL
|
||||
; display unichar
|
||||
; > (display (string-ref "λ" 0))
|
||||
; λ#t
|
||||
|
||||
|
||||
; Quoted unichar
|
||||
; These test that the script can contain unichars
|
||||
; versus test that a script can process unichars.
|
||||
|
||||
; quoted unichar is not type char
|
||||
(assert `(not (char? 'λ)))
|
||||
|
||||
; quoted unichar is type symbol
|
||||
(assert (symbol? 'λ))
|
85
plug-ins/script-fu/test/tests/TS/vector.scm
Normal file
85
plug-ins/script-fu/test/tests/TS/vector.scm
Normal file
@ -0,0 +1,85 @@
|
||||
; test vector methods of TS
|
||||
|
||||
|
||||
|
||||
; make-vector
|
||||
|
||||
; make-vector succeeds
|
||||
(assert '(make-vector 25))
|
||||
; Note vector is anonymous and will be garbage collected
|
||||
|
||||
; make-vector of size 0 succeeds
|
||||
(assert '(make-vector 0))
|
||||
|
||||
(define testVector (make-vector 25))
|
||||
|
||||
; make-vector yields a vector
|
||||
(assert `(vector? ,testVector))
|
||||
|
||||
; make-vector yields a vector of given length
|
||||
(assert `(= (vector-length ,testVector)
|
||||
25))
|
||||
|
||||
; make-vector initializes each element to empty list
|
||||
(assert `(equal?
|
||||
(vector-ref ,testVector 0)
|
||||
'()))
|
||||
|
||||
|
||||
; other vector construction methods
|
||||
|
||||
(assert '(equal?
|
||||
(vector 'a 'b 'c)
|
||||
#(a b c)))
|
||||
|
||||
(assert '(equal?
|
||||
(list->vector '(dididit dah))
|
||||
#(dididit dah)))
|
||||
|
||||
|
||||
; fill
|
||||
|
||||
; fill succeeds
|
||||
(assert `(vector-fill! ,testVector 99))
|
||||
|
||||
; fill effective
|
||||
(assert `(=
|
||||
(vector-ref ,testVector 0)
|
||||
99))
|
||||
|
||||
|
||||
; referencing out of bounds
|
||||
|
||||
; past end fails
|
||||
(assert-error `(vector-ref ,testVector 25)
|
||||
"vector-ref: out of bounds:")
|
||||
; error msg omits repr of atom
|
||||
|
||||
; negative index fails
|
||||
(assert-error `(vector-ref ,testVector -1)
|
||||
"vector-ref: argument 2 must be: non-negative integer")
|
||||
|
||||
|
||||
|
||||
|
||||
; undefined vector ops in TS
|
||||
|
||||
; make-initialized-vector
|
||||
(assert-error '(equal?
|
||||
(make-initialized-vector 5 (lambda (x) (* x x)))
|
||||
#(0 1 4 9 16))
|
||||
"eval: unbound variable:")
|
||||
; error msg omits prefix "Error: " and suffix "make-initialized-vector"
|
||||
|
||||
; vector-copy
|
||||
; equals the original
|
||||
(assert-error
|
||||
`(equal?
|
||||
(vector-copy ,testVector)
|
||||
,testVector)
|
||||
"eval: unbound variable:")
|
||||
|
||||
|
||||
|
||||
|
||||
|
Reference in New Issue
Block a user