rapydscript-ns 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.agignore +1 -0
- package/.gitattributes +4 -0
- package/.github/workflows/ci.yml +38 -0
- package/.github/workflows/web-repl-page-deploy.yml +42 -0
- package/=template.pyj +5 -0
- package/CHANGELOG.md +456 -0
- package/CONTRIBUTORS +13 -0
- package/HACKING.md +103 -0
- package/LICENSE +24 -0
- package/README.md +2512 -0
- package/TODO.md +327 -0
- package/add-toc-to-readme +2 -0
- package/bin/export +75 -0
- package/bin/rapydscript +70 -0
- package/bin/web-repl-export +102 -0
- package/build +3 -0
- package/package.json +46 -0
- package/publish.py +37 -0
- package/release/baselib-plain-pretty.js +4370 -0
- package/release/baselib-plain-ugly.js +3 -0
- package/release/compiler.js +18394 -0
- package/release/signatures.json +31 -0
- package/session.vim +4 -0
- package/setup.cfg +2 -0
- package/src/ast.pyj +1356 -0
- package/src/baselib-builtins.pyj +279 -0
- package/src/baselib-containers.pyj +723 -0
- package/src/baselib-errors.pyj +37 -0
- package/src/baselib-internal.pyj +421 -0
- package/src/baselib-itertools.pyj +97 -0
- package/src/baselib-str.pyj +798 -0
- package/src/compiler.pyj +36 -0
- package/src/errors.pyj +30 -0
- package/src/lib/aes.pyj +646 -0
- package/src/lib/collections.pyj +695 -0
- package/src/lib/elementmaker.pyj +83 -0
- package/src/lib/encodings.pyj +126 -0
- package/src/lib/functools.pyj +148 -0
- package/src/lib/gettext.pyj +569 -0
- package/src/lib/itertools.pyj +580 -0
- package/src/lib/math.pyj +193 -0
- package/src/lib/numpy.pyj +2101 -0
- package/src/lib/operator.pyj +11 -0
- package/src/lib/pythonize.pyj +20 -0
- package/src/lib/random.pyj +118 -0
- package/src/lib/re.pyj +470 -0
- package/src/lib/traceback.pyj +63 -0
- package/src/lib/uuid.pyj +77 -0
- package/src/monaco-language-service/analyzer.js +526 -0
- package/src/monaco-language-service/builtins.js +543 -0
- package/src/monaco-language-service/completions.js +498 -0
- package/src/monaco-language-service/diagnostics.js +643 -0
- package/src/monaco-language-service/dts.js +550 -0
- package/src/monaco-language-service/hover.js +121 -0
- package/src/monaco-language-service/index.js +386 -0
- package/src/monaco-language-service/scope.js +162 -0
- package/src/monaco-language-service/signature.js +144 -0
- package/src/output/__init__.pyj +0 -0
- package/src/output/classes.pyj +296 -0
- package/src/output/codegen.pyj +492 -0
- package/src/output/comments.pyj +45 -0
- package/src/output/exceptions.pyj +105 -0
- package/src/output/functions.pyj +491 -0
- package/src/output/literals.pyj +109 -0
- package/src/output/loops.pyj +444 -0
- package/src/output/modules.pyj +329 -0
- package/src/output/operators.pyj +429 -0
- package/src/output/statements.pyj +463 -0
- package/src/output/stream.pyj +309 -0
- package/src/output/treeshake.pyj +182 -0
- package/src/output/utils.pyj +72 -0
- package/src/parse.pyj +3106 -0
- package/src/string_interpolation.pyj +72 -0
- package/src/tokenizer.pyj +702 -0
- package/src/unicode_aliases.pyj +576 -0
- package/src/utils.pyj +192 -0
- package/test/_import_one.pyj +37 -0
- package/test/_import_two/__init__.pyj +11 -0
- package/test/_import_two/level2/__init__.pyj +0 -0
- package/test/_import_two/level2/deep.pyj +4 -0
- package/test/_import_two/other.pyj +6 -0
- package/test/_import_two/sub.pyj +13 -0
- package/test/aes_vectors.pyj +421 -0
- package/test/annotations.pyj +80 -0
- package/test/baselib.pyj +319 -0
- package/test/classes.pyj +452 -0
- package/test/collections.pyj +152 -0
- package/test/decorators.pyj +77 -0
- package/test/dict_spread.pyj +76 -0
- package/test/docstrings.pyj +39 -0
- package/test/elementmaker_test.pyj +45 -0
- package/test/ellipsis.pyj +49 -0
- package/test/functions.pyj +151 -0
- package/test/generators.pyj +41 -0
- package/test/generic.pyj +370 -0
- package/test/imports.pyj +72 -0
- package/test/internationalization.pyj +73 -0
- package/test/lint.pyj +164 -0
- package/test/loops.pyj +85 -0
- package/test/numpy.pyj +734 -0
- package/test/omit_function_metadata.pyj +20 -0
- package/test/regexp.pyj +55 -0
- package/test/repl.pyj +121 -0
- package/test/scoped_flags.pyj +76 -0
- package/test/starargs.pyj +506 -0
- package/test/starred_assign.pyj +104 -0
- package/test/str.pyj +198 -0
- package/test/subscript_tuple.pyj +53 -0
- package/test/unit/fixtures/fibonacci_expected.js +46 -0
- package/test/unit/index.js +2989 -0
- package/test/unit/language-service-builtins.js +815 -0
- package/test/unit/language-service-completions.js +1067 -0
- package/test/unit/language-service-dts.js +543 -0
- package/test/unit/language-service-hover.js +455 -0
- package/test/unit/language-service-scope.js +833 -0
- package/test/unit/language-service-signature.js +458 -0
- package/test/unit/language-service.js +705 -0
- package/test/unit/run-language-service.js +41 -0
- package/test/unit/web-repl.js +484 -0
- package/tools/build-language-service.js +190 -0
- package/tools/cli.js +547 -0
- package/tools/compile.js +219 -0
- package/tools/compiler.js +108 -0
- package/tools/completer.js +131 -0
- package/tools/embedded_compiler.js +251 -0
- package/tools/export.js +316 -0
- package/tools/gettext.js +185 -0
- package/tools/ini.js +65 -0
- package/tools/lint.js +705 -0
- package/tools/msgfmt.js +187 -0
- package/tools/repl.js +223 -0
- package/tools/self.js +162 -0
- package/tools/test.js +118 -0
- package/tools/utils.js +128 -0
- package/tools/web_repl.js +95 -0
- package/try +41 -0
- package/web-repl/env.js +74 -0
- package/web-repl/index.html +163 -0
- package/web-repl/language-service.js +4084 -0
- package/web-repl/main.js +254 -0
- package/web-repl/prism.css +139 -0
- package/web-repl/prism.js +113 -0
- package/web-repl/rapydscript.js +435 -0
- package/web-repl/sha1.js +25 -0
package/test/generic.pyj
ADDED
|
@@ -0,0 +1,370 @@
|
|
|
1
|
+
# globals: assrt, ρσ_last_exception
|
|
2
|
+
|
|
3
|
+
import traceback
|
|
4
|
+
|
|
5
|
+
def throw_test(code):
|
|
6
|
+
assrt.throws(def():
|
|
7
|
+
RapydScript.parse(code, {'filename':code}).body[0]
|
|
8
|
+
, RapydScript.SyntaxError)
|
|
9
|
+
|
|
10
|
+
# unary operators
|
|
11
|
+
assrt.equal(-(1), -1)
|
|
12
|
+
assrt.equal(-(-1), 1)
|
|
13
|
+
assrt.equal(+(+1), 1)
|
|
14
|
+
|
|
15
|
+
# arithmetic
|
|
16
|
+
assrt.equal(3**4, Math.pow(3, 4))
|
|
17
|
+
assrt.equal(100**-2, Math.pow(100, -2))
|
|
18
|
+
assrt.equal(2*5**2*3, 150)
|
|
19
|
+
assrt.equal(-2**2, -4)
|
|
20
|
+
assrt.equal((-2)**2, 4)
|
|
21
|
+
assrt.equal(pow(2, 2, 2), 0)
|
|
22
|
+
assrt.equal(100 // 3, 33)
|
|
23
|
+
assrt.equal(-100 // 3, -34)
|
|
24
|
+
a = 100
|
|
25
|
+
a //= 3
|
|
26
|
+
assrt.equal(a, 33)
|
|
27
|
+
assrt.equal(0b11, 3)
|
|
28
|
+
assrt.ok(42 / "x" is NaN)
|
|
29
|
+
assrt.ok(42 is not NaN)
|
|
30
|
+
assrt.ok(NaN is parseInt('asd', 10))
|
|
31
|
+
assrt.ok('NaN' is not 42 / 'x')
|
|
32
|
+
|
|
33
|
+
# comparisons
|
|
34
|
+
assrt.ok(3<5<7)
|
|
35
|
+
assrt.equal(-1 < 0 == 1 < 0, False)
|
|
36
|
+
|
|
37
|
+
# Empty tuple
|
|
38
|
+
assrt.deepEqual((), [])
|
|
39
|
+
|
|
40
|
+
# Conditional operators
|
|
41
|
+
assrt.equal(1 if True else 2, 1)
|
|
42
|
+
assrt.equal(1
|
|
43
|
+
if True else 2, 1)
|
|
44
|
+
assrt.deepEqual([x for x in ("asd" if True else "xyz") if x], 'asd'.split(''))
|
|
45
|
+
assrt.deepEqual((1, [x for x in [2] if x]), [1, [2]])
|
|
46
|
+
|
|
47
|
+
# Comprehensions
|
|
48
|
+
assrt.deepEqual([a+1 for a in [1,2,3] if a > 1], [3, 4])
|
|
49
|
+
assrt.deepEqual({a+1:a+2 for a in [1,2,3] if a > 1}, {3:4, 4:5})
|
|
50
|
+
assrt.deepEqual({a+1 for a in [1,2,3] if a > 1}, set([3, 4]))
|
|
51
|
+
assrt.deepEqual([(a+1, 1) for a in [1,2,3] if a > 1], [[3, 1], [4, 1]])
|
|
52
|
+
|
|
53
|
+
# Destructuring assignment
|
|
54
|
+
a, (b, (c, d)), e = [1, [2, [3, 4]], 5]
|
|
55
|
+
assrt.deepEqual([a, b, c, d, e], [1, 2, 3, 4, 5])
|
|
56
|
+
for x, (y, z) in [ [1, [2, 3]] ]:
|
|
57
|
+
assrt.deepEqual([x, y, z], [1, 2, 3])
|
|
58
|
+
assrt.deepEqual([ [x, y, z, w] for ((x, y), (z, w)) in [ [[1, 2], [3, 4]] ] ],
|
|
59
|
+
[[1, 2, 3, 4]])
|
|
60
|
+
assrt.deepEqual([ [x, y, z] for x, (y, z) in [ [1, [2, 3] ] ]],
|
|
61
|
+
[[1, 2, 3]])
|
|
62
|
+
(a, b) = [1, 2]
|
|
63
|
+
assrt.deepEqual([a, b], [1, 2])
|
|
64
|
+
(a, (b, c)) = [1, [2, 3]]
|
|
65
|
+
assrt.deepEqual([a, b, c], [1, 2, 3])
|
|
66
|
+
|
|
67
|
+
# Chained assignment
|
|
68
|
+
a = b = 11
|
|
69
|
+
assrt.deepEqual([a, b], [11, 11])
|
|
70
|
+
def inc():
|
|
71
|
+
nonlocal a
|
|
72
|
+
a += 1
|
|
73
|
+
return a
|
|
74
|
+
a = b = inc()
|
|
75
|
+
assrt.deepEqual([a, b], [12, 12])
|
|
76
|
+
a, b = c, d = 1, 2
|
|
77
|
+
assrt.deepEqual([a, b, c, d], [1, 2, 1, 2])
|
|
78
|
+
(a, b) = [c, d] = 1, 2
|
|
79
|
+
assrt.deepEqual([a, b, c, d], [1, 2, 1, 2])
|
|
80
|
+
a, (x, b) = c, d = [1, [2, 3]]
|
|
81
|
+
assrt.deepEqual([a, x, b, c, d], [1, 2, 3, 1, [2, 3]])
|
|
82
|
+
a, b = [c, d] = [e, f] = [1, 2]
|
|
83
|
+
assrt.deepEqual([a, b, c, d, e, f], [1, 2, 1, 2, 1, 2])
|
|
84
|
+
a = b, c = 1, 2
|
|
85
|
+
assrt.deepEqual([a, b, c], [[1,2], 1, 2])
|
|
86
|
+
|
|
87
|
+
throw_test('a += b += 1')
|
|
88
|
+
throw_test('a += 1, 2 += b')
|
|
89
|
+
throw_test('a += [1, 2] += b')
|
|
90
|
+
throw_test('function = 1')
|
|
91
|
+
throw_test('def function():\n pass')
|
|
92
|
+
throw_test('class function:\n pass')
|
|
93
|
+
throw_test('while 1:\npass')
|
|
94
|
+
throw_test('def f():\n while 1:\n pass')
|
|
95
|
+
throw_test('1 1')
|
|
96
|
+
throw_test('z = x y')
|
|
97
|
+
throw_test('while a = 1: pass')
|
|
98
|
+
throw_test('while 1\n pass')
|
|
99
|
+
throw_test('for a in [1]\n pass')
|
|
100
|
+
|
|
101
|
+
# object literals
|
|
102
|
+
{1:
|
|
103
|
+
1
|
|
104
|
+
} # Check that arbitrary indentation is allowed after : for an object literal key
|
|
105
|
+
|
|
106
|
+
# strict equality
|
|
107
|
+
assrt(1 == 1) # number vs number: ok
|
|
108
|
+
assrt(True == True) # boolean vs boolean: ok
|
|
109
|
+
assrt(not (1 == True)) # number vs boolean: NEVER equal
|
|
110
|
+
assrt(1 != True) # number vs boolean: NEVER equal
|
|
111
|
+
assrt(not ("" == False)) # string vs boolean: NEVER equal
|
|
112
|
+
assrt(not ("0" == 0)) # string vs integer: NEVER equal
|
|
113
|
+
assrt(not ("" == 0)) # string vs integer: NEVER equal
|
|
114
|
+
assrt(bool(1) == True) # boolean conversion
|
|
115
|
+
assrt(bool("") == False) # boolean conversion
|
|
116
|
+
assrt(v'1 == true') # javascript override
|
|
117
|
+
assrt(not v'(1 != true)') # javascript override
|
|
118
|
+
assrt(v'String("test")' == "test") # this should do string conversion rather than creating a string object
|
|
119
|
+
assrt(String("test") != "test") # this should create a string object
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
# raw JavaScript
|
|
123
|
+
v'var def = {}' # ability to bypass reserved keywords in declaration
|
|
124
|
+
v'def'.item = 3 # ability to use reserved keywords
|
|
125
|
+
assrt(v'def.item' == 3)
|
|
126
|
+
|
|
127
|
+
n = 5
|
|
128
|
+
assrt.equal(v"""
|
|
129
|
+
(function() {
|
|
130
|
+
var s = 0
|
|
131
|
+
for (var i=0; i<=n; i++) {
|
|
132
|
+
s += i
|
|
133
|
+
}
|
|
134
|
+
return s
|
|
135
|
+
})()
|
|
136
|
+
""", (def():
|
|
137
|
+
s = 0
|
|
138
|
+
for i in range(n+1):
|
|
139
|
+
s += i
|
|
140
|
+
return s
|
|
141
|
+
)()) # shared scoping and equivalent capability
|
|
142
|
+
a = []
|
|
143
|
+
for v'var i = 0; i < 1; i++':
|
|
144
|
+
a[i] = 1 # noqa: undef
|
|
145
|
+
assrt.deepEqual(a, [1])
|
|
146
|
+
|
|
147
|
+
# String literals
|
|
148
|
+
a = '\u00ad'
|
|
149
|
+
assrt.equal(a.charCodeAt(0), 0xad)
|
|
150
|
+
# String literal concatenation
|
|
151
|
+
|
|
152
|
+
assrt.equal('1' '2', '12')
|
|
153
|
+
assrt.equal('1'
|
|
154
|
+
'2' '3', '123')
|
|
155
|
+
assrt.equal(u'a', 'a')
|
|
156
|
+
assrt.equal('a' * 5, 'aaaaa')
|
|
157
|
+
assrt.ok(isinstance('a', str))
|
|
158
|
+
|
|
159
|
+
# Various bits of miscellaneous code that caused parser infinite loops and other breakage
|
|
160
|
+
throw_test('for a in b:\\n 1+1')
|
|
161
|
+
|
|
162
|
+
def localvars_in_comprehension():
|
|
163
|
+
return {k:i for i, k in enumerate([1,2])}
|
|
164
|
+
assrt.deepEqual(localvars_in_comprehension(), {'1':0, '2':1})
|
|
165
|
+
|
|
166
|
+
# Numbers
|
|
167
|
+
assrt.equal(1e2, 100)
|
|
168
|
+
assrt.equal(-1e2, -100)
|
|
169
|
+
assrt.equal(1e+2, 100)
|
|
170
|
+
assrt.equal(1E-1, 0.1)
|
|
171
|
+
|
|
172
|
+
# Equality operators
|
|
173
|
+
|
|
174
|
+
class D:
|
|
175
|
+
|
|
176
|
+
def __init__(self, data):
|
|
177
|
+
self.data = data
|
|
178
|
+
|
|
179
|
+
def __eq__(self, other):
|
|
180
|
+
return self.data == other.data
|
|
181
|
+
|
|
182
|
+
assrt.ok(D(1) == D(1))
|
|
183
|
+
assrt.ok(D(2) != D(1))
|
|
184
|
+
assrt.ok(D(1) == {'data':1})
|
|
185
|
+
assrt.ok({'data':1} == D(1))
|
|
186
|
+
|
|
187
|
+
arr = []
|
|
188
|
+
{} == arr.append(2)
|
|
189
|
+
assrt.ok(arr.length is 1)
|
|
190
|
+
|
|
191
|
+
call_count = 0
|
|
192
|
+
def cc():
|
|
193
|
+
nonlocal call_count
|
|
194
|
+
call_count += 1
|
|
195
|
+
return [1]
|
|
196
|
+
cc()[-1]
|
|
197
|
+
assrt.equal(call_count, 1)
|
|
198
|
+
|
|
199
|
+
# Test the del operator
|
|
200
|
+
|
|
201
|
+
# JS object
|
|
202
|
+
deleteme = {1:1}
|
|
203
|
+
assrt.ok(Object.keys(deleteme).indexOf('1') is not -1)
|
|
204
|
+
del deleteme[1]
|
|
205
|
+
assrt.ok(Object.keys(deleteme).indexOf('1') is -1)
|
|
206
|
+
|
|
207
|
+
# list
|
|
208
|
+
deleteme = [1, 2]
|
|
209
|
+
del deleteme[0]
|
|
210
|
+
assrt.equal(deleteme.length, 1)
|
|
211
|
+
assrt.deepEqual(deleteme, [2])
|
|
212
|
+
deleteme = [1, 2, 3]
|
|
213
|
+
del deleteme[::2]
|
|
214
|
+
assrt.deepEqual(deleteme, [2])
|
|
215
|
+
deleteme = [1, 2, 3]
|
|
216
|
+
del deleteme[::1]
|
|
217
|
+
assrt.equal(deleteme.length, 0)
|
|
218
|
+
deleteme = [1, 2, 3]
|
|
219
|
+
del deleteme[1:2]
|
|
220
|
+
assrt.deepEqual(deleteme, [1, 3])
|
|
221
|
+
|
|
222
|
+
# global
|
|
223
|
+
del deleteme
|
|
224
|
+
|
|
225
|
+
# python dict
|
|
226
|
+
from __python__ import dict_literals, overload_getitem
|
|
227
|
+
deleteme = {1:1, 2:2}
|
|
228
|
+
assrt.ok(1 in deleteme)
|
|
229
|
+
del deleteme[1]
|
|
230
|
+
assrt.ok(1 not in deleteme)
|
|
231
|
+
assrt.equal(len(deleteme), 1)
|
|
232
|
+
|
|
233
|
+
# Asserts
|
|
234
|
+
|
|
235
|
+
assrt.throws(def():
|
|
236
|
+
assert 0
|
|
237
|
+
, AssertionError
|
|
238
|
+
)
|
|
239
|
+
assrt.throws(def():
|
|
240
|
+
assert 0, 'xdx'
|
|
241
|
+
, /xdx/
|
|
242
|
+
)
|
|
243
|
+
|
|
244
|
+
# Exceptions
|
|
245
|
+
|
|
246
|
+
class MyException(Exception):
|
|
247
|
+
|
|
248
|
+
def __init__(self, message, val):
|
|
249
|
+
Exception.__init__(self, message)
|
|
250
|
+
self.val = val
|
|
251
|
+
|
|
252
|
+
try:
|
|
253
|
+
raise MyException('xxx', 3)
|
|
254
|
+
except MyException as e:
|
|
255
|
+
assrt.equal(e.name, 'MyException')
|
|
256
|
+
assrt.equal(e.message, 'xxx')
|
|
257
|
+
assrt.equal(e.val, 3)
|
|
258
|
+
assrt.equal(e.toString(), 'MyException: xxx')
|
|
259
|
+
assrt.ok(v'e instanceof MyException')
|
|
260
|
+
assrt.ok(v'e instanceof Error')
|
|
261
|
+
|
|
262
|
+
try:
|
|
263
|
+
raise Error('eee')
|
|
264
|
+
except Exception:
|
|
265
|
+
# Test that we can catch JS errors and that local variables in the except block are declared
|
|
266
|
+
xxlocalvar = 1
|
|
267
|
+
assrt.equal(xxlocalvar, 1)
|
|
268
|
+
|
|
269
|
+
def errf():
|
|
270
|
+
raise MyException()
|
|
271
|
+
|
|
272
|
+
try:
|
|
273
|
+
errf()
|
|
274
|
+
except MyException as e:
|
|
275
|
+
fe = traceback.format_exception()
|
|
276
|
+
assrt.ok(str.strip(fe[-2]).startsWith('at errf'))
|
|
277
|
+
|
|
278
|
+
|
|
279
|
+
def stackf():
|
|
280
|
+
return traceback.format_stack()
|
|
281
|
+
assrt.ok(str.strip(stackf()[-1]).startsWith('at stackf'))
|
|
282
|
+
|
|
283
|
+
|
|
284
|
+
def else_without_finally(fail):
|
|
285
|
+
ans = []
|
|
286
|
+
try:
|
|
287
|
+
if fail:
|
|
288
|
+
raise Exception('a')
|
|
289
|
+
ans.push('ok')
|
|
290
|
+
except:
|
|
291
|
+
ans.append('ex')
|
|
292
|
+
else:
|
|
293
|
+
ans.append('el')
|
|
294
|
+
return ans
|
|
295
|
+
|
|
296
|
+
def else_with_finally(fail):
|
|
297
|
+
ans = []
|
|
298
|
+
try:
|
|
299
|
+
if fail:
|
|
300
|
+
raise Exception('a')
|
|
301
|
+
ans.push('ok')
|
|
302
|
+
except:
|
|
303
|
+
ans.push('ex')
|
|
304
|
+
else:
|
|
305
|
+
ans.push('el')
|
|
306
|
+
finally:
|
|
307
|
+
ans.push('fi')
|
|
308
|
+
return ans
|
|
309
|
+
|
|
310
|
+
def exc_in_else():
|
|
311
|
+
ans = []
|
|
312
|
+
try:
|
|
313
|
+
try:
|
|
314
|
+
ans.push('ok')
|
|
315
|
+
except:
|
|
316
|
+
pass
|
|
317
|
+
else:
|
|
318
|
+
raise Exception('1')
|
|
319
|
+
finally:
|
|
320
|
+
ans.push('fi')
|
|
321
|
+
except:
|
|
322
|
+
ans.push('ex')
|
|
323
|
+
return ans
|
|
324
|
+
|
|
325
|
+
assrt.deepEqual(else_without_finally(), ['ok', 'el'])
|
|
326
|
+
assrt.deepEqual(else_without_finally(True), ['ex'])
|
|
327
|
+
assrt.deepEqual(else_with_finally(), ['ok', 'el', 'fi'])
|
|
328
|
+
assrt.deepEqual(else_with_finally(True), ['ex', 'fi'])
|
|
329
|
+
assrt.deepEqual(exc_in_else(), ['ok', 'fi', 'ex'])
|
|
330
|
+
|
|
331
|
+
# Existential operator
|
|
332
|
+
|
|
333
|
+
assrt.ok(not gfsgs?)
|
|
334
|
+
assrt.equal(gfsgs ? 1, 1)
|
|
335
|
+
assrt.equal(gfsgs?.b, undefined)
|
|
336
|
+
assrt.equal(gfsgs?(), undefined) # noqa: undef
|
|
337
|
+
undef = undefined
|
|
338
|
+
assrt.ok(not undef?)
|
|
339
|
+
undef = None
|
|
340
|
+
assrt.ok(not undef?)
|
|
341
|
+
undef = 0
|
|
342
|
+
assrt.ok(undef?)
|
|
343
|
+
assrt.equal(undef?(), undefined)
|
|
344
|
+
assrt.equal(undef?.xxx?(), undefined)
|
|
345
|
+
assrt.equal(undef.a, undefined)
|
|
346
|
+
assrt.equal(undef[1], undefined)
|
|
347
|
+
assrt.equal(undef ? 1, 0)
|
|
348
|
+
ml = 1, '''
|
|
349
|
+
'''
|
|
350
|
+
assrt.deepEqual(ml, [1, '\n'])
|
|
351
|
+
|
|
352
|
+
|
|
353
|
+
# localvars in conditions
|
|
354
|
+
|
|
355
|
+
gv = 1
|
|
356
|
+
(def ():
|
|
357
|
+
if (gv = 2):
|
|
358
|
+
pass
|
|
359
|
+
assrt.equal(gv, 2)
|
|
360
|
+
)()
|
|
361
|
+
assrt.equal(gv, 1)
|
|
362
|
+
|
|
363
|
+
assrt.ok(1 not in [2, 3])
|
|
364
|
+
assrt.ok(1 in [1, 2])
|
|
365
|
+
assrt.ok("1" + "2" in ["12", "x"])
|
|
366
|
+
assrt.ok("1" + "2" not in ["1", "2"])
|
|
367
|
+
if "1" + "2" not in ["1", "2"]:
|
|
368
|
+
assrt.ok(1)
|
|
369
|
+
else:
|
|
370
|
+
assrt.ok(0)
|
package/test/imports.pyj
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# globals:test_path, GLOBAL_SYMBOL, assrt
|
|
2
|
+
from _import_one import toplevel_var, toplevel_func as tf, TopLevel, true_var, false_var, test_other
|
|
3
|
+
from _import_two import (toplevel_var2,
|
|
4
|
+
toplevel_func2, TopLevel2 as TL2)
|
|
5
|
+
|
|
6
|
+
def AClass(x):
|
|
7
|
+
return this
|
|
8
|
+
|
|
9
|
+
eq = assrt.equal
|
|
10
|
+
# Test import of top-level variables and callables
|
|
11
|
+
eq(toplevel_var, 'foo')
|
|
12
|
+
eq(tf('x'), 'xtoplevel')
|
|
13
|
+
eq(toplevel_var2, 'foo2')
|
|
14
|
+
eq(toplevel_func2('x'), 'xtoplevel2')
|
|
15
|
+
eq(false_var, undefined)
|
|
16
|
+
eq(test_other, 'other')
|
|
17
|
+
|
|
18
|
+
# Test import of top-level vars in a conditional
|
|
19
|
+
eq('true', true_var)
|
|
20
|
+
|
|
21
|
+
# Test plain imports
|
|
22
|
+
import _import_one
|
|
23
|
+
eq(_import_one.toplevel_var, toplevel_var)
|
|
24
|
+
eq(_import_one.toplevel_func('x'), tf('x'))
|
|
25
|
+
|
|
26
|
+
# Test recognition of imported classes
|
|
27
|
+
tl = TopLevel('1')
|
|
28
|
+
eq(tl.a, '1')
|
|
29
|
+
tl2 = TL2('x')
|
|
30
|
+
eq(tl2.a, 'x')
|
|
31
|
+
|
|
32
|
+
# Test access to submodules via plain imports
|
|
33
|
+
import _import_two.sub, _import_two.sub as ts
|
|
34
|
+
eq('sub', _import_two.sub.sub_var)
|
|
35
|
+
eq('sub', ts.sub_var)
|
|
36
|
+
eq('sub', _import_two.sub.sub_func())
|
|
37
|
+
|
|
38
|
+
# Test deep import
|
|
39
|
+
from _import_two.level2.deep import deep_var
|
|
40
|
+
eq('deep', deep_var)
|
|
41
|
+
|
|
42
|
+
# Test that class accessed via plain import is
|
|
43
|
+
# recognized
|
|
44
|
+
s = _import_two.sub.Sub(1)
|
|
45
|
+
eq(s.a, 1)
|
|
46
|
+
s2 = ts.Sub(1)
|
|
47
|
+
eq(s2.a, 1)
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
# Test that a class imported into an inner scope is not recognized as a class
|
|
51
|
+
# outside that scope
|
|
52
|
+
def inner():
|
|
53
|
+
from _import_one import AClass
|
|
54
|
+
a = AClass(1)
|
|
55
|
+
eq(a.a, 1)
|
|
56
|
+
|
|
57
|
+
inner()
|
|
58
|
+
b = AClass(1)
|
|
59
|
+
eq(b, this)
|
|
60
|
+
|
|
61
|
+
# Test global symbol declared in other module
|
|
62
|
+
eq(GLOBAL_SYMBOL, 'i am global')
|
|
63
|
+
|
|
64
|
+
# Import errors happen during parsing, so we cannot test them directly as they would
|
|
65
|
+
# prevent this file from being parsed.
|
|
66
|
+
|
|
67
|
+
assrt.throws(def():
|
|
68
|
+
RapydScript.parse('from _import_one import not_exported', {'basedir':test_path}).body[0]
|
|
69
|
+
, /not exported/)
|
|
70
|
+
assrt.throws(def():
|
|
71
|
+
RapydScript.parse('import xxxx', {'basedir':test_path}).body[0]
|
|
72
|
+
, /doesn't exist/)
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
# vim:fileencoding=utf-8
|
|
2
|
+
# License: BSD Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
|
|
3
|
+
|
|
4
|
+
from gettext import gettext as _, ngettext, install
|
|
5
|
+
|
|
6
|
+
g = require('../tools/gettext.js')
|
|
7
|
+
|
|
8
|
+
def gettext(code):
|
|
9
|
+
ans = {}
|
|
10
|
+
g.gettext(ans, code, '<test>')
|
|
11
|
+
return ans
|
|
12
|
+
|
|
13
|
+
def test_string(code, *args):
|
|
14
|
+
catalog = gettext(code)
|
|
15
|
+
assrt.equal(len(catalog), len(args))
|
|
16
|
+
for msgid, q in zip(Object.keys(catalog), args):
|
|
17
|
+
assrt.equal(g.entry_to_string(msgid, catalog[msgid]), q)
|
|
18
|
+
|
|
19
|
+
test_string('a = _("one")', '#: <test>:1\nmsgid "one"\nmsgstr ""')
|
|
20
|
+
test_string('a = _("one")\nb = gettext("one")', '#: <test>:1\n#: <test>:2\nmsgid "one"\nmsgstr ""')
|
|
21
|
+
test_string('''a = _("""one
|
|
22
|
+
two""")''', '#: <test>:1\nmsgid "one\\ntwo"\nmsgstr ""')
|
|
23
|
+
test_string('a = _("{}one")', '#: <test>:1\n#, python-brace-format\nmsgid "{}one"\nmsgstr ""')
|
|
24
|
+
test_string('a = _("{one}")', '#: <test>:1\n#, python-brace-format\nmsgid "{one}"\nmsgstr ""')
|
|
25
|
+
test_string('ngettext("one", "two", 1)', '#: <test>:1\nmsgid "one"\nmsgid_plural "two"\nmsgstr[0] ""\nmsgstr[1] ""')
|
|
26
|
+
test_string('''_('o"ne')''', '#: <test>:1\nmsgid "o\\"ne"\nmsgstr ""')
|
|
27
|
+
|
|
28
|
+
m = require('../tools/msgfmt.js')
|
|
29
|
+
catalog = m.parse(r'''
|
|
30
|
+
msgid ""
|
|
31
|
+
msgstr ""
|
|
32
|
+
"Language: en\n"
|
|
33
|
+
"Plural-Forms: nplurals=2; \n"
|
|
34
|
+
|
|
35
|
+
#, fuzzy
|
|
36
|
+
msgid "one\n"
|
|
37
|
+
"continued"
|
|
38
|
+
msgstr "ON"
|
|
39
|
+
"E"
|
|
40
|
+
|
|
41
|
+
msgid "two"
|
|
42
|
+
msgid_plural "three"
|
|
43
|
+
msgstr[0] "a"
|
|
44
|
+
"bc"
|
|
45
|
+
msgstr[1] "def"
|
|
46
|
+
|
|
47
|
+
msgid "test \"quote\" escape"
|
|
48
|
+
msgstr "good"
|
|
49
|
+
''')
|
|
50
|
+
|
|
51
|
+
assrt.equal(2, catalog['nplurals'])
|
|
52
|
+
assrt.equal('en', catalog['language'])
|
|
53
|
+
assrt.equal(catalog['entries'].length, 3)
|
|
54
|
+
item = catalog['entries'][0]
|
|
55
|
+
assrt.equal(item['msgid'], 'one\ncontinued')
|
|
56
|
+
assrt.deepEqual(item['msgstr'], v"['ONE']")
|
|
57
|
+
assrt.ok(item['fuzzy'], 'item not fuzzy')
|
|
58
|
+
item = catalog['entries'][1]
|
|
59
|
+
assrt.equal(item['msgid'], 'two')
|
|
60
|
+
assrt.deepEqual(item['msgstr'], v"['abc', 'def']")
|
|
61
|
+
assrt.ok(not item['fuzzy'], 'item not fuzzy')
|
|
62
|
+
item = catalog['entries'][2]
|
|
63
|
+
assrt.equal(item['msgid'], 'test "quote" escape')
|
|
64
|
+
assrt.deepEqual(item['msgstr'], v"['good']")
|
|
65
|
+
|
|
66
|
+
install({'entries': {
|
|
67
|
+
'one':['ONE'],
|
|
68
|
+
'two':['1', '2'],
|
|
69
|
+
}})
|
|
70
|
+
|
|
71
|
+
assrt.equal(_('one'), 'ONE')
|
|
72
|
+
assrt.equal(ngettext('two', 'xxx', 1), '1')
|
|
73
|
+
assrt.equal(ngettext('two', 'xxx', 100), '2')
|
package/test/lint.pyj
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# vim:fileencoding=utf-8
|
|
2
|
+
# License: BSD
|
|
3
|
+
# Copyright: 2015, Kovid Goyal <kovid at kovidgoyal.net>
|
|
4
|
+
|
|
5
|
+
linter = require('../tools/lint.js')
|
|
6
|
+
|
|
7
|
+
def lint(code):
|
|
8
|
+
return linter.lint_code(code, {'filename':'<test>', 'report':def():
|
|
9
|
+
pass
|
|
10
|
+
})
|
|
11
|
+
|
|
12
|
+
def err_test(code, ident, line, name, other_line):
|
|
13
|
+
msgs = lint(code)
|
|
14
|
+
assrt.ok(len(msgs) > 0, 'failed to find error in: ' + code)
|
|
15
|
+
assrt.equal(len(msgs), 1, 'found ' + (len(msgs) - 1) + ' extra errors in: ' + code)
|
|
16
|
+
assrt.equal(msgs[0].ident, ident, 'incorrect ident: ' + msgs[0].ident + ' for: ' + code)
|
|
17
|
+
if line != undefined:
|
|
18
|
+
assrt.equal(msgs[0].start_line, line, 'incorrect line: ' + msgs[0].start_line + ' for: ' + code)
|
|
19
|
+
if name != undefined:
|
|
20
|
+
assrt.equal(msgs[0].name, name, 'incorrect name: ' + msgs[0].name + ' for: ' + code)
|
|
21
|
+
if other_line != undefined:
|
|
22
|
+
assrt.equal(msgs[0].other_line, other_line, 'incorrect other_line: ' + msgs[0].other_line + ' for: ' + code)
|
|
23
|
+
|
|
24
|
+
def ok_test(code):
|
|
25
|
+
msgs = lint(code)
|
|
26
|
+
assrt.equal(msgs.length, 0, 'Got unexpected msg: ' + (msgs[0] or {}).message + ' for code: ' + code)
|
|
27
|
+
|
|
28
|
+
# Imports
|
|
29
|
+
err_test('import foo', 'unused-import', 1, 'foo')
|
|
30
|
+
err_test('import foo.boo', 'unused-import', 1, 'foo')
|
|
31
|
+
err_test('import foo as boo', 'unused-import', 1, 'boo')
|
|
32
|
+
err_test('from x import foo', 'unused-import', 1, 'foo')
|
|
33
|
+
err_test('from x import foo as boo', 'unused-import', 1, 'boo')
|
|
34
|
+
ok_test('import foo\nfoo')
|
|
35
|
+
|
|
36
|
+
# Function arguments
|
|
37
|
+
ok_test('def f(a):\n return a')
|
|
38
|
+
ok_test('def f(a=1):\n return a')
|
|
39
|
+
ok_test('def f(*a):\n return a')
|
|
40
|
+
ok_test('def f(**a):\n return a')
|
|
41
|
+
ok_test('def f(a):\n return 1')
|
|
42
|
+
|
|
43
|
+
# Extended slices
|
|
44
|
+
ok_test('a = []; a[::2], a[1:-1]')
|
|
45
|
+
|
|
46
|
+
# Top level unused ignored
|
|
47
|
+
ok_test('a=1\ndef f():\n pass')
|
|
48
|
+
|
|
49
|
+
# Destructuring assignment
|
|
50
|
+
ok_test('def f():\n a, b = 1, 2; a, b')
|
|
51
|
+
ok_test('def f():\n a = 1; b, c = a, 2; return b, c')
|
|
52
|
+
ok_test('for x, (y, z) in [ [1, [2, 3]] ]:\n x + y + z')
|
|
53
|
+
err_test('def f():\n a, b = 1, 1; return a', 'unused-local', 2, 'b')
|
|
54
|
+
|
|
55
|
+
# Compound assignment
|
|
56
|
+
err_test('a += 1', 'undef', 1, 'a')
|
|
57
|
+
ok_test('def f():\n a = 1; a += 1')
|
|
58
|
+
|
|
59
|
+
# Unused bindings
|
|
60
|
+
err_test('def f():\n a=1', 'unused-local', 2, 'a')
|
|
61
|
+
err_test('def f():\n def a():\n pass', 'unused-local', 2, 'a')
|
|
62
|
+
|
|
63
|
+
# Undefined references
|
|
64
|
+
err_test('f()', 'undef', 1, 'f')
|
|
65
|
+
err_test('a', 'undef', 1, 'a')
|
|
66
|
+
err_test('def f():\n a=1; return a\na', 'undef', 3, 'a')
|
|
67
|
+
|
|
68
|
+
# Comprehensions
|
|
69
|
+
ok_test('[x for x in [1,2]]')
|
|
70
|
+
ok_test('[1 for x in [1,2] if x]')
|
|
71
|
+
ok_test('[1 for x in [1,2]]')
|
|
72
|
+
ok_test('def f():\n l=[1,2];[x for x in l]')
|
|
73
|
+
ok_test('def f():\n l=[1,2];{x:True for x in l}')
|
|
74
|
+
err_test('def f():\n [x for x in [1,2]]; return x', 'undef', 2, 'x')
|
|
75
|
+
|
|
76
|
+
# Loops
|
|
77
|
+
ok_test('def f():\n for x in "":\n pass\n return x')
|
|
78
|
+
ok_test('def f():\n for x in "":\n x += 1\n')
|
|
79
|
+
ok_test('def f():\n for x, y in "":\n pass\n return x, y')
|
|
80
|
+
ok_test('for v"var i = 0; i < 1; i++":\n print(i)')
|
|
81
|
+
err_test('def f():\n a = 1\n for a in "":\n a', 'loop-shadowed', 3, 'a', 2)
|
|
82
|
+
|
|
83
|
+
# Semi-colons
|
|
84
|
+
err_test('a=1;;a', 'extra-semicolon', 1, ';')
|
|
85
|
+
err_test('a=1;', 'eol-semicolon', 1, ';')
|
|
86
|
+
|
|
87
|
+
# Builtins
|
|
88
|
+
for k in 'String Symbol this self window Map arguments print len range dir undefined'.split(' '):
|
|
89
|
+
ok_test(k)
|
|
90
|
+
|
|
91
|
+
# noqa
|
|
92
|
+
ok_test('f() # noqa')
|
|
93
|
+
ok_test('f() # noqa:undef')
|
|
94
|
+
err_test('f() # noqa:xxx', 'undef')
|
|
95
|
+
|
|
96
|
+
# Named func in branch
|
|
97
|
+
err_test('if 1:\n def f():\n pass', 'func-in-branch', 2, 'f')
|
|
98
|
+
err_test('if 1:\n pass\nelse:\n def f():\n pass', 'func-in-branch', 4, 'f')
|
|
99
|
+
err_test('try:\n def f():\n pass\nexcept:\n pass', 'func-in-branch', 2, 'f')
|
|
100
|
+
ok_test('if 1:\n a = def():\n pass')
|
|
101
|
+
|
|
102
|
+
# Syntax errors
|
|
103
|
+
err_test('def f(:\n pass', 'syntax-err', 1)
|
|
104
|
+
|
|
105
|
+
# Functions
|
|
106
|
+
ok_test('def f():\n pass\nf()')
|
|
107
|
+
|
|
108
|
+
# Non-locals
|
|
109
|
+
err_test('def a():\n x = 1\n def b():\n nonlocal x\n b()', 'unused-local', 2, 'x')
|
|
110
|
+
ok_test('def a():\n x = 1\n def b():\n nonlocal x\n x\n b()')
|
|
111
|
+
ok_test('def a():\n x = 1\n def b():\n nonlocal x\n x\n x = 2\n b()')
|
|
112
|
+
ok_test('def a():\n x = 1\n def ():\n nonlocal x\n x = 1\n x')
|
|
113
|
+
ok_test('nonlocal a\na()')
|
|
114
|
+
|
|
115
|
+
# Define after use
|
|
116
|
+
err_test('def g():\n f()\n f()\n def f():\n pass', 'def-after-use', 3, 'f')
|
|
117
|
+
|
|
118
|
+
# Decorators
|
|
119
|
+
ok_test('from x import y\n@y\ndef f():\n pass')
|
|
120
|
+
|
|
121
|
+
# try/except
|
|
122
|
+
ok_test('try:\n 1\nexcept Error as e:\n e')
|
|
123
|
+
|
|
124
|
+
# Classes
|
|
125
|
+
ok_test('''
|
|
126
|
+
class A:
|
|
127
|
+
|
|
128
|
+
h = j = 1
|
|
129
|
+
x = h + j
|
|
130
|
+
if True:
|
|
131
|
+
k = 1
|
|
132
|
+
else:
|
|
133
|
+
k = 2
|
|
134
|
+
|
|
135
|
+
def __init__(self, a):
|
|
136
|
+
self.a = a
|
|
137
|
+
|
|
138
|
+
def unused(self):
|
|
139
|
+
pass
|
|
140
|
+
other = unused
|
|
141
|
+
|
|
142
|
+
class B(A):
|
|
143
|
+
|
|
144
|
+
def __init__(self):
|
|
145
|
+
A.__init__(self, 'b')
|
|
146
|
+
''')
|
|
147
|
+
err_test('class A:\n def a(self):\n a()', 'undef', 3, 'a')
|
|
148
|
+
err_test('class A:\n def a(self):\n pass\n def a(self):\n pass', 'dup-method', 4, 'a')
|
|
149
|
+
|
|
150
|
+
# Object literals
|
|
151
|
+
err_test('{"a":1, "a":2}', 'dup-key', 1, 'a')
|
|
152
|
+
|
|
153
|
+
# keyword arg values
|
|
154
|
+
ok_test('def f():\n a=1\n f(b=a)')
|
|
155
|
+
ok_test('def f():\n a={}\n f(**a)')
|
|
156
|
+
|
|
157
|
+
# with statement
|
|
158
|
+
ok_test('''
|
|
159
|
+
def f():
|
|
160
|
+
a = 1
|
|
161
|
+
with a as b:
|
|
162
|
+
b()
|
|
163
|
+
''')
|
|
164
|
+
err_test('with a:\n pass', 'undef', '1', 'a')
|