testml 0.0.1 → 0.0.2

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.
Files changed (58) hide show
  1. data/.gemspec +3 -1
  2. data/CHANGELOG.yaml +4 -1
  3. data/LICENSE +1 -1
  4. data/README.rdoc +30 -5
  5. data/Rakefile +10 -1
  6. data/ToDo +56 -0
  7. data/lib/rake/testml.rb +14 -0
  8. data/lib/testml.rb +46 -2
  9. data/lib/testml/bridge.rb +5 -0
  10. data/lib/testml/compiler.rb +106 -0
  11. data/lib/testml/compiler/lite.rb +194 -0
  12. data/lib/testml/compiler/pegex.rb +50 -0
  13. data/lib/testml/compiler/pegex/ast.rb +145 -0
  14. data/lib/testml/compiler/pegex/grammar.rb +173 -0
  15. data/lib/testml/library.rb +7 -0
  16. data/lib/testml/library/debug.rb +18 -0
  17. data/lib/testml/library/standard.rb +86 -0
  18. data/lib/testml/runtime.rb +501 -0
  19. data/lib/testml/runtime/unit.rb +94 -0
  20. data/lib/testml/setup.rb +65 -0
  21. data/lib/testml/util.rb +22 -0
  22. data/test/ast/arguments.tml +87 -0
  23. data/test/ast/basic.tml +83 -0
  24. data/test/ast/dataless.tml +36 -0
  25. data/test/ast/exceptions.tml +59 -0
  26. data/test/ast/external.tml +42 -0
  27. data/test/ast/function.tml +276 -0
  28. data/test/ast/label.tml +58 -0
  29. data/test/ast/markers.tml +36 -0
  30. data/test/ast/semicolons.tml +30 -0
  31. data/test/ast/truth.tml +85 -0
  32. data/test/ast/types.tml +163 -0
  33. data/test/compile-lite.rb +38 -0
  34. data/test/compile-testml-document.rb +59 -0
  35. data/test/compile.rb +57 -0
  36. data/test/inline-bridge.rb +30 -0
  37. data/test/inline.rb +28 -0
  38. data/test/strings.rb +24 -0
  39. data/test/testml.rb +38 -0
  40. data/test/testml.yaml +10 -0
  41. data/test/testml/arguments.tml +18 -0
  42. data/test/testml/assertions.tml +15 -0
  43. data/test/testml/basic.tml +37 -0
  44. data/test/testml/dataless.tml +9 -0
  45. data/test/testml/exceptions.tml +16 -0
  46. data/test/testml/external.tml +8 -0
  47. data/test/testml/external1.tml +10 -0
  48. data/test/testml/external2.tml +3 -0
  49. data/test/testml/function.tml +82 -0
  50. data/test/testml/label.tml +24 -0
  51. data/test/testml/markers.tml +19 -0
  52. data/test/testml/semicolons.tml +10 -0
  53. data/test/testml/standard.tml +50 -0
  54. data/test/testml/truth.tml +22 -0
  55. data/test/testml/types.tml +24 -0
  56. data/test/testml_bridge.rb +28 -0
  57. metadata +69 -4
  58. data/test/fail.rb +0 -12
@@ -0,0 +1,163 @@
1
+ --- !!perl/hash:TestML::Function
2
+ namespace:
3
+ TestML: !!perl/hash:TestML::Str
4
+ value: '0.1.0'
5
+
6
+ statements:
7
+ - !!perl/hash:TestML::Assignment
8
+ name: Plan
9
+ expr: !!perl/hash:TestML::Num
10
+ value: 11
11
+ - !!perl/hash:TestML::Assignment
12
+ name: Label
13
+ expr: !!perl/hash:TestML::Str
14
+ value: Test $TestNumber
15
+ - !!perl/hash:TestML::Statement
16
+ expr: !!perl/hash:TestML::Expression
17
+ calls:
18
+ - !!perl/hash:TestML::Str
19
+ value: Foo
20
+ - !!perl/hash:TestML::Call
21
+ name: Type
22
+ assert: !!perl/hash:TestML::Assertion
23
+ name: EQ
24
+ expr: !!perl/hash:TestML::Str
25
+ value: Str
26
+ - !!perl/hash:TestML::Statement
27
+ expr: !!perl/hash:TestML::Expression
28
+ calls:
29
+ - !!perl/hash:TestML::Num
30
+ value: 42
31
+ - !!perl/hash:TestML::Call
32
+ name: Type
33
+ assert: !!perl/hash:TestML::Assertion
34
+ name: EQ
35
+ expr: !!perl/hash:TestML::Str
36
+ value: Num
37
+ - !!perl/hash:TestML::Statement
38
+ expr: !!perl/hash:TestML::Expression
39
+ calls:
40
+ - !!perl/hash:TestML::Call
41
+ name: 'True'
42
+ - !!perl/hash:TestML::Call
43
+ name: Type
44
+ assert: !!perl/hash:TestML::Assertion
45
+ name: EQ
46
+ expr: !!perl/hash:TestML::Str
47
+ value: Bool
48
+ - !!perl/hash:TestML::Statement
49
+ expr: !!perl/hash:TestML::Expression
50
+ calls:
51
+ - !!perl/hash:TestML::Call
52
+ args:
53
+ - !!perl/hash:TestML::Num
54
+ value: 1
55
+ - !!perl/hash:TestML::Num
56
+ value: 2
57
+ - !!perl/hash:TestML::Num
58
+ value: 3
59
+ name: List
60
+ - !!perl/hash:TestML::Call
61
+ name: Type
62
+ assert: !!perl/hash:TestML::Assertion
63
+ name: EQ
64
+ expr: !!perl/hash:TestML::Str
65
+ value: List
66
+ - !!perl/hash:TestML::Statement
67
+ expr: !!perl/hash:TestML::Expression
68
+ calls:
69
+ - !!perl/hash:TestML::Function
70
+ statements: []
71
+ - !!perl/hash:TestML::Call
72
+ name: Type
73
+ assert: !!perl/hash:TestML::Assertion
74
+ name: EQ
75
+ expr: !!perl/hash:TestML::Str
76
+ value: Func
77
+ - !!perl/hash:TestML::Statement
78
+ expr: !!perl/hash:TestML::Expression
79
+ calls:
80
+ - !!perl/hash:TestML::Function
81
+ statements: []
82
+ - !!perl/hash:TestML::Call
83
+ name: Type
84
+ assert: !!perl/hash:TestML::Assertion
85
+ name: EQ
86
+ expr: !!perl/hash:TestML::Str
87
+ value: Func
88
+ - !!perl/hash:TestML::Assignment
89
+ name: s
90
+ expr: !!perl/hash:TestML::Str
91
+ value: Foo
92
+ - !!perl/hash:TestML::Statement
93
+ expr: !!perl/hash:TestML::Expression
94
+ calls:
95
+ - !!perl/hash:TestML::Call
96
+ name: s
97
+ - !!perl/hash:TestML::Call
98
+ name: Type
99
+ assert: !!perl/hash:TestML::Assertion
100
+ name: EQ
101
+ expr: !!perl/hash:TestML::Str
102
+ value: Str
103
+ - !!perl/hash:TestML::Assignment
104
+ name: n
105
+ expr: !!perl/hash:TestML::Num
106
+ value: 42
107
+ - !!perl/hash:TestML::Statement
108
+ expr: !!perl/hash:TestML::Expression
109
+ calls:
110
+ - !!perl/hash:TestML::Call
111
+ name: n
112
+ - !!perl/hash:TestML::Call
113
+ name: Type
114
+ assert: !!perl/hash:TestML::Assertion
115
+ name: EQ
116
+ expr: !!perl/hash:TestML::Str
117
+ value: Num
118
+ - !!perl/hash:TestML::Assignment
119
+ name: b
120
+ expr: !!perl/hash:TestML::Call
121
+ name: 'False'
122
+ - !!perl/hash:TestML::Statement
123
+ expr: !!perl/hash:TestML::Expression
124
+ calls:
125
+ - !!perl/hash:TestML::Call
126
+ name: b
127
+ - !!perl/hash:TestML::Call
128
+ name: Type
129
+ assert: !!perl/hash:TestML::Assertion
130
+ name: EQ
131
+ expr: !!perl/hash:TestML::Str
132
+ value: Bool
133
+ - !!perl/hash:TestML::Assignment
134
+ name: l
135
+ expr: !!perl/hash:TestML::Call
136
+ name: List
137
+ args: []
138
+ - !!perl/hash:TestML::Statement
139
+ expr: !!perl/hash:TestML::Expression
140
+ calls:
141
+ - !!perl/hash:TestML::Call
142
+ name: l
143
+ - !!perl/hash:TestML::Call
144
+ name: Type
145
+ assert: !!perl/hash:TestML::Assertion
146
+ name: EQ
147
+ expr: !!perl/hash:TestML::Str
148
+ value: List
149
+ - !!perl/hash:TestML::Assignment
150
+ name: f
151
+ expr: !!perl/hash:TestML::Function
152
+ statements: []
153
+ - !!perl/hash:TestML::Statement
154
+ expr: !!perl/hash:TestML::Expression
155
+ calls:
156
+ - !!perl/hash:TestML::Call
157
+ name: f
158
+ - !!perl/hash:TestML::Call
159
+ name: Type
160
+ assert: !!perl/hash:TestML::Assertion
161
+ name: EQ
162
+ expr: !!perl/hash:TestML::Str
163
+ value: Func
@@ -0,0 +1,38 @@
1
+ require 'test/unit'
2
+
3
+ require 'testml/runtime'
4
+ require 'testml/compiler/pegex'
5
+ require 'testml/compiler/lite'
6
+ require 'yaml'
7
+
8
+ class TestCompileLite < Test::Unit::TestCase
9
+ def test_compile_lite
10
+ testml = <<'...'
11
+ # A comment
12
+ %TestML 0.1.0
13
+
14
+ Plan = 2;
15
+ Title = "O HAI TEST";
16
+
17
+ *input.uppercase == *output;
18
+
19
+ === Test mixed case string
20
+ --- input: I Like Pie
21
+ --- output: I LIKE PIE
22
+
23
+ === Test lower case string
24
+ --- input: i love lucy
25
+ --- output: I LOVE LUCY
26
+ ...
27
+
28
+ func = TestML::Compiler::Pegex.new.compile(testml)
29
+ func_lite = TestML::Compiler::Lite.new.compile(testml)
30
+
31
+ # File.open('/tmp/got', 'w') {|f| f.write func.to_yaml}
32
+ # File.open('/tmp/want', 'w') {|f| f.write func_lite.to_yaml}
33
+ # STDERR.write(`diff -u /tmp/want /tmp/got`)
34
+
35
+ assert_equal YAML.dump(func_lite), YAML.dump(func),
36
+ 'Lite compile matches normal compile'
37
+ end
38
+ end
@@ -0,0 +1,59 @@
1
+ require 'test/unit'
2
+
3
+ require 'testml/runtime'
4
+ require 'testml/compiler/pegex'
5
+
6
+ class TestCompileTestMLDocument < Test::Unit::TestCase
7
+ def test_compile_testml_document
8
+ testml = <<'...'
9
+ # A comment
10
+ %TestML 0.1.0
11
+
12
+ Plan = 2
13
+ Title = "O HAI TEST"
14
+
15
+ *input.uppercase() == *output
16
+
17
+ === Test mixed case string
18
+ --- input: I Like Pie
19
+ --- output: I LIKE PIE
20
+
21
+ === Test lower case string
22
+ --- input: i love lucy
23
+ --- output: I LOVE LUCY
24
+ ...
25
+
26
+ func = TestML::Compiler::Pegex.new.compile(testml)
27
+ assert func, 'TestML string matches against TestML grammar'
28
+ assert_equal func.namespace['TestML'].value, '0.1.0', 'Version parses'
29
+ assert_equal func.statements[0].expr.value, 2, 'Plan parses'
30
+ assert_equal func.statements[1].expr.value, 'O HAI TEST', 'Title parses'
31
+ assert_equal func.statements[1].expr.value, 'O HAI TEST', 'Title parses'
32
+
33
+ assert_equal func.statements.size, 3, 'Three test statements'
34
+ statement = func.statements[2]
35
+ assert_equal statement.points.join('-'), 'input-output',
36
+ 'Point list is correct'
37
+
38
+ assert_equal statement.expr.calls.size, 2, 'Expression has two calls'
39
+ expr = statement.expr
40
+ assert expr.calls[0].kind_of?(TestML::Point), 'First sub is a Point'
41
+ assert_equal expr.calls[0].name, 'input', 'Point name is "input"'
42
+ assert_equal expr.calls[1].name, 'uppercase', 'Second sub is "uppercase"'
43
+
44
+ assert_equal statement.assert.name, 'EQ', 'Assertion is "EQ"'
45
+
46
+ expr = statement.assert.expr
47
+ assert expr.kind_of?(TestML::Point), 'First sub is a Point'
48
+ assert_equal expr.name, 'output', 'Point name is "output"'
49
+
50
+ assert_equal func.data.size, 2, 'Two data blocks'
51
+ (block1, block2) = func.data
52
+ assert_equal block1.label, 'Test mixed case string', 'Block 1 label ok'
53
+ assert_equal block1.points['input'], 'I Like Pie', 'Block 1, input point'
54
+ assert_equal block1.points['output'], 'I LIKE PIE', 'Block 1, output point'
55
+ assert_equal block2.label, 'Test lower case string', 'Block 2 label ok'
56
+ assert_equal block2.points['input'], 'i love lucy', 'Block 2, input point'
57
+ assert_equal block2.points['output'], 'I LOVE LUCY', 'Block 2, output point'
58
+ end
59
+ end
data/test/compile.rb ADDED
@@ -0,0 +1,57 @@
1
+ require 'test/unit'
2
+
3
+ require 'testml/runtime'
4
+ require 'testml/compiler/lite'
5
+ require 'testml/compiler/pegex'
6
+ require 'yaml'
7
+
8
+ class TestCompile < Test::Unit::TestCase
9
+ def test_compile
10
+ compile('testml/arguments.tml', TestML::Compiler::Pegex)
11
+ compile('testml/basic.tml', TestML::Compiler::Pegex)
12
+ compile('testml/dataless.tml', TestML::Compiler::Pegex)
13
+ compile('testml/exceptions.tml', TestML::Compiler::Pegex)
14
+ compile('testml/external.tml', TestML::Compiler::Pegex)
15
+ compile('testml/function.tml', TestML::Compiler::Pegex)
16
+ compile('testml/label.tml', TestML::Compiler::Pegex)
17
+ compile('testml/markers.tml', TestML::Compiler::Pegex)
18
+ compile('testml/semicolons.tml', TestML::Compiler::Pegex)
19
+ compile('testml/truth.tml', TestML::Compiler::Pegex)
20
+ compile('testml/types.tml', TestML::Compiler::Pegex)
21
+
22
+ compile('testml/arguments.tml', TestML::Compiler::Lite)
23
+ compile('testml/basic.tml', TestML::Compiler::Lite)
24
+ compile('testml/exceptions.tml', TestML::Compiler::Lite)
25
+ compile('testml/semicolons.tml', TestML::Compiler::Lite)
26
+ end
27
+
28
+ def compile(file, compiler=TestML::Compiler)
29
+ filename = file.sub(/(.*)\//, '')
30
+ runtime = TestML::Runtime.new({base: "test/#{$1}"})
31
+ testml = runtime.read_testml_file(filename)
32
+ ast1 = compiler.new.compile(testml)
33
+ got = YAML.dump(ast1)
34
+
35
+ yaml = File.read("test/ast/#{filename}") \
36
+ .gsub(/!!perl\/hash:/, '!ruby/object:') \
37
+ .gsub(/(explicit_call: )(\d)/) do |m|
38
+ "#{$1}#{($2 == '1') ? 'true' : 'false'}"
39
+ end
40
+ # .gsub(/^(\s*):(\w+:)/, "$1$2")
41
+
42
+ ast2 = YAML.load(yaml)
43
+ want = YAML.dump(ast2)
44
+
45
+ label = "#{file} - #{compiler.to_s}"
46
+ if got == want
47
+ assert_equal want, got, label
48
+ else
49
+ puts "Failed test: #{label}"
50
+ if want.match /\n/
51
+ File.open('/tmp/got', 'w') {|f| f.write got}
52
+ File.open('/tmp/want', 'w') {|f| f.write want}
53
+ puts `diff -u /tmp/want /tmp/got`
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,30 @@
1
+ require 'testml'
2
+ require 'testml/bridge'
3
+ require 'testml/util'
4
+ include TestML::Util
5
+
6
+ class Bridge < TestML::Bridge
7
+ def upper(string)
8
+ str string.value.upcase
9
+ end
10
+ end
11
+
12
+ TestML.new(
13
+ bridge: Bridge,
14
+ ).testml = <<'...'
15
+ %TestML 0.1.0
16
+
17
+ *foo.upper() == *bar
18
+
19
+ === Foo for thought
20
+ --- foo: o hai
21
+ --- bar: O HAI
22
+
23
+ === Bar the door
24
+ --- foo
25
+ o
26
+ Hai
27
+ --- bar
28
+ O
29
+ HAI
30
+ ...
data/test/inline.rb ADDED
@@ -0,0 +1,28 @@
1
+ $:.unshift "#{Dir.getwd}/test"
2
+
3
+ require 'testml'
4
+ require 'testml_bridge'
5
+
6
+ TestML.new(
7
+ bridge: TestMLBridge,
8
+ ).testml = <<'...'
9
+ %TestML 0.1.0
10
+
11
+ Title = "Ingy's Test";
12
+ Plan = 4;
13
+
14
+ *foo == *bar;
15
+ *bar == *foo;
16
+
17
+ === Foo for thought
18
+ --- foo: O HAI
19
+ --- bar: O HAI
20
+
21
+ === Bar the door
22
+ --- bar
23
+ O
24
+ HAI
25
+ --- foo
26
+ O
27
+ HAI
28
+ ...
data/test/strings.rb ADDED
@@ -0,0 +1,24 @@
1
+ require 'testml'
2
+
3
+ TestML.new.testml = <<'...'
4
+ %TestML 0.1.0
5
+
6
+ Plan = 6
7
+
8
+ Throw(*error).bogus().Catch() == *error
9
+ *error.Throw().bogus().Catch() == *error
10
+ Throw('My error message').Catch() == *error
11
+
12
+ *empty == "".Str
13
+ *empty == ""
14
+
15
+ Label = 'Simple string comparison'
16
+ "foo" == "foo"
17
+
18
+ === Throw/Catch
19
+ --- error: My error message
20
+
21
+ === Empty Point
22
+ --- empty
23
+
24
+ ...
data/test/testml.rb ADDED
@@ -0,0 +1,38 @@
1
+ require 'test/unit'
2
+ require 'testml'
3
+ require 'testml/compiler/pegex'
4
+ require 'testml/compiler/lite'
5
+ $:.unshift "#{Dir.getwd}/test"
6
+ require 'testml_bridge'
7
+
8
+ class TestMLTestCase < Test::Unit::TestCase
9
+ def run_testml_file(file, compiler=TestML::Compiler::Pegex)
10
+ TestML.new(
11
+ testml: file,
12
+ bridge: TestMLBridge,
13
+ compiler: compiler,
14
+ ).run(self)
15
+ end
16
+
17
+ (Dir.glob('test/testml/*.tml')
18
+ .select { |f| f !~ /external[12]/ }
19
+ .collect {|f| f.sub(/^test\//, '')}
20
+ ).each do |file|
21
+ method_name = 'test_' + file.gsub(/\W/, '_').sub(/_tml$/, '')
22
+ define_method(method_name.to_sym) do
23
+ run_testml_file(file)
24
+ end
25
+ end
26
+
27
+ %w(
28
+ testml/arguments.tml
29
+ testml/basic.tml
30
+ testml/exceptions.tml
31
+ testml/semicolons.tml
32
+ ).each do |file|
33
+ method_name = 'test_lite_' + file.gsub(/\W/, '_').sub(/_tml$/, '')
34
+ define_method(method_name.to_sym) do
35
+ run_testml_file(file, TestML::Compiler::Lite)
36
+ end
37
+ end
38
+ end