gisele-language 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. data/CHANGELOG.md +5 -0
  2. data/Gemfile +12 -0
  3. data/Gemfile.lock +26 -0
  4. data/LICENCE.md +22 -0
  5. data/Manifest.txt +13 -0
  6. data/README.md +7 -0
  7. data/Rakefile +11 -0
  8. data/gisele-language.gemspec +188 -0
  9. data/gisele-language.noespec +24 -0
  10. data/lib/gisele/language/ast/bool_and.rb +14 -0
  11. data/lib/gisele/language/ast/bool_expr.rb +22 -0
  12. data/lib/gisele/language/ast/bool_not.rb +14 -0
  13. data/lib/gisele/language/ast/bool_or.rb +14 -0
  14. data/lib/gisele/language/ast/case_st.rb +14 -0
  15. data/lib/gisele/language/ast/else_clause.rb +14 -0
  16. data/lib/gisele/language/ast/elsif_clause.rb +14 -0
  17. data/lib/gisele/language/ast/if_st.rb +14 -0
  18. data/lib/gisele/language/ast/node.rb +35 -0
  19. data/lib/gisele/language/ast/task_call_st.rb +14 -0
  20. data/lib/gisele/language/ast/var_ref.rb +14 -0
  21. data/lib/gisele/language/ast/when_clause.rb +14 -0
  22. data/lib/gisele/language/ast/while_st.rb +14 -0
  23. data/lib/gisele/language/grammar.citrus +236 -0
  24. data/lib/gisele/language/grammar.sexp.yml +83 -0
  25. data/lib/gisele/language/processors/elsif_flattener.rb +36 -0
  26. data/lib/gisele/language/processors/if_to_case.rb +65 -0
  27. data/lib/gisele/language/processors/scoping_helper.rb +32 -0
  28. data/lib/gisele/language/processors/sugar_removal.rb +17 -0
  29. data/lib/gisele/language/processors.rb +4 -0
  30. data/lib/gisele/language/syntax/bool_and.rb +14 -0
  31. data/lib/gisele/language/syntax/bool_expr.rb +14 -0
  32. data/lib/gisele/language/syntax/bool_lit.rb +14 -0
  33. data/lib/gisele/language/syntax/bool_not.rb +14 -0
  34. data/lib/gisele/language/syntax/bool_or.rb +14 -0
  35. data/lib/gisele/language/syntax/bool_paren.rb +14 -0
  36. data/lib/gisele/language/syntax/case_st.rb +19 -0
  37. data/lib/gisele/language/syntax/else_clause.rb +14 -0
  38. data/lib/gisele/language/syntax/elsif_clause.rb +16 -0
  39. data/lib/gisele/language/syntax/event_set.rb +15 -0
  40. data/lib/gisele/language/syntax/fluent_def.rb +18 -0
  41. data/lib/gisele/language/syntax/if_st.rb +18 -0
  42. data/lib/gisele/language/syntax/implicit_seq_st.rb +16 -0
  43. data/lib/gisele/language/syntax/node.rb +40 -0
  44. data/lib/gisele/language/syntax/par_st.rb +14 -0
  45. data/lib/gisele/language/syntax/seq_st.rb +14 -0
  46. data/lib/gisele/language/syntax/st_list.rb +14 -0
  47. data/lib/gisele/language/syntax/task_call_st.rb +14 -0
  48. data/lib/gisele/language/syntax/task_def.rb +18 -0
  49. data/lib/gisele/language/syntax/trackvar_def.rb +19 -0
  50. data/lib/gisele/language/syntax/unit_def.rb +14 -0
  51. data/lib/gisele/language/syntax/var_ref.rb +14 -0
  52. data/lib/gisele/language/syntax/when_clause.rb +16 -0
  53. data/lib/gisele/language/syntax/while_st.rb +16 -0
  54. data/lib/gisele/language.rb +31 -0
  55. data/lib/gisele-language/loader.rb +3 -0
  56. data/lib/gisele-language/version.rb +16 -0
  57. data/lib/gisele-language.rb +19 -0
  58. data/spec/fixtures/tasks/complete.gis +40 -0
  59. data/spec/fixtures/tasks/simple.ast +51 -0
  60. data/spec/fixtures/tasks/simple.gis +16 -0
  61. data/spec/language/ast/test_bool_expr.rb +50 -0
  62. data/spec/language/grammar_sexp/test_case_st.rb +20 -0
  63. data/spec/language/grammar_sexp/test_event_set.rb +14 -0
  64. data/spec/language/grammar_sexp/test_fluent_def.rb +18 -0
  65. data/spec/language/grammar_sexp/test_initially.rb +18 -0
  66. data/spec/language/grammar_sexp/test_nop_st.rb +10 -0
  67. data/spec/language/grammar_sexp/test_when_clause.rb +12 -0
  68. data/spec/language/processors/test_elsif_flattener.rb +94 -0
  69. data/spec/language/processors/test_if_to_case.rb +105 -0
  70. data/spec/language/processors/test_scoping_helper.rb +45 -0
  71. data/spec/language/syntax/grammar/test_bool_expr.rb +34 -0
  72. data/spec/language/syntax/grammar/test_boolean_literal.rb +17 -0
  73. data/spec/language/syntax/grammar/test_case_st.rb +60 -0
  74. data/spec/language/syntax/grammar/test_event.rb +18 -0
  75. data/spec/language/syntax/grammar/test_event_name.rb +21 -0
  76. data/spec/language/syntax/grammar/test_event_set.rb +26 -0
  77. data/spec/language/syntax/grammar/test_fluent_def.rb +21 -0
  78. data/spec/language/syntax/grammar/test_if_st.rb +21 -0
  79. data/spec/language/syntax/grammar/test_par_st.rb +11 -0
  80. data/spec/language/syntax/grammar/test_process_statement.rb +19 -0
  81. data/spec/language/syntax/grammar/test_seq_st.rb +11 -0
  82. data/spec/language/syntax/grammar/test_spaces.rb +19 -0
  83. data/spec/language/syntax/grammar/test_spacing.rb +17 -0
  84. data/spec/language/syntax/grammar/test_task_def.rb +35 -0
  85. data/spec/language/syntax/grammar/test_task_name.rb +19 -0
  86. data/spec/language/syntax/grammar/test_task_start_or_end.rb +17 -0
  87. data/spec/language/syntax/grammar/test_trackvar_def.rb +21 -0
  88. data/spec/language/syntax/grammar/test_unit_def.rb +29 -0
  89. data/spec/language/syntax/grammar/test_variable_name.rb +51 -0
  90. data/spec/language/syntax/grammar/test_when_clause.rb +21 -0
  91. data/spec/language/syntax/grammar/test_while_st.rb +11 -0
  92. data/spec/language/syntax/to_ast/test_bool_expr.rb +32 -0
  93. data/spec/language/syntax/to_ast/test_case_st.rb +47 -0
  94. data/spec/language/syntax/to_ast/test_else_clause.rb +13 -0
  95. data/spec/language/syntax/to_ast/test_elsif_clause.rb +15 -0
  96. data/spec/language/syntax/to_ast/test_event_set.rb +24 -0
  97. data/spec/language/syntax/to_ast/test_fluent_def.rb +26 -0
  98. data/spec/language/syntax/to_ast/test_if_st.rb +39 -0
  99. data/spec/language/syntax/to_ast/test_par_st.rb +12 -0
  100. data/spec/language/syntax/to_ast/test_seq_st.rb +12 -0
  101. data/spec/language/syntax/to_ast/test_task_call_st.rb +10 -0
  102. data/spec/language/syntax/to_ast/test_task_def.rb +44 -0
  103. data/spec/language/syntax/to_ast/test_trackvar_def.rb +26 -0
  104. data/spec/language/syntax/to_ast/test_unit_def.rb +28 -0
  105. data/spec/language/syntax/to_ast/test_var_ref.rb +12 -0
  106. data/spec/language/syntax/to_ast/test_when_clause.rb +15 -0
  107. data/spec/language/syntax/to_ast/test_while_st.rb +24 -0
  108. data/spec/language/test_syntax.rb +51 -0
  109. data/spec/spec_helper.rb +44 -0
  110. data/spec/test_gisele-language.rb +8 -0
  111. data/tasks/gem.rake +73 -0
  112. data/tasks/spec_test.rake +71 -0
  113. 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,11 @@
1
+ require 'spec_helper'
2
+ module Gisele::Language
3
+ describe Grammar, 'par_st' do
4
+
5
+ it 'parses a single parallel statement' do
6
+ expr = 'par Task1 Task2 end'
7
+ parse(expr, :par_st).should eq(expr)
8
+ end
9
+
10
+ end
11
+ 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,11 @@
1
+ require 'spec_helper'
2
+ module Gisele::Language
3
+ describe Grammar, 'seq_st' do
4
+
5
+ it 'parses a single sequence statement' do
6
+ expr = 'seq Task1 Task2 end'
7
+ parse(expr, :seq_st).should eq(expr)
8
+ end
9
+
10
+ end
11
+ 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
@@ -0,0 +1,11 @@
1
+ require 'spec_helper'
2
+ module Gisele::Language
3
+ describe Grammar, 'while_st' do
4
+
5
+ it 'parses a single while statement' do
6
+ expr = 'while badCond Task end'
7
+ parse(expr, :while_st).should eq(expr)
8
+ end
9
+
10
+ end
11
+ end