gisele-language 0.5.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.
- data/CHANGELOG.md +5 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +26 -0
- data/LICENCE.md +22 -0
- data/Manifest.txt +13 -0
- data/README.md +7 -0
- data/Rakefile +11 -0
- data/gisele-language.gemspec +188 -0
- data/gisele-language.noespec +24 -0
- data/lib/gisele/language/ast/bool_and.rb +14 -0
- data/lib/gisele/language/ast/bool_expr.rb +22 -0
- data/lib/gisele/language/ast/bool_not.rb +14 -0
- data/lib/gisele/language/ast/bool_or.rb +14 -0
- data/lib/gisele/language/ast/case_st.rb +14 -0
- data/lib/gisele/language/ast/else_clause.rb +14 -0
- data/lib/gisele/language/ast/elsif_clause.rb +14 -0
- data/lib/gisele/language/ast/if_st.rb +14 -0
- data/lib/gisele/language/ast/node.rb +35 -0
- data/lib/gisele/language/ast/task_call_st.rb +14 -0
- data/lib/gisele/language/ast/var_ref.rb +14 -0
- data/lib/gisele/language/ast/when_clause.rb +14 -0
- data/lib/gisele/language/ast/while_st.rb +14 -0
- data/lib/gisele/language/grammar.citrus +236 -0
- data/lib/gisele/language/grammar.sexp.yml +83 -0
- data/lib/gisele/language/processors/elsif_flattener.rb +36 -0
- data/lib/gisele/language/processors/if_to_case.rb +65 -0
- data/lib/gisele/language/processors/scoping_helper.rb +32 -0
- data/lib/gisele/language/processors/sugar_removal.rb +17 -0
- data/lib/gisele/language/processors.rb +4 -0
- data/lib/gisele/language/syntax/bool_and.rb +14 -0
- data/lib/gisele/language/syntax/bool_expr.rb +14 -0
- data/lib/gisele/language/syntax/bool_lit.rb +14 -0
- data/lib/gisele/language/syntax/bool_not.rb +14 -0
- data/lib/gisele/language/syntax/bool_or.rb +14 -0
- data/lib/gisele/language/syntax/bool_paren.rb +14 -0
- data/lib/gisele/language/syntax/case_st.rb +19 -0
- data/lib/gisele/language/syntax/else_clause.rb +14 -0
- data/lib/gisele/language/syntax/elsif_clause.rb +16 -0
- data/lib/gisele/language/syntax/event_set.rb +15 -0
- data/lib/gisele/language/syntax/fluent_def.rb +18 -0
- data/lib/gisele/language/syntax/if_st.rb +18 -0
- data/lib/gisele/language/syntax/implicit_seq_st.rb +16 -0
- data/lib/gisele/language/syntax/node.rb +40 -0
- data/lib/gisele/language/syntax/par_st.rb +14 -0
- data/lib/gisele/language/syntax/seq_st.rb +14 -0
- data/lib/gisele/language/syntax/st_list.rb +14 -0
- data/lib/gisele/language/syntax/task_call_st.rb +14 -0
- data/lib/gisele/language/syntax/task_def.rb +18 -0
- data/lib/gisele/language/syntax/trackvar_def.rb +19 -0
- data/lib/gisele/language/syntax/unit_def.rb +14 -0
- data/lib/gisele/language/syntax/var_ref.rb +14 -0
- data/lib/gisele/language/syntax/when_clause.rb +16 -0
- data/lib/gisele/language/syntax/while_st.rb +16 -0
- data/lib/gisele/language.rb +31 -0
- data/lib/gisele-language/loader.rb +3 -0
- data/lib/gisele-language/version.rb +16 -0
- data/lib/gisele-language.rb +19 -0
- data/spec/fixtures/tasks/complete.gis +40 -0
- data/spec/fixtures/tasks/simple.ast +51 -0
- data/spec/fixtures/tasks/simple.gis +16 -0
- data/spec/language/ast/test_bool_expr.rb +50 -0
- data/spec/language/grammar_sexp/test_case_st.rb +20 -0
- data/spec/language/grammar_sexp/test_event_set.rb +14 -0
- data/spec/language/grammar_sexp/test_fluent_def.rb +18 -0
- data/spec/language/grammar_sexp/test_initially.rb +18 -0
- data/spec/language/grammar_sexp/test_nop_st.rb +10 -0
- data/spec/language/grammar_sexp/test_when_clause.rb +12 -0
- data/spec/language/processors/test_elsif_flattener.rb +94 -0
- data/spec/language/processors/test_if_to_case.rb +105 -0
- data/spec/language/processors/test_scoping_helper.rb +45 -0
- data/spec/language/syntax/grammar/test_bool_expr.rb +34 -0
- data/spec/language/syntax/grammar/test_boolean_literal.rb +17 -0
- data/spec/language/syntax/grammar/test_case_st.rb +60 -0
- data/spec/language/syntax/grammar/test_event.rb +18 -0
- data/spec/language/syntax/grammar/test_event_name.rb +21 -0
- data/spec/language/syntax/grammar/test_event_set.rb +26 -0
- data/spec/language/syntax/grammar/test_fluent_def.rb +21 -0
- data/spec/language/syntax/grammar/test_if_st.rb +21 -0
- data/spec/language/syntax/grammar/test_par_st.rb +11 -0
- data/spec/language/syntax/grammar/test_process_statement.rb +19 -0
- data/spec/language/syntax/grammar/test_seq_st.rb +11 -0
- data/spec/language/syntax/grammar/test_spaces.rb +19 -0
- data/spec/language/syntax/grammar/test_spacing.rb +17 -0
- data/spec/language/syntax/grammar/test_task_def.rb +35 -0
- data/spec/language/syntax/grammar/test_task_name.rb +19 -0
- data/spec/language/syntax/grammar/test_task_start_or_end.rb +17 -0
- data/spec/language/syntax/grammar/test_trackvar_def.rb +21 -0
- data/spec/language/syntax/grammar/test_unit_def.rb +29 -0
- data/spec/language/syntax/grammar/test_variable_name.rb +51 -0
- data/spec/language/syntax/grammar/test_when_clause.rb +21 -0
- data/spec/language/syntax/grammar/test_while_st.rb +11 -0
- data/spec/language/syntax/to_ast/test_bool_expr.rb +32 -0
- data/spec/language/syntax/to_ast/test_case_st.rb +47 -0
- data/spec/language/syntax/to_ast/test_else_clause.rb +13 -0
- data/spec/language/syntax/to_ast/test_elsif_clause.rb +15 -0
- data/spec/language/syntax/to_ast/test_event_set.rb +24 -0
- data/spec/language/syntax/to_ast/test_fluent_def.rb +26 -0
- data/spec/language/syntax/to_ast/test_if_st.rb +39 -0
- data/spec/language/syntax/to_ast/test_par_st.rb +12 -0
- data/spec/language/syntax/to_ast/test_seq_st.rb +12 -0
- data/spec/language/syntax/to_ast/test_task_call_st.rb +10 -0
- data/spec/language/syntax/to_ast/test_task_def.rb +44 -0
- data/spec/language/syntax/to_ast/test_trackvar_def.rb +26 -0
- data/spec/language/syntax/to_ast/test_unit_def.rb +28 -0
- data/spec/language/syntax/to_ast/test_var_ref.rb +12 -0
- data/spec/language/syntax/to_ast/test_when_clause.rb +15 -0
- data/spec/language/syntax/to_ast/test_while_st.rb +24 -0
- data/spec/language/test_syntax.rb +51 -0
- data/spec/spec_helper.rb +44 -0
- data/spec/test_gisele-language.rb +8 -0
- data/tasks/gem.rake +73 -0
- data/tasks/spec_test.rake +71 -0
- metadata +269 -0
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe IfToCase do
|
|
4
|
+
|
|
5
|
+
def ast(source)
|
|
6
|
+
Gisele.ast(Gisele.parse(source.strip, :root => :if_st))
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def rewrite(ast)
|
|
10
|
+
@rewrited = IfToCase.call(ast)
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
after{
|
|
14
|
+
(sexp_grammar[:case_st] === @rewrited).should be_true
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
it 'rewrites single if correctly' do
|
|
18
|
+
source = ast("if goodCond Task1 end")
|
|
19
|
+
expected = \
|
|
20
|
+
[:case_st, nil,
|
|
21
|
+
[:when_clause,
|
|
22
|
+
[:bool_expr, [:var_ref, "goodCond"]],
|
|
23
|
+
[:task_call_st, "Task1"] ]]
|
|
24
|
+
rewrite(source).should eq(expected)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
it 'negates the else clause' do
|
|
28
|
+
source = ast("if goodCond Task1 else Task2 end")
|
|
29
|
+
expected = \
|
|
30
|
+
[:case_st, nil,
|
|
31
|
+
[:when_clause,
|
|
32
|
+
[:bool_expr, [:var_ref, "goodCond"]],
|
|
33
|
+
[:task_call_st, "Task1"] ],
|
|
34
|
+
[:when_clause,
|
|
35
|
+
[:bool_expr, [:bool_not, [:var_ref, "goodCond"]]],
|
|
36
|
+
[:task_call_st, "Task2"] ]
|
|
37
|
+
]
|
|
38
|
+
rewrite(source).should eq(expected)
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
it 'handles elsif clauses correctly' do
|
|
42
|
+
source = ast(<<-IF)
|
|
43
|
+
if c1 Task1
|
|
44
|
+
elsif c2 Task2
|
|
45
|
+
elsif c3 Task3
|
|
46
|
+
else Task4
|
|
47
|
+
end
|
|
48
|
+
IF
|
|
49
|
+
expected = \
|
|
50
|
+
[:case_st, nil,
|
|
51
|
+
[:when_clause,
|
|
52
|
+
[:bool_expr, [:var_ref, "c1"]],
|
|
53
|
+
[:task_call_st, "Task1"] ],
|
|
54
|
+
[:when_clause,
|
|
55
|
+
[:bool_expr, [:bool_and,
|
|
56
|
+
[:var_ref, "c2"],
|
|
57
|
+
[:bool_not, [:var_ref, "c1"]] ]],
|
|
58
|
+
[:task_call_st, "Task2"] ],
|
|
59
|
+
[:when_clause,
|
|
60
|
+
[:bool_expr, [:bool_and,
|
|
61
|
+
[:var_ref, "c3"],
|
|
62
|
+
[:bool_and,
|
|
63
|
+
[:bool_not, [:var_ref, "c2"]],
|
|
64
|
+
[:bool_not, [:var_ref, "c1"]] ]]],
|
|
65
|
+
[:task_call_st, "Task3"] ],
|
|
66
|
+
[:when_clause,
|
|
67
|
+
[:bool_expr, [:bool_and,
|
|
68
|
+
[:bool_not, [:var_ref, "c3"]],
|
|
69
|
+
[:bool_and,
|
|
70
|
+
[:bool_not, [:var_ref, "c2"]],
|
|
71
|
+
[:bool_not, [:var_ref, "c1"]]]]],
|
|
72
|
+
[:task_call_st, "Task4"] ],
|
|
73
|
+
]
|
|
74
|
+
rewrite(source).should eq(expected)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
it 'avoids double negations' do
|
|
78
|
+
source = ast("if not(goodCond) Task1 else Task2 end")
|
|
79
|
+
expected = \
|
|
80
|
+
[:case_st, nil,
|
|
81
|
+
[:when_clause,
|
|
82
|
+
[:bool_expr, [:bool_not, [:var_ref, "goodCond"]]],
|
|
83
|
+
[:task_call_st, "Task1"] ],
|
|
84
|
+
[:when_clause,
|
|
85
|
+
[:bool_expr, [:var_ref, "goodCond"]],
|
|
86
|
+
[:task_call_st, "Task2"] ] ]
|
|
87
|
+
rewrite(source).should eq(expected)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
it 'keeps traceability markers on a single if' do
|
|
91
|
+
if_st = ast("if goodCond Task1 end")
|
|
92
|
+
rw_st = rewrite(if_st)
|
|
93
|
+
rw_st.tracking_markers.should eq(if_st.tracking_markers)
|
|
94
|
+
rw_st.last.tracking_markers.should eq(if_st.tracking_markers)
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
it 'keeps traceability markers when a else if present' do
|
|
98
|
+
if_st = ast("if goodCond Task1 else Task2 end")
|
|
99
|
+
rw_st = rewrite(if_st)
|
|
100
|
+
rw_st.tracking_markers.should eq(if_st.tracking_markers)
|
|
101
|
+
rw_st.last.tracking_markers.should eq(if_st.last.tracking_markers)
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
end
|
|
105
|
+
end
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe ScopingHelper do
|
|
4
|
+
|
|
5
|
+
let(:rw_class) do
|
|
6
|
+
Class.new(Sexpr::Rewriter) do
|
|
7
|
+
grammar Gisele::Language
|
|
8
|
+
helper ScopingHelper
|
|
9
|
+
|
|
10
|
+
def on_hello(node)
|
|
11
|
+
scope_stack.dup
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def on_missing(node)
|
|
15
|
+
call(node.sexpr_body.last)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
let(:rw){ rw_class.new }
|
|
21
|
+
|
|
22
|
+
it 'installs the methods on the rewriter' do
|
|
23
|
+
rw.respond_to?(:scope_stack).should be_true
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
it 'does nothing special on non _def nodes' do
|
|
27
|
+
node = [:hello, "world"]
|
|
28
|
+
rw.call(node).should eq([])
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
it 'keeps _def nodes as successive scopes' do
|
|
32
|
+
second = [:task_def, [:hello]]
|
|
33
|
+
first = [:task_def, second]
|
|
34
|
+
rw.call(first).should eq([first, second])
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'pops scopes when returning along the stack' do
|
|
38
|
+
second = [:task_def, [:hello]]
|
|
39
|
+
first = [:task_def, second]
|
|
40
|
+
rw.call(first)
|
|
41
|
+
rw.scope_stack.should eq([])
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
end
|
|
45
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe Grammar, 'bool_expr' do
|
|
4
|
+
|
|
5
|
+
it 'parses single variable references' do
|
|
6
|
+
parse('diagKnown', :bool_expr).should eq('diagKnown')
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
it 'parses boolean literals' do
|
|
10
|
+
parse('true', :bool_expr).should eq('true')
|
|
11
|
+
parse('false', :bool_expr).should eq('false')
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'parses negated expression' do
|
|
15
|
+
parse('not diagKnown', :bool_expr).should eq('not diagKnown')
|
|
16
|
+
parse('not true', :bool_expr).should eq('not true')
|
|
17
|
+
parse('not false', :bool_expr).should eq('not false')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'parses or expressions' do
|
|
21
|
+
parse('diagKnown or platLow', :bool_expr).should eq('diagKnown or platLow')
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it 'parses and expressions' do
|
|
25
|
+
parse('diagKnown and platLow', :bool_expr).should eq('diagKnown and platLow')
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
it 'parses complex expressions' do
|
|
29
|
+
expr = 'diagKnown and (platLow or not(metastased and mplus))'
|
|
30
|
+
parse(expr, :bool_expr).should eq(expr)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe Grammar, 'boolean_literal' do
|
|
4
|
+
|
|
5
|
+
it 'parses booleans' do
|
|
6
|
+
parse('true', :boolean_literal).should eq('true')
|
|
7
|
+
parse('false', :boolean_literal).should eq('false')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'does not parses integers' do
|
|
11
|
+
lambda{
|
|
12
|
+
parse('0', :boolean_literal)
|
|
13
|
+
}.should raise_error(Citrus::ParseError)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe Grammar, 'case_st' do
|
|
4
|
+
|
|
5
|
+
it 'supports a single when clause' do
|
|
6
|
+
expr = <<-CASE_ST.strip
|
|
7
|
+
case
|
|
8
|
+
when goodCond
|
|
9
|
+
Task1
|
|
10
|
+
end
|
|
11
|
+
CASE_ST
|
|
12
|
+
parse(expr, :case_st).should eq(expr)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'supports boolean expressions in when clauses' do
|
|
16
|
+
expr = <<-CASE_ST.strip
|
|
17
|
+
case
|
|
18
|
+
when not(goodCond) or badCond
|
|
19
|
+
Task1
|
|
20
|
+
end
|
|
21
|
+
CASE_ST
|
|
22
|
+
parse(expr, :case_st).should eq(expr)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
it 'supports a multiple when clauses' do
|
|
26
|
+
expr = <<-CASE_ST.strip
|
|
27
|
+
case
|
|
28
|
+
when goodCond
|
|
29
|
+
Task1
|
|
30
|
+
when badCond
|
|
31
|
+
Task2
|
|
32
|
+
end
|
|
33
|
+
CASE_ST
|
|
34
|
+
parse(expr, :case_st).should eq(expr)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
it 'supports an else clause' do
|
|
38
|
+
expr = <<-CASE_ST.strip
|
|
39
|
+
case
|
|
40
|
+
when goodCond
|
|
41
|
+
Task1
|
|
42
|
+
else
|
|
43
|
+
Task2
|
|
44
|
+
end
|
|
45
|
+
CASE_ST
|
|
46
|
+
parse(expr, :case_st).should eq(expr)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
it 'supports an optional variable name' do
|
|
50
|
+
expr = <<-CASE_ST.strip
|
|
51
|
+
case someVariable
|
|
52
|
+
when goodCond
|
|
53
|
+
Task1
|
|
54
|
+
end
|
|
55
|
+
CASE_ST
|
|
56
|
+
parse(expr, :case_st).should eq(expr)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
|
60
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe Grammar, 'event' do
|
|
4
|
+
|
|
5
|
+
it 'parses correct events' do
|
|
6
|
+
parse('Task:start', :event).should eq('Task:start')
|
|
7
|
+
parse('Task:end', :event).should eq('Task:end')
|
|
8
|
+
parse('an_event', :event).should eq('an_event')
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it 'raises on invalid event names' do
|
|
12
|
+
lambda{
|
|
13
|
+
parse('Task', :event)
|
|
14
|
+
}.should raise_error(Citrus::ParseError)
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe Grammar, 'event_name' do
|
|
4
|
+
|
|
5
|
+
it 'parses correct event names' do
|
|
6
|
+
parse('a', :event_name).should eq('a')
|
|
7
|
+
parse('event', :event_name).should eq('event')
|
|
8
|
+
parse('event_name', :event_name).should eq('event_name')
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
it 'raises on invalid variable names' do
|
|
12
|
+
lambda{
|
|
13
|
+
parse('NotAnEventName', :event_name)
|
|
14
|
+
}.should raise_error(Citrus::ParseError)
|
|
15
|
+
lambda{
|
|
16
|
+
parse('notAnEventName', :event_name)
|
|
17
|
+
}.should raise_error(Citrus::ParseError)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe Grammar, 'event_set' do
|
|
4
|
+
|
|
5
|
+
it 'parses empty sets' do
|
|
6
|
+
parse('{}', :event_set).should eq('{}')
|
|
7
|
+
parse('{ }', :event_set).should eq('{ }')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'parses event singletons' do
|
|
11
|
+
parse('{Task:start}', :event_set).should eq('{Task:start}')
|
|
12
|
+
parse('{ Task:start }', :event_set).should eq('{ Task:start }')
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'parses event sets' do
|
|
16
|
+
parse('{Task:start, Task:end}', :event_set).should eq('{Task:start, Task:end}')
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
it 'recognizes invalid events in the set' do
|
|
20
|
+
lambda{
|
|
21
|
+
parse('{Task:start, NotAnEvent}', :event_set)
|
|
22
|
+
}.should raise_error(Citrus::ParseError)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe Grammar, 'fluent_def' do
|
|
4
|
+
|
|
5
|
+
it 'parses valid fluent definitions' do
|
|
6
|
+
defn = 'fluent diagKnown {Diagnosis:start}, {Treatment:end} initially false'
|
|
7
|
+
parse(defn, :fluent_def).should eq(defn)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'supports a missing initial value' do
|
|
11
|
+
defn = 'fluent diagKnown {Diagnosis:start}, {Treatment:end}'
|
|
12
|
+
parse(defn, :fluent_def).should eq(defn)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'supports empty sets for events' do
|
|
16
|
+
defn = 'fluent diagKnown {}, {} initially true'
|
|
17
|
+
parse(defn, :fluent_def).should eq(defn)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe Grammar, 'if_st' do
|
|
4
|
+
|
|
5
|
+
it 'parses a single if statement' do
|
|
6
|
+
expr = 'if goodCond Task end'
|
|
7
|
+
parse(expr, :if_st).should eq(expr)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'supports an optional else' do
|
|
11
|
+
expr = 'if goodCond GoodTask else BadTask end'
|
|
12
|
+
parse(expr, :if_st).should eq(expr)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'supports an optional elsif clauses' do
|
|
16
|
+
expr = 'if goodCond GoodTask elsif otherCond OtherTask elsif yetAnother BadTask end'
|
|
17
|
+
parse(expr, :if_st).should eq(expr)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe Grammar, 'process_statement' do
|
|
4
|
+
|
|
5
|
+
it 'parses a simple process statement' do
|
|
6
|
+
expr = <<-PROCESS.strip
|
|
7
|
+
DoSomething
|
|
8
|
+
if goodCond
|
|
9
|
+
DoForGood
|
|
10
|
+
else
|
|
11
|
+
DoForBad
|
|
12
|
+
end
|
|
13
|
+
CleanDesk
|
|
14
|
+
PROCESS
|
|
15
|
+
parse(expr, :process_statement).should eq(expr)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe Grammar, 'spaces' do
|
|
4
|
+
|
|
5
|
+
it 'parses all kind of spaces' do
|
|
6
|
+
parse(' ', :spaces).should eq(' ')
|
|
7
|
+
parse("\t", :spaces).should eq("\t")
|
|
8
|
+
parse("\n", :spaces).should eq("\n")
|
|
9
|
+
parse(" \t\n", :spaces).should eq(" \t\n")
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'enforces mandatory spacing' do
|
|
13
|
+
lambda{
|
|
14
|
+
parse('', :spaces)
|
|
15
|
+
}.should raise_error(Citrus::ParseError)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe Grammar, 'spacing' do
|
|
4
|
+
|
|
5
|
+
it 'parses all kind of spaces' do
|
|
6
|
+
parse(' ', :spacing).should eq(' ')
|
|
7
|
+
parse("\t", :spacing).should eq("\t")
|
|
8
|
+
parse("\n", :spacing).should eq("\n")
|
|
9
|
+
parse(" \t\n", :spacing).should eq(" \t\n")
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'does not enforces mandatory spacing' do
|
|
13
|
+
parse('', :spacing).should eq('')
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe Grammar, 'task_def' do
|
|
4
|
+
|
|
5
|
+
it 'parses a simple implicit task definition' do
|
|
6
|
+
taskdef = <<-TASKDEF.strip
|
|
7
|
+
task Process
|
|
8
|
+
Diagnosis
|
|
9
|
+
end
|
|
10
|
+
TASKDEF
|
|
11
|
+
parse(taskdef, :task_def).should eq(taskdef)
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
it 'allows any statement' do
|
|
15
|
+
taskdef = <<-TASKDEF.strip
|
|
16
|
+
task Process
|
|
17
|
+
while true Diagnosis end
|
|
18
|
+
end
|
|
19
|
+
TASKDEF
|
|
20
|
+
parse(taskdef, :task_def).should eq(taskdef)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
it 'supports optional variable definitions in the signature' do
|
|
24
|
+
taskdef = <<-TASKDEF.strip
|
|
25
|
+
task Process
|
|
26
|
+
fluent diagKnown {Diagnosis:start}, {} initially false
|
|
27
|
+
trackvar mplus {Diagnosis:end}
|
|
28
|
+
Diagnosis
|
|
29
|
+
end
|
|
30
|
+
TASKDEF
|
|
31
|
+
parse(taskdef, :task_def).should eq(taskdef)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe Grammar,'task_name' do
|
|
4
|
+
|
|
5
|
+
it 'parses correct task names' do
|
|
6
|
+
parse('A', :task_name).should eq('A')
|
|
7
|
+
parse('Diagnosis', :task_name).should eq('Diagnosis')
|
|
8
|
+
parse('TaskName', :task_name).should eq('TaskName')
|
|
9
|
+
parse('Task_Name', :task_name).should eq('Task_Name')
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'raises on invalid task names' do
|
|
13
|
+
lambda{
|
|
14
|
+
parse('not_a_task_name', :task_name)
|
|
15
|
+
}.should raise_error(Citrus::ParseError)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
end
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe Grammar, 'task_start_or_end' do
|
|
4
|
+
|
|
5
|
+
it 'parses correct event names' do
|
|
6
|
+
parse('Task:start', :task_start_or_end).should eq('Task:start')
|
|
7
|
+
parse('Task:end', :task_start_or_end).should eq('Task:end')
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'raises on simple task names' do
|
|
11
|
+
lambda{
|
|
12
|
+
parse('Task', :task_start_or_end)
|
|
13
|
+
}.should raise_error(Citrus::ParseError)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe Grammar, 'trackvar_def' do
|
|
4
|
+
|
|
5
|
+
it 'parses valid tracking variable definitions' do
|
|
6
|
+
defn = 'trackvar plateletLow {BloodTest:end}'
|
|
7
|
+
parse(defn, :trackvar_def).should eq(defn)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'supports an optional initial value' do
|
|
11
|
+
defn = 'trackvar plateletLow {BloodTest:end} initially false'
|
|
12
|
+
parse(defn, :trackvar_def).should eq(defn)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'supports optional obsolete events' do
|
|
16
|
+
defn = 'trackvar plateletLow {BloodTest:end}, {Chemotherapy:end}'
|
|
17
|
+
parse(defn, :trackvar_def).should eq(defn)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe Grammar, 'unit' do
|
|
4
|
+
|
|
5
|
+
it 'parses a single task definition' do
|
|
6
|
+
expr = <<-UNIT.strip
|
|
7
|
+
task Task1 end
|
|
8
|
+
UNIT
|
|
9
|
+
parse(expr, :unit_def).should eq(expr)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it 'accepts multiple task definitions' do
|
|
13
|
+
expr = <<-UNIT.strip
|
|
14
|
+
task Task1 end
|
|
15
|
+
task Task2 end
|
|
16
|
+
UNIT
|
|
17
|
+
parse(expr, :unit_def).should eq(expr)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'allows trailing spaces' do
|
|
21
|
+
expr = <<-UNIT
|
|
22
|
+
task Task1 end
|
|
23
|
+
task Task2 end
|
|
24
|
+
UNIT
|
|
25
|
+
parse(expr, :unit_def).should eq(expr)
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
end
|
|
29
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe Grammar, 'variable_name' do
|
|
4
|
+
|
|
5
|
+
RESERVED_WORDS = [
|
|
6
|
+
"if",
|
|
7
|
+
"else",
|
|
8
|
+
"elsif",
|
|
9
|
+
"when",
|
|
10
|
+
"while",
|
|
11
|
+
"seq",
|
|
12
|
+
"par",
|
|
13
|
+
"task",
|
|
14
|
+
"refinement",
|
|
15
|
+
"fluent",
|
|
16
|
+
"trackvar",
|
|
17
|
+
"initially",
|
|
18
|
+
"end",
|
|
19
|
+
"not",
|
|
20
|
+
"or",
|
|
21
|
+
"and",
|
|
22
|
+
"true",
|
|
23
|
+
"false"
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
it 'parses correct variable names' do
|
|
27
|
+
parse('a', :variable_name).should eq('a')
|
|
28
|
+
parse('diagnosis', :variable_name).should eq('diagnosis')
|
|
29
|
+
parse('varName', :variable_name).should eq('varName')
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
it 'does not allow reserved words' do
|
|
33
|
+
RESERVED_WORDS.each do |word|
|
|
34
|
+
lambda{
|
|
35
|
+
parse(word.to_s + " ", :variable_name)
|
|
36
|
+
}.should raise_error(Citrus::ParseError)
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
it 'allows a reserved word as prefix' do
|
|
41
|
+
parse('ifSomething', :variable_name).should eq('ifSomething')
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
it 'raises on invalid variable names' do
|
|
45
|
+
lambda{
|
|
46
|
+
parse('NotAVarName', :variable_name)
|
|
47
|
+
}.should raise_error(Citrus::ParseError)
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
require 'spec_helper'
|
|
2
|
+
module Gisele::Language
|
|
3
|
+
describe Grammar, 'when_clause' do
|
|
4
|
+
|
|
5
|
+
it 'parses a single when clause statement' do
|
|
6
|
+
expr = 'when goodCond Task'
|
|
7
|
+
parse(expr, :when_clause).should eq(expr)
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
it 'supports a boolean expression' do
|
|
11
|
+
expr = 'when not(goodCond and badCond) Task'
|
|
12
|
+
parse(expr, :when_clause).should eq(expr)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
it 'supports an complex process statement' do
|
|
16
|
+
expr = 'when goodCond Task1 par Task2 Task3 end'
|
|
17
|
+
parse(expr, :when_clause).should eq(expr)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|