adsl 0.0.3 → 0.1.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.
- checksums.yaml +4 -4
- data/Gemfile +2 -20
- data/README.md +14 -21
- data/bin/adsl-verify +8 -8
- data/lib/adsl.rb +3 -0
- data/lib/adsl/adsl.rb +3 -0
- data/lib/adsl/ds/data_store_spec.rb +339 -0
- data/lib/adsl/extract/instrumenter.rb +206 -0
- data/lib/adsl/extract/meta.rb +33 -0
- data/lib/adsl/extract/rails/action_block_builder.rb +233 -0
- data/lib/adsl/extract/rails/action_instrumenter.rb +400 -0
- data/lib/adsl/extract/rails/action_runner.rb +57 -0
- data/lib/adsl/extract/rails/active_record_metaclass_generator.rb +555 -0
- data/lib/adsl/extract/rails/callback_chain_simulator.rb +135 -0
- data/lib/adsl/extract/rails/invariant_extractor.rb +48 -0
- data/lib/adsl/extract/rails/invariant_instrumenter.rb +70 -0
- data/lib/adsl/extract/rails/other_meta.rb +57 -0
- data/lib/adsl/extract/rails/rails_extractor.rb +211 -0
- data/lib/adsl/extract/rails/rails_instrumentation_test_case.rb +34 -0
- data/lib/adsl/extract/rails/rails_special_gem_instrumentation.rb +120 -0
- data/lib/adsl/extract/rails/rails_test_helper.rb +140 -0
- data/lib/adsl/extract/sexp_utils.rb +54 -0
- data/lib/adsl/fol/first_order_logic.rb +261 -0
- data/lib/adsl/parser/adsl_parser.racc +159 -0
- data/lib/{parser → adsl/parser}/adsl_parser.rex +4 -4
- data/lib/{parser → adsl/parser}/adsl_parser.rex.rb +6 -6
- data/lib/adsl/parser/adsl_parser.tab.rb +1031 -0
- data/lib/adsl/parser/ast_nodes.rb +1410 -0
- data/lib/adsl/railtie.rb +67 -0
- data/lib/adsl/spass/bin.rb +230 -0
- data/lib/{spass → adsl/spass}/ruby_extensions.rb +0 -0
- data/lib/adsl/spass/spass_ds_extensions.rb +931 -0
- data/lib/adsl/spass/spass_translator.rb +393 -0
- data/lib/adsl/spass/util.rb +13 -0
- data/lib/adsl/util/csv_hash_formatter.rb +94 -0
- data/lib/adsl/util/general.rb +228 -0
- data/lib/adsl/util/test_helper.rb +71 -0
- data/lib/adsl/verification/formula_generators.rb +231 -0
- data/lib/adsl/verification/instrumentation_filter.rb +50 -0
- data/lib/adsl/verification/invariant.rb +19 -0
- data/lib/adsl/verification/rails_verification.rb +33 -0
- data/lib/adsl/verification/utils.rb +20 -0
- data/lib/adsl/verification/verification_case.rb +13 -0
- data/test/integration/rails/rails_branch_verification_test.rb +112 -0
- data/test/integration/rails/rails_verification_test.rb +253 -0
- data/test/integration/spass/basic_translation_test.rb +563 -0
- data/test/integration/spass/control_flow_translation_test.rb +421 -0
- data/test/unit/adsl/ds/data_store_spec_test.rb +54 -0
- data/test/unit/adsl/extract/instrumenter_test.rb +103 -0
- data/test/unit/adsl/extract/meta_test.rb +142 -0
- data/test/unit/adsl/extract/rails/action_block_builder_test.rb +178 -0
- data/test/unit/adsl/extract/rails/action_instrumenter_test.rb +68 -0
- data/test/unit/adsl/extract/rails/active_record_metaclass_generator_test.rb +336 -0
- data/test/unit/adsl/extract/rails/callback_chain_simulator_test.rb +76 -0
- data/test/unit/adsl/extract/rails/invariant_extractor_test.rb +92 -0
- data/test/unit/adsl/extract/rails/rails_extractor_test.rb +1380 -0
- data/test/unit/adsl/extract/rails/rails_test_helper_test.rb +25 -0
- data/test/unit/adsl/extract/sexp_utils_test.rb +100 -0
- data/test/unit/adsl/fol/first_order_logic_test.rb +227 -0
- data/test/unit/adsl/parser/action_parser_test.rb +1040 -0
- data/test/unit/adsl/parser/ast_nodes_test.rb +359 -0
- data/test/unit/adsl/parser/class_parser_test.rb +288 -0
- data/test/unit/adsl/parser/general_parser_test.rb +67 -0
- data/test/unit/adsl/parser/invariant_parser_test.rb +432 -0
- data/test/unit/adsl/parser/parser_util_test.rb +126 -0
- data/test/unit/adsl/spass/bin_test.rb +65 -0
- data/test/unit/adsl/spass/ruby_extensions_test.rb +39 -0
- data/test/unit/adsl/spass/spass_ds_extensions_test.rb +7 -0
- data/test/unit/adsl/spass/spass_translator_test.rb +342 -0
- data/test/unit/adsl/util/csv_hash_formatter_test.rb +68 -0
- data/test/unit/adsl/util/general_test.rb +303 -0
- data/test/unit/adsl/util/test_helper_test.rb +120 -0
- data/test/unit/adsl/verification/formula_generators_test.rb +200 -0
- data/test/unit/adsl/verification/instrumentation_filter_test.rb +39 -0
- data/test/unit/adsl/verification/utils_test.rb +39 -0
- data/test/unit/adsl/verification/verification_case_test.rb +8 -0
- metadata +229 -29
- data/lib/ds/data_store_spec.rb +0 -292
- data/lib/fol/first_order_logic.rb +0 -260
- data/lib/parser/adsl_ast.rb +0 -779
- data/lib/parser/adsl_parser.racc +0 -151
- data/lib/parser/adsl_parser.tab.rb +0 -976
- data/lib/parser/dsdl_parser.rex.rb +0 -196
- data/lib/parser/dsdl_parser.tab.rb +0 -976
- data/lib/spass/bin.rb +0 -164
- data/lib/spass/spass_ds_extensions.rb +0 -870
- data/lib/spass/spass_translator.rb +0 -388
- data/lib/spass/util.rb +0 -11
- data/lib/util/csv_hash_formatter.rb +0 -47
- data/lib/util/test_helper.rb +0 -33
- data/lib/util/util.rb +0 -114
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
require 'adsl/parser/adsl_parser.tab'
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require 'pp'
|
|
4
|
+
|
|
5
|
+
module ADSL::Parser
|
|
6
|
+
class GeneralParserTest < Test::Unit::TestCase
|
|
7
|
+
include ADSL::Parser
|
|
8
|
+
|
|
9
|
+
def test_comments_single_line
|
|
10
|
+
parser = ADSLParser.new
|
|
11
|
+
|
|
12
|
+
['#', '//'].each do |commentchar|
|
|
13
|
+
spec = parser.parse <<-ADSL
|
|
14
|
+
class Class1 {}
|
|
15
|
+
#{commentchar} class Class1 {}
|
|
16
|
+
class Class2
|
|
17
|
+
#{commentchar} class Class3
|
|
18
|
+
{} #{commentchar}#{commentchar} class Class4 {}
|
|
19
|
+
#{commentchar}#{commentchar}
|
|
20
|
+
#{commentchar}
|
|
21
|
+
ADSL
|
|
22
|
+
assert_equal ['Class1', 'Class2'], spec.classes.map{ |c| c.name }
|
|
23
|
+
|
|
24
|
+
spec = parser.parse <<-ADSL
|
|
25
|
+
#{commentchar} class Class1 {}
|
|
26
|
+
ADSL
|
|
27
|
+
assert spec.classes.empty?
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_comments_multi_line
|
|
32
|
+
parser = ADSLParser.new
|
|
33
|
+
|
|
34
|
+
spec = parser.parse <<-ADSL
|
|
35
|
+
class Class1 {}
|
|
36
|
+
/* class Class2 {} */
|
|
37
|
+
ADSL
|
|
38
|
+
assert_equal ['Class1'], spec.classes.map{ |c| c.name }
|
|
39
|
+
|
|
40
|
+
spec = parser.parse <<-ADSL
|
|
41
|
+
class Class1 /*
|
|
42
|
+
*/ {} /*
|
|
43
|
+
*/ class Class2 {}
|
|
44
|
+
ADSL
|
|
45
|
+
assert_equal ['Class1', 'Class2'], spec.classes.map{ |c| c.name }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def test_different_comment_types_dont_interfere
|
|
49
|
+
parser = ADSLParser.new
|
|
50
|
+
|
|
51
|
+
spec = parser.parse <<-ADSL
|
|
52
|
+
class Class1 {}
|
|
53
|
+
/* // */
|
|
54
|
+
class Class2 {}
|
|
55
|
+
/* # */
|
|
56
|
+
ADSL
|
|
57
|
+
assert_equal ['Class1', 'Class2'], spec.classes.map{ |c| c.name }
|
|
58
|
+
|
|
59
|
+
spec = parser.parse <<-ADSL
|
|
60
|
+
// /*
|
|
61
|
+
class Class1 {}
|
|
62
|
+
# */
|
|
63
|
+
ADSL
|
|
64
|
+
assert_equal ['Class1'], spec.classes.map{ |c| c.name }
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,432 @@
|
|
|
1
|
+
require 'adsl/parser/adsl_parser.tab'
|
|
2
|
+
require 'adsl/ds/data_store_spec'
|
|
3
|
+
require 'test/unit'
|
|
4
|
+
require 'pp'
|
|
5
|
+
|
|
6
|
+
module ADSL::Parser
|
|
7
|
+
class InvariantParserTest < Test::Unit::TestCase
|
|
8
|
+
include ADSL::Parser
|
|
9
|
+
include ADSL::DS
|
|
10
|
+
|
|
11
|
+
def test_invariant__constants
|
|
12
|
+
parser = ADSLParser.new
|
|
13
|
+
|
|
14
|
+
[true, false].each do |bool|
|
|
15
|
+
spec = nil
|
|
16
|
+
assert_nothing_raised ADSLError do
|
|
17
|
+
spec = parser.parse "invariant #{bool.to_s}"
|
|
18
|
+
end
|
|
19
|
+
assert_equal([], spec.actions)
|
|
20
|
+
assert_equal([], spec.classes)
|
|
21
|
+
assert_equal 1, spec.invariants.length
|
|
22
|
+
assert_equal bool, spec.invariants.first.formula.bool_value
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_invariant__names
|
|
27
|
+
parser = ADSLParser.new
|
|
28
|
+
spec = nil
|
|
29
|
+
assert_nothing_raised ADSLError do
|
|
30
|
+
spec = parser.parse "invariant some_name: true"
|
|
31
|
+
end
|
|
32
|
+
assert_equal "some_name", spec.invariants.first.name
|
|
33
|
+
|
|
34
|
+
assert_nothing_raised ADSLError do
|
|
35
|
+
spec = parser.parse <<-ADSL
|
|
36
|
+
invariant some_name: true
|
|
37
|
+
invariant true
|
|
38
|
+
ADSL
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
assert_raise ADSLError do
|
|
42
|
+
spec = parser.parse <<-ADSL
|
|
43
|
+
invariant some_name: true
|
|
44
|
+
invariant some_name: true
|
|
45
|
+
ADSL
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
assert_nothing_raised ADSLError do
|
|
49
|
+
spec = parser.parse <<-ADSL
|
|
50
|
+
invariant true
|
|
51
|
+
invariant true
|
|
52
|
+
ADSL
|
|
53
|
+
end
|
|
54
|
+
assert_equal "unnamed_line_1", spec.invariants.first.name
|
|
55
|
+
assert_equal "unnamed_line_2", spec.invariants.last.name
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
def test_invariant__forall_and_exists_one_param
|
|
59
|
+
parser = ADSLParser.new
|
|
60
|
+
|
|
61
|
+
operators = {
|
|
62
|
+
"forall" => DSForAll,
|
|
63
|
+
"exists" => DSExists
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
operators.each do |word, type|
|
|
67
|
+
spec = nil
|
|
68
|
+
assert_nothing_raised ADSLError do
|
|
69
|
+
spec = parser.parse <<-ADSL
|
|
70
|
+
class Class {}
|
|
71
|
+
invariant #{word}(Class a: true)
|
|
72
|
+
ADSL
|
|
73
|
+
end
|
|
74
|
+
invariant = spec.invariants.first
|
|
75
|
+
assert_equal type, invariant.formula.class
|
|
76
|
+
assert_equal 1, invariant.formula.vars.length
|
|
77
|
+
assert_equal spec.classes.first, invariant.formula.vars.first.type
|
|
78
|
+
assert_equal 'a', invariant.formula.vars.first.name
|
|
79
|
+
assert_equal true, invariant.formula.subformula.bool_value
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
def test_invariant__forall_and_exists_mulitple_params
|
|
84
|
+
parser = ADSLParser.new
|
|
85
|
+
|
|
86
|
+
operators = {
|
|
87
|
+
"forall" => DSForAll,
|
|
88
|
+
"exists" => DSExists
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
operators.each do |word, type|
|
|
92
|
+
spec = nil
|
|
93
|
+
assert_nothing_raised ADSLError do
|
|
94
|
+
spec = parser.parse <<-ADSL
|
|
95
|
+
class Class {}
|
|
96
|
+
invariant #{word}(Class a, Class b: true)
|
|
97
|
+
ADSL
|
|
98
|
+
end
|
|
99
|
+
invariant = spec.invariants.first
|
|
100
|
+
assert_equal type, invariant.formula.class
|
|
101
|
+
assert_equal 2, invariant.formula.vars.length
|
|
102
|
+
assert_equal [spec.classes.first, spec.classes.first], invariant.formula.vars.map{ |v| v.type }
|
|
103
|
+
assert_equal ['a', 'b'], invariant.formula.vars.map{ |v| v.name }
|
|
104
|
+
assert_equal true, invariant.formula.subformula.bool_value
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def test_invariant__forall_and_exists_typecheck
|
|
109
|
+
parser = ADSLParser.new
|
|
110
|
+
|
|
111
|
+
['forall', 'exists'].each do |formula|
|
|
112
|
+
assert_raise do
|
|
113
|
+
parser.parse <<-ADSL
|
|
114
|
+
invariant #{formula}(true)
|
|
115
|
+
ADSL
|
|
116
|
+
end
|
|
117
|
+
assert_raise ADSLError do
|
|
118
|
+
parser.parse <<-ADSL
|
|
119
|
+
invariant #{formula}(Class a, Class b: true)
|
|
120
|
+
ADSL
|
|
121
|
+
end
|
|
122
|
+
assert_raise ADSLError do
|
|
123
|
+
parser.parse <<-ADSL
|
|
124
|
+
class Class {}
|
|
125
|
+
invariant #{formula}(Class a, Class a: true)
|
|
126
|
+
ADSL
|
|
127
|
+
end
|
|
128
|
+
assert_raise ADSLError do
|
|
129
|
+
parser.parse <<-ADSL
|
|
130
|
+
class Class {}
|
|
131
|
+
invariant #{formula}(Class a: #{formula}(Class a: true))
|
|
132
|
+
ADSL
|
|
133
|
+
end
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
def test_invariant__forall_and_exists_can_use_objsets
|
|
138
|
+
parser = ADSLParser.new
|
|
139
|
+
['forall', 'exists'].each do |formula|
|
|
140
|
+
spec = parser.parse <<-ADSL
|
|
141
|
+
class Class { 0+ Class relation }
|
|
142
|
+
invariant #{formula}(a in allof(Class): true)
|
|
143
|
+
ADSL
|
|
144
|
+
invariant = spec.invariants.first
|
|
145
|
+
assert_equal 'a', invariant.formula.vars.first.name
|
|
146
|
+
assert_equal DSAllOf, invariant.formula.objsets.first.class
|
|
147
|
+
|
|
148
|
+
spec = parser.parse <<-ADSL
|
|
149
|
+
class Class { 0+ Class relation }
|
|
150
|
+
invariant #{formula}(a in allof(Class).relation: true)
|
|
151
|
+
ADSL
|
|
152
|
+
invariant = spec.invariants.first
|
|
153
|
+
assert_equal 'a', invariant.formula.vars.first.name
|
|
154
|
+
assert_equal DSDereference, invariant.formula.objsets.first.class
|
|
155
|
+
|
|
156
|
+
spec = parser.parse <<-ADSL
|
|
157
|
+
class Class { 0+ Class relation }
|
|
158
|
+
invariant #{formula}(Class a: #{formula}(b in a: true))
|
|
159
|
+
ADSL
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
def test_invariant__exists_can_go_without_subformula_while_forall_cannot
|
|
164
|
+
parser = ADSLParser.new
|
|
165
|
+
assert_nothing_raised ADSLError do
|
|
166
|
+
spec = parser.parse <<-ADSL
|
|
167
|
+
class Class {}
|
|
168
|
+
invariant exists(Class a)
|
|
169
|
+
ADSL
|
|
170
|
+
end
|
|
171
|
+
assert_raise do
|
|
172
|
+
spec = parser.parse <<-ADSL
|
|
173
|
+
class Class {}
|
|
174
|
+
invariant forall(Class a)
|
|
175
|
+
ADSL
|
|
176
|
+
end
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def test_invariant__parenthesis
|
|
180
|
+
parser = ADSLParser.new
|
|
181
|
+
spec = parser.parse <<-ADSL
|
|
182
|
+
invariant (true)
|
|
183
|
+
ADSL
|
|
184
|
+
invariant = spec.invariants.first
|
|
185
|
+
assert_equal true, invariant.formula.bool_value
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def test_invariant__not
|
|
189
|
+
parser = ADSLParser.new
|
|
190
|
+
['not', '!'].each do |word|
|
|
191
|
+
spec = parser.parse <<-ADSL
|
|
192
|
+
invariant not false
|
|
193
|
+
ADSL
|
|
194
|
+
invariant = spec.invariants.first
|
|
195
|
+
assert_equal DSNot, invariant.formula.class
|
|
196
|
+
assert_equal false, invariant.formula.subformula.bool_value
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def test_invariant__and_or
|
|
201
|
+
parser = ADSLParser.new
|
|
202
|
+
operators = {
|
|
203
|
+
"and" => DSAnd,
|
|
204
|
+
"or" => DSOr
|
|
205
|
+
}
|
|
206
|
+
operators.each do |word, type|
|
|
207
|
+
spec = parser.parse <<-ADSL
|
|
208
|
+
invariant true #{word} false
|
|
209
|
+
ADSL
|
|
210
|
+
invariant = spec.invariants.first
|
|
211
|
+
assert_equal type, invariant.formula.class
|
|
212
|
+
assert_equal [true, false], invariant.formula.subformulae.map{ |a| a.bool_value}
|
|
213
|
+
|
|
214
|
+
spec = parser.parse <<-ADSL
|
|
215
|
+
invariant true #{word} false #{word} true
|
|
216
|
+
ADSL
|
|
217
|
+
invariant = spec.invariants.first
|
|
218
|
+
assert_equal type, invariant.formula.class
|
|
219
|
+
assert_equal [true, false, true], invariant.formula.subformulae.map{ |a| a.bool_value}
|
|
220
|
+
end
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
def test_invariant__operator_precedence_and_associativity
|
|
224
|
+
parser = ADSLParser.new
|
|
225
|
+
operators = {
|
|
226
|
+
"and" => DSAnd,
|
|
227
|
+
"or" => DSOr
|
|
228
|
+
}
|
|
229
|
+
operators.each do |word, type|
|
|
230
|
+
spec = parser.parse <<-ADSL
|
|
231
|
+
invariant not true #{word} false
|
|
232
|
+
ADSL
|
|
233
|
+
invariant = spec.invariants.first
|
|
234
|
+
assert_equal type, invariant.formula.class
|
|
235
|
+
assert_equal DSNot, invariant.formula.subformulae.first.class
|
|
236
|
+
assert_equal false, invariant.formula.subformulae.second.bool_value
|
|
237
|
+
end
|
|
238
|
+
operators.each do |word, type|
|
|
239
|
+
spec = parser.parse <<-ADSL
|
|
240
|
+
invariant not (true #{word} false)
|
|
241
|
+
ADSL
|
|
242
|
+
invariant = spec.invariants.first
|
|
243
|
+
assert_equal DSNot, invariant.formula.class
|
|
244
|
+
assert_equal type, invariant.formula.subformula.class
|
|
245
|
+
end
|
|
246
|
+
spec = parser.parse <<-ADSL
|
|
247
|
+
invariant true and !false or true
|
|
248
|
+
ADSL
|
|
249
|
+
invariant = spec.invariants.first
|
|
250
|
+
assert_equal DSOr, invariant.formula.class
|
|
251
|
+
assert_equal true, invariant.formula.subformulae.second.bool_value
|
|
252
|
+
assert_equal DSAnd, invariant.formula.subformulae.first.class
|
|
253
|
+
assert_equal true, invariant.formula.subformulae.first.subformulae.first.bool_value
|
|
254
|
+
assert_equal DSNot, invariant.formula.subformulae.first.subformulae.second.class
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
def test_invariant__equal
|
|
258
|
+
parser = ADSLParser.new
|
|
259
|
+
spec = parser.parse <<-ADSL
|
|
260
|
+
class Class {}
|
|
261
|
+
invariant exists(Class o1, Class o2: o1 == o2)
|
|
262
|
+
ADSL
|
|
263
|
+
f = spec.invariants.first.formula.subformula
|
|
264
|
+
assert_equal DSEqual, f.class
|
|
265
|
+
assert_equal ['o1', 'o2'], f.objsets.map { |v| v.name }
|
|
266
|
+
|
|
267
|
+
spec = parser.parse <<-ADSL
|
|
268
|
+
class Class {}
|
|
269
|
+
invariant exists(Class o1, Class o2: equal(o1, o2))
|
|
270
|
+
ADSL
|
|
271
|
+
f = spec.invariants.first.formula.subformula
|
|
272
|
+
assert_equal DSEqual, f.class
|
|
273
|
+
assert_equal ['o1', 'o2'], f.objsets.map { |v| v.name }
|
|
274
|
+
|
|
275
|
+
spec = parser.parse <<-ADSL
|
|
276
|
+
class Class {}
|
|
277
|
+
invariant exists(Class o1, Class o2: equal(o1, o2, o1, o1))
|
|
278
|
+
ADSL
|
|
279
|
+
f = spec.invariants.first.formula.subformula
|
|
280
|
+
assert_equal DSEqual, f.class
|
|
281
|
+
assert_equal ['o1', 'o2', 'o1', 'o1'], f.objsets.map { |v| v.name }
|
|
282
|
+
|
|
283
|
+
assert_nothing_raised ADSLError do
|
|
284
|
+
parser.parse <<-ADSL
|
|
285
|
+
class Class {}
|
|
286
|
+
class Child extends Class {}
|
|
287
|
+
invariant allof(Class) == allof(Child)
|
|
288
|
+
ADSL
|
|
289
|
+
end
|
|
290
|
+
assert_raise ADSLError do
|
|
291
|
+
parser.parse <<-ADSL
|
|
292
|
+
class Class1 {}
|
|
293
|
+
class Class2 {}
|
|
294
|
+
invariant allof(Class1) == allof(Child2)
|
|
295
|
+
ADSL
|
|
296
|
+
end
|
|
297
|
+
assert_raise ADSLError do
|
|
298
|
+
parser.parse <<-ADSL
|
|
299
|
+
class Parent {}
|
|
300
|
+
class Class1 extends Parent {}
|
|
301
|
+
class Class2 extends Parent {}
|
|
302
|
+
invariant equal(allof(Parent), allof(Class1), allof(Child2))
|
|
303
|
+
ADSL
|
|
304
|
+
end
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
def test_invariant__not_equal
|
|
308
|
+
parser = ADSLParser.new
|
|
309
|
+
spec = parser.parse <<-ADSL
|
|
310
|
+
class Class {}
|
|
311
|
+
invariant exists(Class o1, Class o2: o1 != o2)
|
|
312
|
+
ADSL
|
|
313
|
+
f = spec.invariants.first.formula.subformula
|
|
314
|
+
assert_equal DSNot, f.class
|
|
315
|
+
assert_equal DSEqual, f.subformula.class
|
|
316
|
+
assert_equal ['o1', 'o2'], f.subformula.objsets.map { |v| v.name }
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
def test_invariant__equiv
|
|
320
|
+
parser = ADSLParser.new
|
|
321
|
+
spec = parser.parse <<-ADSL
|
|
322
|
+
class Class {}
|
|
323
|
+
invariant true <=> false
|
|
324
|
+
ADSL
|
|
325
|
+
invariant = spec.invariants.first
|
|
326
|
+
assert_equal DSEquiv, invariant.formula.class
|
|
327
|
+
assert_equal [true, false], invariant.formula.subformulae.map{ |f| f.bool_value }
|
|
328
|
+
|
|
329
|
+
spec = parser.parse <<-ADSL
|
|
330
|
+
class Class {}
|
|
331
|
+
invariant equiv(true, false)
|
|
332
|
+
ADSL
|
|
333
|
+
invariant = spec.invariants.first
|
|
334
|
+
assert_equal DSEquiv, invariant.formula.class
|
|
335
|
+
assert_equal [true, false], invariant.formula.subformulae.map{ |f| f.bool_value }
|
|
336
|
+
|
|
337
|
+
spec = parser.parse <<-ADSL
|
|
338
|
+
class Class {}
|
|
339
|
+
invariant equiv(true, false, true, true)
|
|
340
|
+
ADSL
|
|
341
|
+
invariant = spec.invariants.first
|
|
342
|
+
assert_equal DSEquiv, invariant.formula.class
|
|
343
|
+
assert_equal [true, false, true, true], invariant.formula.subformulae.map{ |f| f.bool_value }
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
def test_invariant__implies
|
|
347
|
+
parser = ADSLParser.new
|
|
348
|
+
spec = parser.parse <<-ADSL
|
|
349
|
+
class Class {}
|
|
350
|
+
invariant true => false
|
|
351
|
+
ADSL
|
|
352
|
+
invariant = spec.invariants.first
|
|
353
|
+
assert_equal DSImplies, invariant.formula.class
|
|
354
|
+
assert_equal true, invariant.formula.subformula1.bool_value
|
|
355
|
+
assert_equal false, invariant.formula.subformula2.bool_value
|
|
356
|
+
|
|
357
|
+
spec = parser.parse <<-ADSL
|
|
358
|
+
class Class {}
|
|
359
|
+
invariant false <= true
|
|
360
|
+
ADSL
|
|
361
|
+
invariant = spec.invariants.first
|
|
362
|
+
assert_equal DSImplies, invariant.formula.class
|
|
363
|
+
assert_equal true, invariant.formula.subformula1.bool_value
|
|
364
|
+
assert_equal false, invariant.formula.subformula2.bool_value
|
|
365
|
+
|
|
366
|
+
spec = parser.parse <<-ADSL
|
|
367
|
+
class Class {}
|
|
368
|
+
invariant implies(true, false)
|
|
369
|
+
ADSL
|
|
370
|
+
invariant = spec.invariants.first
|
|
371
|
+
assert_equal DSImplies, invariant.formula.class
|
|
372
|
+
assert_equal true, invariant.formula.subformula1.bool_value
|
|
373
|
+
assert_equal false, invariant.formula.subformula2.bool_value
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
def test_invariant__empty
|
|
377
|
+
parser = ADSLParser.new
|
|
378
|
+
spec = parser.parse <<-ADSL
|
|
379
|
+
class Class {}
|
|
380
|
+
invariant empty(allof(Class))
|
|
381
|
+
ADSL
|
|
382
|
+
invariant = spec.invariants.first
|
|
383
|
+
assert_equal DSEmpty, invariant.formula.class
|
|
384
|
+
assert_equal DSAllOf, invariant.formula.objset.class
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
def test_invariant__in
|
|
388
|
+
parser = ADSLParser.new
|
|
389
|
+
spec = parser.parse <<-ADSL
|
|
390
|
+
class Class {}
|
|
391
|
+
invariant allof(Class) in allof(Class)
|
|
392
|
+
ADSL
|
|
393
|
+
invariant = spec.invariants.first
|
|
394
|
+
assert_equal DSIn, invariant.formula.class
|
|
395
|
+
assert_equal DSAllOf, invariant.formula.objset1.class
|
|
396
|
+
assert_equal DSAllOf, invariant.formula.objset2.class
|
|
397
|
+
|
|
398
|
+
assert_raise ADSLError do
|
|
399
|
+
parser.parse <<-ADSL
|
|
400
|
+
class Class1 {}
|
|
401
|
+
class Class2 {}
|
|
402
|
+
invariant allof(Class1) in allof(Class2)
|
|
403
|
+
ADSL
|
|
404
|
+
end
|
|
405
|
+
assert_raise ADSLError do
|
|
406
|
+
parser.parse <<-ADSL
|
|
407
|
+
class Super {}
|
|
408
|
+
class Sub extends Super {}
|
|
409
|
+
invariant allof(Super) in allof(Sub)
|
|
410
|
+
ADSL
|
|
411
|
+
end
|
|
412
|
+
assert_nothing_raised ADSLError do
|
|
413
|
+
parser.parse <<-ADSL
|
|
414
|
+
class Super {}
|
|
415
|
+
class Sub extends Super {}
|
|
416
|
+
invariant allof(Sub) in allof(Super)
|
|
417
|
+
ADSL
|
|
418
|
+
end
|
|
419
|
+
end
|
|
420
|
+
|
|
421
|
+
def test_invariant__variable_scope
|
|
422
|
+
parser = ADSLParser.new
|
|
423
|
+
spec = parser.parse <<-ADSL
|
|
424
|
+
class Class {}
|
|
425
|
+
invariant exists(Class o)
|
|
426
|
+
invariant exists(Class o)
|
|
427
|
+
invariant exists(Class o)
|
|
428
|
+
invariant exists(Class o)
|
|
429
|
+
ADSL
|
|
430
|
+
end
|
|
431
|
+
end
|
|
432
|
+
end
|