Skip to content

Commit 2b55db1

Browse files
authored
Merge pull request #25 from Mathics3/revise-tests
Go over unit tests
2 parents eb1fae6 + 73bf47f commit 2b55db1

File tree

2 files changed

+140
-131
lines changed

2 files changed

+140
-131
lines changed

Makefile

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ PIP ?= pip3
1010
RM ?= rm
1111

1212
.PHONY: all build \
13-
check clean \
13+
check check-full check-mathics clean \
1414
develop dist doc \
1515
inputrc-no-unicode \
1616
inputrc-unicode \
@@ -41,7 +41,14 @@ dist: admin-tools/make-dist.sh
4141
install: build
4242
$(PYTHON) setup.py install
4343

44-
test check: pytest
44+
#: Run unit tests and Mathics doctest
45+
check-full: pytest check-mathics
46+
47+
#: Run unit tests and Mathics doctest
48+
check: pytest
49+
50+
#: Same as check
51+
test: check
4552

4653
#: Build Sphinx HTML documentation
4754
doc: mathics_scanner/data/characters.json

test/test_tokeniser.py

Lines changed: 131 additions & 129 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,52 @@
77
import random
88
import sys
99

10-
from mathics_scanner.tokeniser import Tokeniser, Token
10+
from mathics_scanner.tokeniser import Tokeniser, Token, is_symbol_name
1111
from mathics_scanner.errors import ScanError, IncompleteSyntaxError, InvalidSyntaxError
1212
from mathics_scanner.feed import SingleLineFeeder
1313

1414

15+
def check_number(code):
16+
token = single_token(code)
17+
assert token, Token("Number", code, 0)
18+
19+
20+
def check_symbol(code):
21+
token = single_token(code)
22+
assert token, Token("Symbol", code, 0)
23+
24+
25+
def check_string(code):
26+
token = single_token(code)
27+
assert token, Token("String", code, 0)
28+
29+
30+
def incomplete_error(string):
31+
with pytest.raises(IncompleteSyntaxError):
32+
tokens(string)
33+
34+
35+
def invalid_error(string):
36+
with pytest.raises(InvalidSyntaxError):
37+
tokens(string)
38+
39+
40+
def scan_error(string):
41+
with pytest.raises(ScanError):
42+
tokens(string)
43+
44+
45+
def single_token(code):
46+
toks = tokens(code)
47+
assert len(toks) == 1
48+
token = toks[0]
49+
return token
50+
51+
52+
def tags(code):
53+
return [token.tag for token in tokens(code)]
54+
55+
1556
def tokens(code):
1657
tokeniser = Tokeniser(SingleLineFeeder(code))
1758
tokens = []
@@ -24,104 +65,134 @@ def tokens(code):
2465
return tokens
2566

2667

27-
def tags(code):
28-
return [token.tag for token in tokens(code)]
68+
def test_apply():
69+
assert tokens("f // x") == [
70+
Token("Symbol", "f", 0),
71+
Token("Postfix", "//", 2),
72+
Token("Symbol", "x", 5),
73+
]
74+
assert tokens("f @ x") == [
75+
Token("Symbol", "f", 0),
76+
Token("Prefix", "@", 2),
77+
Token("Symbol", "x", 4),
78+
]
79+
assert tokens("f ~ x") == [
80+
Token("Symbol", "f", 0),
81+
Token("Infix", "~", 2),
82+
Token("Symbol", "x", 4),
83+
]
2984

3085

31-
def single_token(code):
32-
toks = tokens(code)
33-
assert len(toks) == 1
34-
token = toks[0]
35-
return token
86+
def test_association():
87+
assert tokens("<|x -> m|>") == [
88+
Token("RawLeftAssociation", "<|", 0),
89+
Token("Symbol", "x", 2),
90+
Token("Rule", "->", 4),
91+
Token("Symbol", "m", 7),
92+
Token("RawRightAssociation", "|>", 8),
93+
]
3694

3795

38-
def check_number(code):
39-
token = single_token(code)
40-
assert token, Token("Number", code, 0)
96+
def test_backslash():
97+
assert tokens("\\[Backslash]") == [Token("Backslash", "\u2216", 0)]
4198

99+
assert tokens("\\ a") == [Token("RawBackslash", "\\", 0), Token("Symbol", "a", 2)]
42100

43-
def check_symbol(code):
44-
token = single_token(code)
45-
assert token, Token("Symbol", code, 0)
101+
incomplete_error("\\")
46102

47103

48-
def check_string(code):
49-
token = single_token(code)
50-
assert token, Token("String", code, 0)
104+
def test_boxes():
105+
assert tokens("\\(1\\)") == [
106+
Token("LeftRowBox", "\\(", 0),
107+
Token("Number", "1", 2),
108+
Token("RightRowBox", "\\)", 3),
109+
]
51110

52111

53-
def test_number():
54-
assert tags("1.5") == ["Number"]
55-
assert tags("1.5*^10") == ["Number"]
112+
def test_information():
113+
assert tokens("??Sin") == [Token("Information", "??", 0), Token("Symbol", "Sin", 2)]
56114

115+
assert tokens("? ?Sin") == [
116+
Token("PatternTest", "?", 0),
117+
Token("PatternTest", "?", 2),
118+
Token("Symbol", "Sin", 3),
119+
]
57120

58-
def scan_error(string):
59-
with pytest.raises(ScanError):
60-
tokens(string)
61121

122+
def test_int_repeated():
123+
assert tokens("1..") == [Token("Number", "1", 0), Token("Repeated", "..", 1)]
124+
assert tokens("1. .") == [Token("Number", "1.", 0), Token("Dot", ".", 3)]
62125

63-
def incomplete_error(string):
64-
with pytest.raises(IncompleteSyntaxError):
65-
tokens(string)
126+
127+
def test_integeral():
128+
assert tokens("\u222B x \uF74C y") == [
129+
Token("Integral", "\u222B", 0),
130+
Token("Symbol", "x", 2),
131+
Token("DifferentialD", "\uF74C", 4),
132+
Token("Symbol", "y", 6),
133+
]
66134

67135

68-
def invalid_error(string):
69-
with pytest.raises(InvalidSyntaxError):
70-
tokens(string)
136+
def test_is_symbol():
137+
assert is_symbol_name("Derivative")
138+
assert not is_symbol_name("98") # symbols can't start with numbers
71139

72140

73-
def testSymbol():
74-
check_symbol("xX")
75-
check_symbol("context`name")
76-
check_symbol("`name")
77-
check_symbol("`context`name")
141+
def test_accuracy():
142+
scan_error("1.5``")
143+
check_number("1.0``20")
144+
check_number("1.0``0")
145+
check_number("1.4``-20")
78146

79147

80-
def testNumber():
148+
def test_number():
149+
assert tags("1.5") == ["Number"]
150+
assert tags("1.5*^10") == ["Number"]
81151
check_number("0")
82152

83153

84-
def testNumberBase():
154+
def test_number_base():
85155
check_number("8^^23")
86156
check_number("10*^3")
87157
check_number("10*^-3")
88158
check_number("8^^23*^2")
89159

90160

91-
def testNumberBig():
161+
def test_number_big():
92162
for _ in range(10):
93163
check_number(str(random.randint(0, sys.maxsize)))
94164
check_number(str(random.randint(sys.maxsize, sys.maxsize * sys.maxsize)))
95165

96166

97-
def testNumberReal():
167+
def test_number_real():
98168
check_number("1.5")
99169
check_number("1.5`")
100170
check_number("0.0")
101171

102172

103-
def testString():
104-
check_string(r'"abc"')
105-
incomplete_error(r'"abc')
106-
check_string(r'"abc(*def*)"')
107-
check_string(r'"a\"b\\c"')
108-
incomplete_error(r'"\"')
173+
def test_pre():
174+
assert tokens("++x++") == [
175+
Token("Increment", "++", 0),
176+
Token("Symbol", "x", 2),
177+
Token("Increment", "++", 3),
178+
]
109179

110180

111-
def testPrecision():
181+
def test_precision():
112182
check_number("1.5`-5")
113183
check_number("1.5`0")
114184
check_number("1.5`10")
115185

116186

117-
def testAccuracy():
118-
scan_error("1.5``")
119-
check_number("1.0``20")
120-
check_number("1.0``0")
121-
check_number("1.4``-20")
187+
def test_string():
188+
check_string(r'"abc"')
189+
incomplete_error(r'"abc')
190+
check_string(r'"abc(*def*)"')
191+
check_string(r'"a\"b\\c"')
192+
incomplete_error(r'"\"')
122193

123194

124-
def testSet():
195+
def test_set():
125196
assert tokens("x = y") == [
126197
Token("Symbol", "x", 0),
127198
Token("Set", "=", 2),
@@ -136,93 +207,24 @@ def testSet():
136207
]
137208

138209

139-
def testUnset():
210+
def test_symbol():
211+
check_symbol("xX")
212+
check_symbol("context`name")
213+
check_symbol("`name")
214+
check_symbol("`context`name")
215+
216+
217+
def test_unset():
140218
assert tokens("=.") == [Token("Unset", "=.", 0)]
141219

142220
assert tokens("= .") == [Token("Unset", "= .", 0)]
143221
assert tokens("=.5") == [Token("Set", "=", 0), Token("Number", ".5", 1)]
144222
assert tokens("= ..") == [Token("Set", "=", 0), Token("Repeated", "..", 2)]
145223

146224

147-
def testIntRepeated():
148-
assert tokens("1..") == [Token("Number", "1", 0), Token("Repeated", "..", 1)]
149-
assert tokens("1. .") == [Token("Number", "1.", 0), Token("Dot", ".", 3)]
150-
151-
152-
def testIntegeral():
153-
assert tokens("\u222B x \uF74C y") == [
154-
Token("Integral", "\u222B", 0),
155-
Token("Symbol", "x", 2),
156-
Token("DifferentialD", "\uF74C", 4),
157-
Token("Symbol", "y", 6),
158-
]
159-
160-
161-
def testPre():
162-
assert tokens("++x++") == [
163-
Token("Increment", "++", 0),
164-
Token("Symbol", "x", 2),
165-
Token("Increment", "++", 3),
166-
]
167-
168-
169-
def testFunction():
225+
def test_function():
170226
assert tokens("x&") == [Token("Symbol", "x", 0), Token("Function", "&", 1)]
171227
assert tokens("x\uf4a1") == [
172228
Token("Symbol", "x", 0),
173229
Token("Function", "\uf4a1", 1),
174230
]
175-
176-
177-
def testApply():
178-
assert tokens("f // x") == [
179-
Token("Symbol", "f", 0),
180-
Token("Postfix", "//", 2),
181-
Token("Symbol", "x", 5),
182-
]
183-
assert tokens("f @ x") == [
184-
Token("Symbol", "f", 0),
185-
Token("Prefix", "@", 2),
186-
Token("Symbol", "x", 4),
187-
]
188-
assert tokens("f ~ x") == [
189-
Token("Symbol", "f", 0),
190-
Token("Infix", "~", 2),
191-
Token("Symbol", "x", 4),
192-
]
193-
194-
195-
def testBackslash():
196-
assert tokens("\\[Backslash]") == [Token("Backslash", "\u2216", 0)]
197-
198-
assert tokens("\\ a") == [Token("RawBackslash", "\\", 0), Token("Symbol", "a", 2)]
199-
200-
incomplete_error("\\")
201-
202-
203-
def testBoxes():
204-
assert tokens("\\(1\\)") == [
205-
Token("LeftRowBox", "\\(", 0),
206-
Token("Number", "1", 2),
207-
Token("RightRowBox", "\\)", 3),
208-
]
209-
210-
211-
def testInformation():
212-
assert tokens("??Sin") == [Token("Information", "??", 0), Token("Symbol", "Sin", 2)]
213-
214-
assert tokens("? ?Sin") == [
215-
Token("PatternTest", "?", 0),
216-
Token("PatternTest", "?", 2),
217-
Token("Symbol", "Sin", 3),
218-
]
219-
220-
221-
def testAssociation():
222-
assert tokens("<|x -> m|>") == [
223-
Token("RawLeftAssociation", "<|", 0),
224-
Token("Symbol", "x", 2),
225-
Token("Rule", "->", 4),
226-
Token("Symbol", "m", 7),
227-
Token("RawRightAssociation", "|>", 8),
228-
]

0 commit comments

Comments
 (0)