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.
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