| | 1 | /* |
| | 2 | * built-in function tests |
| | 3 | */ |
| | 4 | |
| | 5 | #include "t3.h" |
| | 6 | #include "tads.h" |
| | 7 | |
| | 8 | obj1: object |
| | 9 | prop1 = "Hello" |
| | 10 | ; |
| | 11 | |
| | 12 | _say_embed(str) { tadsSay(str); } |
| | 13 | |
| | 14 | |
| | 15 | _main(args) |
| | 16 | { |
| | 17 | try |
| | 18 | { |
| | 19 | main(); |
| | 20 | } |
| | 21 | catch (RuntimeError rte) |
| | 22 | { |
| | 23 | "\n<<rte.display>>\n"; |
| | 24 | } |
| | 25 | } |
| | 26 | |
| | 27 | function main() |
| | 28 | { |
| | 29 | t3SetSay(_say_embed); |
| | 30 | tadsSay('built-in function tests\n'); |
| | 31 | |
| | 32 | local str = 'abcdefghijklmnopqrstuvwxyz'; |
| | 33 | tadsSay('str.length() = ' + str.length() + '\n'); |
| | 34 | tadsSay('str.substr(5) = [' + str.substr(5) + ']\n'); |
| | 35 | tadsSay('str.substr(7, 11) = [' + str.substr(7, 11) + ']\n'); |
| | 36 | tadsSay('str.substr(7, 30) = [' + str.substr(7, 30) + ']\n'); |
| | 37 | tadsSay('str.substr(30) = [' + str.substr(30) + ']\n'); |
| | 38 | tadsSay('str.substr(30, 8) = [' + str.substr(30, 8) + ']\n'); |
| | 39 | |
| | 40 | tadsSay('\b'); |
| | 41 | tadsSay('str.startsWith(a) = ' |
| | 42 | + (str.startsWith('a') ? 'yes' : 'no') + '\n'); |
| | 43 | tadsSay('str.startsWith(b) = ' |
| | 44 | + (str.startsWith('b') ? 'yes' : 'no') + '\n'); |
| | 45 | tadsSay('str.startsWith(abc) = ' |
| | 46 | + (str.startsWith('abc') ? 'yes' : 'no') + '\n'); |
| | 47 | tadsSay('str.startsWith(abcdef) = ' |
| | 48 | + (str.startsWith('abcdef') ? 'yes' : 'no') + '\n'); |
| | 49 | tadsSay('str.startsWith(bc) = ' |
| | 50 | + (str.startsWith('bc') ? 'yes' : 'no') + '\n'); |
| | 51 | tadsSay('str.startsWith(abcefg) = ' |
| | 52 | + (str.startsWith('abcefg') ? 'yes' : 'no') + '\n'); |
| | 53 | |
| | 54 | tadsSay('\b'); |
| | 55 | tadsSay('str.endWith(z) = ' |
| | 56 | + (str.endsWith('z') ? 'yes' : 'no') + '\n'); |
| | 57 | tadsSay('str.endWith(y) = ' |
| | 58 | + (str.endsWith('y') ? 'yes' : 'no') + '\n'); |
| | 59 | tadsSay('str.endsWith(xyz) = ' |
| | 60 | + (str.endsWith('xyz') ? 'yes' : 'no') + '\n'); |
| | 61 | tadsSay('str.endsWith(tuvwxyz) = ' |
| | 62 | + (str.endsWith('tuvwxyz') ? 'yes' : 'no') + '\n'); |
| | 63 | tadsSay('str.endsWith(xy) = ' |
| | 64 | + (str.endsWith('xy') ? 'yes' : 'no') + '\n'); |
| | 65 | tadsSay('str.endsWith(tuvxyz) = ' |
| | 66 | + (str.endsWith('tuvxyz') ? 'yes' : 'no') + '\n'); |
| | 67 | |
| | 68 | tadsSay('\b'); |
| | 69 | local lst = ['one', 'two', 'three', 'four', 'five', |
| | 70 | 'six', 'seven', 'eight', 'nine', 'ten']; |
| | 71 | tadsSay('lst.length() = ' + lst.length() + '\n'); |
| | 72 | |
| | 73 | tadsSay('lst.sublist(5) = '); sayList(lst.sublist(5)); tadsSay('\n'); |
| | 74 | tadsSay('lst.sublist(5, 3) = '); sayList(lst.sublist(5, 3)); tadsSay('\n'); |
| | 75 | tadsSay('lst.sublist(5, 15) = '); sayList(lst.sublist(5, 15)); tadsSay('\n'); |
| | 76 | tadsSay('lst.sublist(15) = '); sayList(lst.sublist(15)); tadsSay('\n'); |
| | 77 | tadsSay('lst.sublist(15, 3) = '); sayList(lst.sublist(15, 3)); tadsSay('\n'); |
| | 78 | |
| | 79 | tadsSay('lst.car() = '); tadsSay(lst.car()); tadsSay('\n'); |
| | 80 | tadsSay('lst.cdr() = '); sayList(lst.cdr()); tadsSay('\n'); |
| | 81 | tadsSay('[].car() = nil? ' + ([].car() == nil ? 'yes' : 'no') + '\n'); |
| | 82 | tadsSay('[].cdr() = nil? ' + ([].cdr() == nil ? 'yes' : 'no') + '\n'); |
| | 83 | |
| | 84 | "lst - 'three' -> <<sayList(lst - 'three')>>\n"; |
| | 85 | "lst - ['four', 'eight'] -> <<sayList(lst - ['four', 'eight'])>>\n"; |
| | 86 | "lst - ['four', '123', 'nine'] -> |
| | 87 | <<sayList(lst - ['four', '123', 'nine'])>>\n"; |
| | 88 | |
| | 89 | local lst2 = ['one', [2, 3], 'four']; |
| | 90 | "lst2 == ['one', [2, 3], 'four']: |
| | 91 | <<bool2str(lst2 == ['one', [2, 3], 'four'])>>\n"; |
| | 92 | "lst2 == ['one', 2, 3, 'four']: |
| | 93 | <<bool2str(lst2 == ['one', 2, 3, 'four'])>>\n"; |
| | 94 | "lst2 == ['one', [3, 4], 'four']: |
| | 95 | <<bool2str(lst2 == ['one', [3, 4], 'four'])>>\n"; |
| | 96 | |
| | 97 | "\bdataType() tests\n"; |
| | 98 | lst[1] = 'ONE'; |
| | 99 | str += '1234567890'; |
| | 100 | "dataType(nil) = <<dataType(nil)>>\n"; |
| | 101 | "dataType(true) = <<dataType(true)>>\n"; |
| | 102 | "dataType(obj1) = <<dataType(obj1)>>\n"; |
| | 103 | "dataType(&prop1) = <<dataType(&prop1)>>\n"; |
| | 104 | "dataType(123) = <<dataType(123)>>\n"; |
| | 105 | "dataType('hello') = <<dataType('hello')>>\n"; |
| | 106 | "dataType('<<str>>' /*dynamic string*/) = <<dataType(str)>>\n"; |
| | 107 | "dataType([1, 2, 3]) = <<dataType([1, 2, 3])>>\n"; |
| | 108 | "dataType(<<sayList(lst)>> /*dynamic list*/) = <<dataType(lst)>>\n"; |
| | 109 | "dataType(_main) = <<dataType(_main)>>\n"; |
| | 110 | |
| | 111 | "\bvarargs tests\n"; |
| | 112 | "varfunc(1): << varfunc(1) >>\n"; |
| | 113 | "varfunc(1, 2, 3): << varfunc(1, 2, 3) >>\n"; |
| | 114 | |
| | 115 | local str2 = 'This is a TEST of UPPER and lower. 123;!@#$'; |
| | 116 | "\bupper/lower test\n"; |
| | 117 | "upper('<<str2>>') = '<<str2.toUpper()>>'\n"; |
| | 118 | "lower('<<str2>>') = '<<str2.toLower()>>'\n"; |
| | 119 | |
| | 120 | "\btoString test\n"; |
| | 121 | "toString(123) = <<toString(123)>>\n"; |
| | 122 | "toString(123, 8) = <<toString(123, 8)>>\n"; |
| | 123 | "toString(123, 16) = <<toString(123, 16)>>\n"; |
| | 124 | "toString(true) = <<toString(true)>>\n"; |
| | 125 | "toString(nil) = <<toString(nil)>>\n"; |
| | 126 | |
| | 127 | "toInteger test\n"; |
| | 128 | "toInteger('nil') = <<bool2str(toInteger('nil'))>>\n"; |
| | 129 | "toInteger('true') = <<bool2str(toInteger('true'))>>\n"; |
| | 130 | "toInteger('123') = <<toInteger('123')>>\n"; |
| | 131 | "toInteger('ffff', 16) = <<toInteger('ffff', 16)>>\n"; |
| | 132 | "toInteger('123', 8) = <<toInteger('123', 8)>>\n"; |
| | 133 | |
| | 134 | #if 0 |
| | 135 | // omit these from the automated tests - the times vary, so we can't |
| | 136 | // mechanically compare the results (we need some kind of fixed-time |
| | 137 | // mode that always returns the same value to test getTime mechanically) |
| | 138 | // |
| | 139 | "getTime() test\n"; |
| | 140 | "getTime() = <<sayList(getTime())>>\n"; |
| | 141 | "getTime(1) = <<sayList(getTime(1))>>\n"; |
| | 142 | "getTime(2) = <<getTime(2)>>\n"; |
| | 143 | #endif |
| | 144 | |
| | 145 | "find() test\n"; |
| | 146 | "'<<str>>'.find('') = <<str.find('')>>\n"; |
| | 147 | "'<<str>>'.find('abcdef') = <<str.find('abcdef')>>\n"; |
| | 148 | "'<<str>>'.find('xyz') = <<str.find('xyz')>>\n"; |
| | 149 | "'<<str>>'.find('1234567890') = <<str.find('1234567890')>>\n"; |
| | 150 | "'<<str>>'.find('xxx') = <<str.find('xxx')>>\n"; |
| | 151 | "<<sayList(lst)>>.indexOf('one') = <<lst.indexOf('one')>>\n"; |
| | 152 | "<<sayList(lst)>>.indexOf('ONE') = <<lst.indexOf('ONE')>>\n"; |
| | 153 | "<<sayList(lst)>>.indexOf('two') = <<lst.indexOf('two')>>\n"; |
| | 154 | "<<sayList(lst)>>.indexOf('ten') = <<lst.indexOf('ten')>>\n"; |
| | 155 | "<<sayList(lst)>>.indexOf('222') = <<lst.indexOf('222')>>\n"; |
| | 156 | "[1, [2, 3], 4].indexOf([2, 3]) = <<[1, [2, 3], 4].indexOf([2, 3])>>\n"; |
| | 157 | "[1, [2, 3], 4].indexOf([3, 4]) = <<[1, [2, 3], 4].indexOf([3, 4])>>\n"; |
| | 158 | |
| | 159 | local lst3 = ['one', 'two', 'three', 'four', 'five']; |
| | 160 | local lst4 = ['four', 'five', 'six', 'seven']; |
| | 161 | "[1, 2, 3, 4].intersect([3, 4, 5]) = |
| | 162 | <<sayList([1, 2, 3, 4].intersect([3, 4, 5]))>>\n"; |
| | 163 | "lst3.intersect(lst4) = <<sayList(lst3.intersect(lst4))>>\n"; |
| | 164 | "lst3.intersect(['three', 'six']) = |
| | 165 | <<sayList(lst3.intersect(['three', 'six']))>>\n"; |
| | 166 | "['two', 'four', 'eight'].intersect(lst3) = |
| | 167 | <<sayList(['two', 'four', 'eight'].intersect(lst3))>>\n"; |
| | 168 | "lst3.intersect(['six', 'seven', 'eight', 'nine', 'ten']) = |
| | 169 | <<sayList(lst3.intersect(['six', 'seven', 'eight', 'nine', 'ten'])) |
| | 170 | >>\n"; |
| | 171 | |
| | 172 | regex_tests(); |
| | 173 | } |
| | 174 | |
| | 175 | varfunc(...) |
| | 176 | { |
| | 177 | for (local i = 1 ; i <= argcount ; ++i) |
| | 178 | { |
| | 179 | tadsSay(getArg(i)); |
| | 180 | if (i < argcount) |
| | 181 | ", "; |
| | 182 | } |
| | 183 | } |
| | 184 | |
| | 185 | bool2str(x) |
| | 186 | { |
| | 187 | return x ? 'true' : 'nil'; |
| | 188 | } |
| | 189 | |
| | 190 | function sayList(lst) |
| | 191 | { |
| | 192 | if (lst == nil) |
| | 193 | { |
| | 194 | "nil"; |
| | 195 | return; |
| | 196 | } |
| | 197 | |
| | 198 | tadsSay('['); |
| | 199 | for (local i = 1, local cnt = lst.length() ; i <= cnt ; ++i) |
| | 200 | { |
| | 201 | tadsSay(lst[i]); |
| | 202 | if (i < cnt) |
| | 203 | tadsSay(', '); |
| | 204 | } |
| | 205 | tadsSay(']'); |
| | 206 | } |
| | 207 | |
| | 208 | export RuntimeError; |
| | 209 | |
| | 210 | class RuntimeError: object |
| | 211 | construct(errno, ...) { errno_ = errno; } |
| | 212 | display = "Runtime Error: <<errno_>>" |
| | 213 | errno_ = 0 |
| | 214 | ; |
| | 215 | |
| | 216 | regex_tests() |
| | 217 | { |
| | 218 | "\bRegular Expression Tests\n"; |
| | 219 | |
| | 220 | local pat1 = '%<test%>'; |
| | 221 | local pat2 = '([a-z]+) *%1'; |
| | 222 | local pat3 = '([a-z]+)([0-9]+)'; |
| | 223 | "pat1 = '<<pat1.htmlify()>>'\npat2 = '<<pat2>>'\npat3 = '<<pat3>>'\n"; |
| | 224 | |
| | 225 | "search(pat1, 'this is a test') = |
| | 226 | <<sayList(rexSearch(pat1, 'this is a test'))>>\n"; |
| | 227 | "search(pat1, 'testing some tests') = |
| | 228 | <<sayList(rexSearch(pat1, 'testing some tests'))>>\n"; |
| | 229 | "search(pat1, 'testing a test run') = |
| | 230 | <<sayList(rexSearch(pat1, 'testing a test run'))>>\n"; |
| | 231 | |
| | 232 | "search(pat2, 'abc def ghi') = |
| | 233 | <<sayList(rexSearch(pat2, 'abc def ghi'))>>\n"; |
| | 234 | "search(pat2, 'abc def def ghi') = |
| | 235 | <<sayList(rexSearch(pat2, 'abc def def ghi'))>>\n"; |
| | 236 | "group(1) = <<sayList(rexGroup(1))>>\n"; |
| | 237 | |
| | 238 | "match(pat1, 'this is a test') = <<rexMatch(pat1, 'this is a test')>>\n"; |
| | 239 | "match(pat1, 'test a bit') = |
| | 240 | <<rexMatch(pat1, 'test a bit')>>\n"; |
| | 241 | "match(pat1, 'testing one two three') = |
| | 242 | <<rexMatch(pat1, 'testing one two three')>>\n"; |
| | 243 | |
| | 244 | "match(pat3, 'abcdef123!!!') = <<rexMatch(pat3, 'abcdef123!!!')>>\n"; |
| | 245 | "group(1) = <<sayList(rexGroup(1))>>\n"; |
| | 246 | "group(2) = <<sayList(rexGroup(2))>>\n"; |
| | 247 | |
| | 248 | "replace(pat1, 'this is a test', 'TEST!!!', ReplaceOnce) = |
| | 249 | <<rexReplace(pat1, 'this is a test', 'TEST!!!', ReplaceOnce)>>\n"; |
| | 250 | "replace(pat3, 'this is box123!!!', '%2%1', ReplaceOnce) = |
| | 251 | <<rexReplace(pat3, 'this is box123!!!', '%2%1', ReplaceOnce)>>\n"; |
| | 252 | "replace(pat2, 'abc def def ghi', '<%*><%*>', ReplaceOnce) = |
| | 253 | <<rexReplace(pat2, 'abc def def ghi', '<%*><%*>', ReplaceOnce) |
| | 254 | .htmlify()>>\n"; |
| | 255 | "replace('^[a-z]*$', 'this is a test', '%*%*', ReplaceOnce) = |
| | 256 | <<rexReplace('^[a-z]*$', 'this is a test', '%*%*', ReplaceOnce)>>\n"; |
| | 257 | "replace('^[a-z]*$', 'testing', '%*%*', ReplaceOnce) = |
| | 258 | <<rexReplace('^[a-z]*$', 'testing', '%*%*', ReplaceOnce)>>\n"; |
| | 259 | "replace('%([0-9][0-9][0-9]%) *[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]', |
| | 260 | 'dial (800) 555-1212 on phone', '\"%*\"', ReplaceOnce) = |
| | 261 | <<rexReplace('%([0-9][0-9][0-9]%) ' |
| | 262 | + '*[0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]', |
| | 263 | 'dial (800) 555-1212 on phone', '"%*"', |
| | 264 | ReplaceOnce)>>\n"; |
| | 265 | |
| | 266 | "replace('[0-9]+', 'abc 123 def 456 789 ghi', '(%*)', ReplaceAll) = |
| | 267 | <<rexReplace('[0-9]+', 'abc 123 def 456 789 ghi', '(%*)', |
| | 268 | ReplaceAll)>>\n"; |
| | 269 | "replace('[0-9]+', '123 def 456 789', '(%*)', ReplaceAll) = |
| | 270 | <<rexReplace('[0-9]+', '123 def 456 789', '(%*)', |
| | 271 | ReplaceAll)>>\n"; |
| | 272 | "replace('[0-9]+', 'abc 123 def 456 789 ghi', '(%*)', ReplaceOnce) = |
| | 273 | <<rexReplace('[0-9]+', 'abc 123 def 456 789 ghi', '(%*)', |
| | 274 | ReplaceOnce)>>\n"; |
| | 275 | "replace('([a-z])([0-9]+)', 'x1937y2908z4200d', '%1 := %2; ', |
| | 276 | ReplaceAll) = |
| | 277 | <<rexReplace('([a-z])([0-9]+)', 'x1937y2908z4200d', '%1 := %2; ', |
| | 278 | ReplaceAll)>>\n"; |
| | 279 | } |
| | 280 | |