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,25 @@
|
|
|
1
|
+
require 'test/unit'
|
|
2
|
+
require 'active_record'
|
|
3
|
+
require 'ruby_parser'
|
|
4
|
+
require 'ruby2ruby'
|
|
5
|
+
require 'adsl/util/test_helper'
|
|
6
|
+
require 'adsl/extract/rails/rails_test_helper'
|
|
7
|
+
require 'adsl/extract/rails/rails_instrumentation_test_case'
|
|
8
|
+
|
|
9
|
+
class ADSL::Extract::Rails::RailsTestHelperTest < ADSL::Extract::Rails::RailsInstrumentationTestCase
|
|
10
|
+
def test__ar_classes_exist_and_work
|
|
11
|
+
assert self.class.const_defined? :Asd
|
|
12
|
+
assert self.class.const_defined? :Kme
|
|
13
|
+
assert self.class.const_defined? :Mod
|
|
14
|
+
assert Mod.const_defined? :Blah
|
|
15
|
+
|
|
16
|
+
a = Asd.new
|
|
17
|
+
a.blahs.build
|
|
18
|
+
a.save!
|
|
19
|
+
|
|
20
|
+
assert_equal 1, Asd.all.length
|
|
21
|
+
a_from_db = Asd.all.first
|
|
22
|
+
assert_equal 1, a_from_db.blahs.length
|
|
23
|
+
assert_equal a_from_db, Mod::Blah.all.first.asd
|
|
24
|
+
end
|
|
25
|
+
end
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
require 'test/unit'
|
|
2
|
+
require 'pp'
|
|
3
|
+
require 'adsl/extract/sexp_utils'
|
|
4
|
+
require 'adsl/util/test_helper'
|
|
5
|
+
|
|
6
|
+
class ADSL::Extract::SexpUtilsTest < Test::Unit::TestCase
|
|
7
|
+
def test_block_replace__no_match
|
|
8
|
+
sexp = s(:array, s(:lit, 1), s(:lit, 2))
|
|
9
|
+
|
|
10
|
+
replacement = sexp.block_replace(:call) do |a|
|
|
11
|
+
"#{a}2".to_sym
|
|
12
|
+
end
|
|
13
|
+
assert_equal s(:array, s(:lit, 1), s(:lit, 2)), replacement
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def test_block_replace__plain
|
|
17
|
+
sexp = s(:array, s(:lit, 1), s(:lit, 2), s(:lit, 0))
|
|
18
|
+
|
|
19
|
+
replacement = sexp.block_replace(:array) do |a|
|
|
20
|
+
Sexp.from_array [:array] + a.sexp_body.map{ |e| [:lit, e[1] * 2] }
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
assert_equal s(:array, s(:lit, 2), s(:lit, 4), s(:lit, 0)), replacement
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def test_block_replace__nested
|
|
27
|
+
sexp = s(:array, s(:lit, 1), s(:lit, 2), s(:array, s(:lit, 3)))
|
|
28
|
+
|
|
29
|
+
replacement = sexp.block_replace(:array) do |a|
|
|
30
|
+
Sexp.from_array [:array] + a.sexp_body.map{ |e| e.sexp_type == :lit ? [:lit, e[1] * 2] : e }
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
assert_equal s(:array, s(:lit, 2), s(:lit, 4), s(:array, s(:lit, 6))), replacement
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def test_block_replace__deep
|
|
37
|
+
sexp = s(:blah, s(:array, s(:lit, 1), s(:lit, 2)))
|
|
38
|
+
|
|
39
|
+
replacement = sexp.block_replace(:lit) do |a|
|
|
40
|
+
s(:lit, a[1]*2)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
assert_equal s(:blah, s(:array, s(:lit, 2), s(:lit, 4))), replacement
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def test_block_replace__unless_in
|
|
47
|
+
sexp = s(:blah, s(:array, s(:lit, 1), s(:blah, s(:lit, 1))), s(:lit, 1))
|
|
48
|
+
|
|
49
|
+
replacement = sexp.block_replace(:lit, :unless_in => :array) do |sexp|
|
|
50
|
+
s(:lit, sexp[1]*2)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
assert_equal s(:blah, s(:array, s(:lit, 1), s(:blah, s(:lit, 1))), s(:lit, 2)), replacement
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
sexp = s(:blah, s(:array, s(:lit, 1), s(:blah, s(:lit, 1))), s(:lit, 1))
|
|
57
|
+
|
|
58
|
+
replacement = sexp.block_replace(:lit, :unless_in => [:array]) do |sexp|
|
|
59
|
+
s(:lit, sexp[1]*2)
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
assert_equal s(:blah, s(:array, s(:lit, 1), s(:blah, s(:lit, 1))), s(:lit, 2)), replacement
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def test_find_shallowest__plain
|
|
66
|
+
assert_equal [], s(s(:self)).find_shallowest(:lit)
|
|
67
|
+
assert_equal [s(:lit, 1), s(:lit, 2)], s(s(:lit, 1), s(:self), s(:lit, 2), s(:self)).find_shallowest(:lit)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
def test_find_shallowest__goes_through_depth
|
|
71
|
+
assert_equal [s(:lit, 1), s(:lit, 2)], s(s(s(:lit, 1), s(:self), s(:lit, 2), s(:self))).find_shallowest(:lit)
|
|
72
|
+
assert_equal [s(:lit, 1), s(:lit, 2)], s(s(:lit, 1), s(s(:self), s(:lit, 2), s(:self))).find_shallowest(:lit)
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def test_find_shallowest__only_the_shallowest
|
|
76
|
+
assert_equal [s(:lit, s(:lit, 2))], s(s(:lit, s(:lit, 2)), s(:self)).find_shallowest(:lit)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def test_may_return_or_raise__simple
|
|
80
|
+
assert_false s(:block, s(:if, s(:true), s(:block), s(:block))).may_return_or_raise?
|
|
81
|
+
assert s(:block, s(:if, s(:true), s(:block), s(:block, s(:return, s(:nil))))).may_return_or_raise?
|
|
82
|
+
|
|
83
|
+
assert_false s(:block, s(:if, s(:true), s(:block), s(:block))).may_return_or_raise?
|
|
84
|
+
assert s(:block, s(:if, s(:true), s(:block), s(:block, s(:call, nil, :raise)))).may_return_or_raise?
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def test_may_return_or_raise__deep
|
|
88
|
+
sexp = s(:if,
|
|
89
|
+
s(:lasgn, :user, s(:call, s(:const, :User), :authenticate, s(:call, nil, :http_user), s(:call, nil, :http_pass))),
|
|
90
|
+
s(:block,
|
|
91
|
+
s(:attrasgn, s(:call, nil, :session), :[]=, s(:str, "user_id"), s(:call, s(:lvar, :user), :id)),
|
|
92
|
+
s(:call, nil, :set_current_user, s(:lvar, :user)),
|
|
93
|
+
s(:return, s(:true))
|
|
94
|
+
),
|
|
95
|
+
nil
|
|
96
|
+
)
|
|
97
|
+
assert sexp.may_return_or_raise?
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
end
|
|
@@ -0,0 +1,227 @@
|
|
|
1
|
+
require 'adsl/fol/first_order_logic'
|
|
2
|
+
require 'test/unit'
|
|
3
|
+
require 'pp'
|
|
4
|
+
|
|
5
|
+
class ADSL::FOL::FirstOrderLogicTest < Test::Unit::TestCase
|
|
6
|
+
def teardown
|
|
7
|
+
if Object.constants.include?(:Foo)
|
|
8
|
+
Object.send(:remove_const, :Foo)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def test_fol_class_integration
|
|
13
|
+
eval <<-ruby
|
|
14
|
+
class Foo
|
|
15
|
+
include ADSL::FOL
|
|
16
|
+
end
|
|
17
|
+
ruby
|
|
18
|
+
foo = Foo.new
|
|
19
|
+
assert foo.methods.include?("_and") || foo.methods.include?(:_and)
|
|
20
|
+
|
|
21
|
+
eval <<-ruby
|
|
22
|
+
class Foo
|
|
23
|
+
def asd
|
|
24
|
+
_and(:a, :b)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
ruby
|
|
28
|
+
assert_equal "and(a, b)", Foo.new.asd.resolve_spass
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def test_literals
|
|
32
|
+
assert_equal "true", true.resolve_spass
|
|
33
|
+
assert_equal "false", false.resolve_spass
|
|
34
|
+
assert_equal "symbol_here", :symbol_here.resolve_spass
|
|
35
|
+
assert_equal "sometext", "sometext".resolve_spass
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def test_split_by_zero_level_comma
|
|
39
|
+
assert_equal [""], "".split_by_zero_level_comma
|
|
40
|
+
assert_equal ["asd"], "asd".split_by_zero_level_comma
|
|
41
|
+
assert_equal ["asd", "kme"], "asd,kme".split_by_zero_level_comma
|
|
42
|
+
assert_equal ["asd", ""], "asd,".split_by_zero_level_comma
|
|
43
|
+
assert_equal ["", ""], ",".split_by_zero_level_comma
|
|
44
|
+
assert_equal ["(asd, asd)"], "(asd, asd)".split_by_zero_level_comma
|
|
45
|
+
assert_equal ["(a,a,a,()((()())))", ""], "(a,a,a,()((()()))),".split_by_zero_level_comma
|
|
46
|
+
assert_raise do
|
|
47
|
+
")(".split_by_zero_level_comma
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def test_not
|
|
52
|
+
assert_raise ArgumentError do
|
|
53
|
+
ADSL::FOL::Not.new
|
|
54
|
+
end
|
|
55
|
+
assert_equal "not(a)", ADSL::FOL::Not.new(:a).resolve_spass
|
|
56
|
+
assert_equal "and(not(a), not(b))".gsub(/\s+/, ''), \
|
|
57
|
+
ADSL::FOL::Not.new(:a, :b).resolve_spass.gsub(/\s+/, '')
|
|
58
|
+
assert_equal "true", ADSL::FOL::Not.new(false).resolve_spass
|
|
59
|
+
assert_equal "false", ADSL::FOL::Not.new(true).resolve_spass
|
|
60
|
+
assert_equal "false", ADSL::FOL::Not.new(true, false).resolve_spass
|
|
61
|
+
assert_equal "a", ADSL::FOL::Not.new(ADSL::FOL::Not.new(:a)).resolve_spass
|
|
62
|
+
assert_equal "and(a, not(b))", ADSL::FOL::Not.new(ADSL::FOL::Not.new(:a), ADSL::FOL::Not.new(ADSL::FOL::Not.new(:b))).resolve_spass
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def test_and
|
|
66
|
+
assert_equal "true", ADSL::FOL::And.new.resolve_spass
|
|
67
|
+
|
|
68
|
+
assert_equal "a", ADSL::FOL::And.new("a").resolve_spass
|
|
69
|
+
assert_equal "and(a, b)", ADSL::FOL::And.new("a", "b").resolve_spass
|
|
70
|
+
|
|
71
|
+
assert_equal "a", ADSL::FOL::And.new(true, 'a').resolve_spass
|
|
72
|
+
assert_equal "and(a, b)", ADSL::FOL::And.new(true, "a", "b").resolve_spass
|
|
73
|
+
assert_equal "false", ADSL::FOL::And.new(true, false).resolve_spass
|
|
74
|
+
assert_equal "true", ADSL::FOL::And.new(true).resolve_spass
|
|
75
|
+
|
|
76
|
+
assert_equal "and(a, b, c)", ADSL::FOL::And.new(ADSL::FOL::And.new(:a, :b), :c).resolve_spass
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def test_or
|
|
80
|
+
assert_equal "false", ADSL::FOL::Or.new.resolve_spass
|
|
81
|
+
|
|
82
|
+
assert_equal "a", ADSL::FOL::Or.new("a").resolve_spass
|
|
83
|
+
assert_equal "or(a, b)", ADSL::FOL::Or.new("a", "b").resolve_spass
|
|
84
|
+
|
|
85
|
+
assert_equal "a", ADSL::FOL::Or.new(false, 'a').resolve_spass
|
|
86
|
+
assert_equal "or(a, b)", ADSL::FOL::Or.new(false, "a", "b").resolve_spass
|
|
87
|
+
assert_equal "true", ADSL::FOL::Or.new(true, false).resolve_spass
|
|
88
|
+
assert_equal "false", ADSL::FOL::Or.new(false).resolve_spass
|
|
89
|
+
|
|
90
|
+
assert_equal "or(a, b, c)", ADSL::FOL::Or.new(ADSL::FOL::Or.new(:a, :b), :c).resolve_spass
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def test_forall
|
|
94
|
+
assert_raise ArgumentError do
|
|
95
|
+
ADSL::FOL::ForAll.new
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
assert_equal "a", ADSL::FOL::ForAll.new(:a).resolve_spass
|
|
99
|
+
assert_equal "true", ADSL::FOL::ForAll.new(:a, :b, true).resolve_spass
|
|
100
|
+
assert_equal "false", ADSL::FOL::ForAll.new(:a, :b, false).resolve_spass
|
|
101
|
+
assert_equal "forall([a], blah(a))".gsub(/\s+/, ''), \
|
|
102
|
+
ADSL::FOL::ForAll.new(:a, "blah(a)").resolve_spass.gsub(/\s+/, '')
|
|
103
|
+
assert_equal "forall([a, b], blah(a))".gsub(/\s+/, ''), \
|
|
104
|
+
ADSL::FOL::ForAll.new(:a, :b, "blah(a)").resolve_spass.gsub(/\s+/, '')
|
|
105
|
+
end
|
|
106
|
+
|
|
107
|
+
def test_exists
|
|
108
|
+
assert_raise ArgumentError do
|
|
109
|
+
ADSL::FOL::Exists.new
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
assert_equal "a", ADSL::FOL::Exists.new(:a).resolve_spass
|
|
113
|
+
assert_equal "true", ADSL::FOL::ForAll.new(:a, :b, true).resolve_spass
|
|
114
|
+
assert_equal "false", ADSL::FOL::ForAll.new(:a, :b, false).resolve_spass
|
|
115
|
+
assert_equal "exists([a], true(a))".gsub(/\s+/, ''), \
|
|
116
|
+
ADSL::FOL::Exists.new(:a, "true(a)").resolve_spass.gsub(/\s+/, '')
|
|
117
|
+
assert_equal "exists([a, b], true(a))".gsub(/\s+/, ''), \
|
|
118
|
+
ADSL::FOL::Exists.new(:a, :b, "true(a)").resolve_spass.gsub(/\s+/, '')
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def test_equiv
|
|
122
|
+
assert_raise ArgumentError do
|
|
123
|
+
ADSL::FOL::Equiv.new
|
|
124
|
+
end
|
|
125
|
+
assert_raise ArgumentError do
|
|
126
|
+
ADSL::FOL::Equiv.new :a
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
assert_equal 'a', ADSL::FOL::Equiv.new(true, :a).resolve_spass
|
|
130
|
+
assert_equal 'and(a, b)', ADSL::FOL::Equiv.new(:a, true, :b).resolve_spass
|
|
131
|
+
assert_equal 'and(not(a), not(b))', ADSL::FOL::Equiv.new(:a, false, :b).resolve_spass
|
|
132
|
+
assert_equal 'false', ADSL::FOL::Equiv.new(:a, false, :b, true).resolve_spass
|
|
133
|
+
assert_equal "equiv(a, b)".gsub(/\s+/, ''), \
|
|
134
|
+
ADSL::FOL::Equiv.new(:a, :b).resolve_spass.gsub(/\s+/, '')
|
|
135
|
+
assert_equal "and(equiv(a, b), equiv(b, c))".gsub(/\s+/, ''), \
|
|
136
|
+
ADSL::FOL::Equiv.new(:a, :b, :c).resolve_spass.gsub(/\s+/, '')
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def test_implies
|
|
140
|
+
assert_raise ArgumentError do
|
|
141
|
+
ADSL::FOL::Implies.new
|
|
142
|
+
end
|
|
143
|
+
assert_raise ArgumentError do
|
|
144
|
+
ADSL::FOL::Implies.new :a
|
|
145
|
+
end
|
|
146
|
+
assert_raise ArgumentError do
|
|
147
|
+
ADSL::FOL::Implies.new :a, :b, :c
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
assert_equal "implies(a, b)".gsub(/\s+/, ''), \
|
|
151
|
+
ADSL::FOL::Implies.new(:a, :b).resolve_spass.gsub(/\s+/, '')
|
|
152
|
+
assert_equal "a".gsub(/\s+/, ''), \
|
|
153
|
+
ADSL::FOL::Implies.new(true, :a).resolve_spass.gsub(/\s+/, '')
|
|
154
|
+
assert_equal "true".gsub(/\s+/, ''), \
|
|
155
|
+
ADSL::FOL::Implies.new(:a, true).resolve_spass.gsub(/\s+/, '')
|
|
156
|
+
assert_equal "true".gsub(/\s+/, ''), \
|
|
157
|
+
ADSL::FOL::Implies.new(false, :a).resolve_spass.gsub(/\s+/, '')
|
|
158
|
+
assert_equal "not(a)".gsub(/\s+/, ''), \
|
|
159
|
+
ADSL::FOL::Implies.new(:a, false).resolve_spass.gsub(/\s+/, '')
|
|
160
|
+
|
|
161
|
+
assert_equal 'true', ADSL::FOL::Implies.new(true, true).resolve_spass
|
|
162
|
+
assert_equal 'false', ADSL::FOL::Implies.new(true, false).resolve_spass
|
|
163
|
+
assert_equal 'true', ADSL::FOL::Implies.new(false, true).resolve_spass
|
|
164
|
+
assert_equal 'true', ADSL::FOL::Implies.new(false, false).resolve_spass
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
def test_equal
|
|
168
|
+
assert_raise ArgumentError do
|
|
169
|
+
ADSL::FOL::Equal.new
|
|
170
|
+
end
|
|
171
|
+
assert_raise ArgumentError do
|
|
172
|
+
ADSL::FOL::Equal.new :a
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
assert_equal "equal(a, b)".gsub(/\s+/, ''), \
|
|
176
|
+
ADSL::FOL::Equal.new(:a, :b).resolve_spass.gsub(/\s+/, '')
|
|
177
|
+
assert_equal "and(equal(a, b), equal(b, c))".gsub(/\s+/, ''), \
|
|
178
|
+
ADSL::FOL::Equal.new(:a, :b, :c).resolve_spass.gsub(/\s+/, '')
|
|
179
|
+
end
|
|
180
|
+
|
|
181
|
+
def test_one_of
|
|
182
|
+
assert_equal 'false', ADSL::FOL::OneOf.new.resolve_spass
|
|
183
|
+
assert_equal "a".gsub(/\s+/, ''), \
|
|
184
|
+
ADSL::FOL::OneOf.new(:a).resolve_spass.gsub(/\s+/, '')
|
|
185
|
+
assert_equal "equiv(not(a), b)".gsub(/\s+/, ''), \
|
|
186
|
+
ADSL::FOL::OneOf.new(:a, :b).resolve_spass.gsub(/\s+/, '')
|
|
187
|
+
assert_equal "and(or(a, b, c), implies(a, and(not(b), not(c))), implies(b, and(not(a), not(c))), implies(c, and(not(a), not(b))))".gsub(/\s+/, ''), \
|
|
188
|
+
ADSL::FOL::OneOf.new(:a, :b, :c).resolve_spass.gsub(/\s+/, '')
|
|
189
|
+
end
|
|
190
|
+
|
|
191
|
+
def test_if_then_else
|
|
192
|
+
assert_equal "and(implies(a, b), implies(not(a), c))".gsub(/\s+/, ''), \
|
|
193
|
+
ADSL::FOL::IfThenElse.new(:a, :b, :c).resolve_spass.gsub(/\s+/, '')
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
def test_if_then_else_eq
|
|
197
|
+
assert_equal "and(equiv(a, b), equiv(not(a), c))".gsub(/\s+/, ''), \
|
|
198
|
+
ADSL::FOL::IfThenElseEq.new(:a, :b, :c).resolve_spass.gsub(/\s+/, '')
|
|
199
|
+
end
|
|
200
|
+
|
|
201
|
+
def test_pairwise_equal__explicit_lists
|
|
202
|
+
assert_raise ArgumentError do
|
|
203
|
+
ADSL::FOL::PairwiseEqual.new [], [:a]
|
|
204
|
+
end
|
|
205
|
+
assert_raise ArgumentError do
|
|
206
|
+
ADSL::FOL::PairwiseEqual.new [:b, :c], [:a]
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
assert_equal "true", ADSL::FOL::PairwiseEqual.new([], []).resolve_spass
|
|
210
|
+
assert_equal "equal(a1, b1)", ADSL::FOL::PairwiseEqual.new([:a1], [:b1]).resolve_spass
|
|
211
|
+
assert_equal "and(equal(a1, b1), equal(a2, b2))", ADSL::FOL::PairwiseEqual.new([:a1, :a2], [:b1, :b2]).resolve_spass
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
def test_pairwise_equal__implicit_lists
|
|
215
|
+
assert_raise ArgumentError do
|
|
216
|
+
ADSL::FOL::PairwiseEqual.new :a
|
|
217
|
+
end
|
|
218
|
+
assert_raise ArgumentError do
|
|
219
|
+
ADSL::FOL::PairwiseEqual.new :b, [[:c]], :a
|
|
220
|
+
end
|
|
221
|
+
|
|
222
|
+
assert_equal "true", ADSL::FOL::PairwiseEqual.new().resolve_spass
|
|
223
|
+
assert_equal "equal(a1, b1)", ADSL::FOL::PairwiseEqual.new(:a1, :b1).resolve_spass
|
|
224
|
+
assert_equal "and(equal(a1, b1), equal(a2, b2))", ADSL::FOL::PairwiseEqual.new(:a1, :a2, :b1, [:b2]).resolve_spass
|
|
225
|
+
end
|
|
226
|
+
end
|
|
227
|
+
|
|
@@ -0,0 +1,1040 @@
|
|
|
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 ActionParserTest < Test::Unit::TestCase
|
|
8
|
+
include ADSL::DS
|
|
9
|
+
|
|
10
|
+
def test_action__empty
|
|
11
|
+
parser = ADSLParser.new
|
|
12
|
+
spec = nil
|
|
13
|
+
assert_nothing_raised ADSLError do
|
|
14
|
+
spec = parser.parse ""
|
|
15
|
+
end
|
|
16
|
+
assert_equal([], spec.actions)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def test_action__no_stmts
|
|
20
|
+
parser = ADSLParser.new
|
|
21
|
+
spec = nil
|
|
22
|
+
assert_nothing_raised ADSLError do
|
|
23
|
+
spec = parser.parse <<-adsl
|
|
24
|
+
action do_something() {
|
|
25
|
+
}
|
|
26
|
+
adsl
|
|
27
|
+
end
|
|
28
|
+
assert_equal 1, spec.actions.length
|
|
29
|
+
assert_equal 0, spec.actions.first.block.statements.length
|
|
30
|
+
assert_equal "do_something", spec.actions.first.name
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def test_action__vars_are_stored
|
|
34
|
+
parser = ADSLParser.new
|
|
35
|
+
spec = nil
|
|
36
|
+
assert_nothing_raised ADSLError do
|
|
37
|
+
spec = parser.parse <<-adsl
|
|
38
|
+
class Class {}
|
|
39
|
+
action do_something() {
|
|
40
|
+
var = allof(Class)
|
|
41
|
+
var = var
|
|
42
|
+
}
|
|
43
|
+
adsl
|
|
44
|
+
end
|
|
45
|
+
assert_equal 1, spec.actions.length
|
|
46
|
+
assert_equal 2, spec.actions.first.block.statements.length
|
|
47
|
+
var1 = spec.actions.first.statements.first.var
|
|
48
|
+
assert_equal var1, spec.actions.first.statements.last.objset
|
|
49
|
+
var2 = spec.actions.first.statements.last.var
|
|
50
|
+
assert var1 != var2
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def test_action__context_difference
|
|
54
|
+
context1 = ASTTypecheckResolveContext.new
|
|
55
|
+
context1.push_frame
|
|
56
|
+
|
|
57
|
+
a1 = DSVariable.new :name => 'a'
|
|
58
|
+
a2 = DSVariable.new :name => 'a'
|
|
59
|
+
b = DSVariable.new :name => 'b'
|
|
60
|
+
b2 = DSVariable.new :name => 'b'
|
|
61
|
+
|
|
62
|
+
context1.define_var a1, true
|
|
63
|
+
context1.define_var b, true
|
|
64
|
+
|
|
65
|
+
context2 = context1.dup
|
|
66
|
+
|
|
67
|
+
context2.redefine_var a2, false
|
|
68
|
+
|
|
69
|
+
assert_equal({"a" => [a1, a2]}, ASTTypecheckResolveContext.context_vars_that_differ(context1, context2))
|
|
70
|
+
|
|
71
|
+
context3 = context2.dup
|
|
72
|
+
assert_equal({"a" => [a1, a2, a2]}, ASTTypecheckResolveContext.context_vars_that_differ(context1, context2, context3))
|
|
73
|
+
|
|
74
|
+
context3.redefine_var b2, false
|
|
75
|
+
assert_equal({"a" => [a1, a2, a2], "b" => [b, b, b2]}, ASTTypecheckResolveContext.context_vars_that_differ(context1, context2, context3))
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def test_action__all_stmts_no_subblocks
|
|
79
|
+
parser = ADSLParser.new
|
|
80
|
+
spec = nil
|
|
81
|
+
assert_nothing_raised ADSLError do
|
|
82
|
+
spec = parser.parse <<-adsl
|
|
83
|
+
class Class { 0+ Class relation }
|
|
84
|
+
action do_something() {
|
|
85
|
+
var = create(Class)
|
|
86
|
+
create(Class)
|
|
87
|
+
delete var
|
|
88
|
+
var.relation += var
|
|
89
|
+
var.relation -= var
|
|
90
|
+
}
|
|
91
|
+
adsl
|
|
92
|
+
end
|
|
93
|
+
assert_equal 1, spec.actions.length
|
|
94
|
+
assert_equal 'do_something', spec.actions.first.name
|
|
95
|
+
statements = spec.actions.first.block.statements
|
|
96
|
+
assert_equal 6, statements.length
|
|
97
|
+
relation = spec.classes.first.relations.first
|
|
98
|
+
|
|
99
|
+
assert_equal spec.classes.first, statements[0].klass
|
|
100
|
+
|
|
101
|
+
var = statements[1].var
|
|
102
|
+
assert !var.nil?
|
|
103
|
+
assert_equal 'var', var.name
|
|
104
|
+
|
|
105
|
+
assert_equal spec.classes.first, statements[2].klass
|
|
106
|
+
|
|
107
|
+
assert_equal var, statements[3].objset
|
|
108
|
+
|
|
109
|
+
assert_equal var, statements[4].objset1
|
|
110
|
+
assert_equal var, statements[4].objset2
|
|
111
|
+
assert_equal relation, statements[4].relation
|
|
112
|
+
|
|
113
|
+
assert_equal var, statements[5].objset1
|
|
114
|
+
assert_equal var, statements[5].objset2
|
|
115
|
+
assert_equal relation, statements[5].relation
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def test_action__multiple_creates_in_single_stmt
|
|
119
|
+
parser = ADSLParser.new
|
|
120
|
+
spec = nil
|
|
121
|
+
assert_nothing_raised ADSLError do
|
|
122
|
+
spec = parser.parse <<-adsl
|
|
123
|
+
class Class { 0+ Class relation}
|
|
124
|
+
action do_something() {
|
|
125
|
+
create(Class).relation += create(Class)
|
|
126
|
+
}
|
|
127
|
+
adsl
|
|
128
|
+
end
|
|
129
|
+
statements = spec.actions.first.block.statements
|
|
130
|
+
assert_equal 3, statements.length
|
|
131
|
+
assert_equal spec.classes.first, statements[0].klass
|
|
132
|
+
assert_equal spec.classes.first, statements[1].klass
|
|
133
|
+
end
|
|
134
|
+
|
|
135
|
+
def test_action__args_typecheck
|
|
136
|
+
parser = ADSLParser.new
|
|
137
|
+
spec = nil
|
|
138
|
+
assert_nothing_raised ADSLError do
|
|
139
|
+
spec = parser.parse <<-adsl
|
|
140
|
+
class Class {}
|
|
141
|
+
action do_something(0+ Class var1) {
|
|
142
|
+
var2 = var1
|
|
143
|
+
}
|
|
144
|
+
adsl
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
klass = spec.classes.first
|
|
148
|
+
var1 = spec.actions.first.args.first
|
|
149
|
+
var2 = spec.actions.first.statements.first.var
|
|
150
|
+
|
|
151
|
+
assert_equal klass, var1.type
|
|
152
|
+
assert_equal klass, var2.type
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def test_action__args_multiple
|
|
156
|
+
parser = ADSLParser.new
|
|
157
|
+
spec = nil
|
|
158
|
+
assert_nothing_raised ADSLError do
|
|
159
|
+
spec = parser.parse <<-adsl
|
|
160
|
+
class Class1 {}
|
|
161
|
+
class Class2 {}
|
|
162
|
+
class Class3 {}
|
|
163
|
+
action do_something(0..1 Class1 var1, 1 Class2 var2, 1+ Class3 var3) {
|
|
164
|
+
}
|
|
165
|
+
adsl
|
|
166
|
+
end
|
|
167
|
+
assert_equal ['var1', 'var2', 'var3'], spec.actions.first.args.map{ |v| v.name }
|
|
168
|
+
assert_equal spec.classes, spec.actions.first.args.map{ |v| v.type }
|
|
169
|
+
assert_equal [[0, 1], [1, 1], [1, 1.0/0.0]], spec.actions.first.cardinalities
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
def test_action__createtup_deletetup_typecheck
|
|
173
|
+
['+=', '-='].each do |operator|
|
|
174
|
+
parser = ADSLParser.new
|
|
175
|
+
spec = nil
|
|
176
|
+
assert_nothing_raised ADSLError do
|
|
177
|
+
spec = parser.parse <<-adsl
|
|
178
|
+
class Class { 1 Class rel }
|
|
179
|
+
action blah() {
|
|
180
|
+
allof(Class).rel #{operator} allof(Class)
|
|
181
|
+
}
|
|
182
|
+
adsl
|
|
183
|
+
end
|
|
184
|
+
stmt = spec.actions.first.block.statements.first
|
|
185
|
+
assert_equal spec.classes.first, stmt.objset1.klass
|
|
186
|
+
assert_equal spec.classes.first, stmt.objset2.klass
|
|
187
|
+
assert_equal spec.classes.first.relations.first, stmt.relation
|
|
188
|
+
|
|
189
|
+
assert_raise ADSLError do
|
|
190
|
+
parser.parse <<-adsl
|
|
191
|
+
class Class1 { 1 Class1 rel }
|
|
192
|
+
class Class2 {}
|
|
193
|
+
action blah() {
|
|
194
|
+
allof(Class2).rel #{operator} allof(Class1)
|
|
195
|
+
}
|
|
196
|
+
adsl
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
assert_raise ADSLError do
|
|
200
|
+
parser.parse <<-adsl
|
|
201
|
+
class Class1 { 1 Class1 rel }
|
|
202
|
+
class Class2 {}
|
|
203
|
+
action blah() {
|
|
204
|
+
allof(Class1).rel #{operator} allof(Class2)
|
|
205
|
+
}
|
|
206
|
+
adsl
|
|
207
|
+
end
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
def test_action__superclass_createtup_deletetup_typecheck
|
|
212
|
+
parser = ADSLParser.new
|
|
213
|
+
['+=', '-='].each do |operator|
|
|
214
|
+
spec = nil
|
|
215
|
+
assert_nothing_raised ADSLError do
|
|
216
|
+
spec = parser.parse <<-adsl
|
|
217
|
+
class Super { 1 Super rel }
|
|
218
|
+
class Sub extends Super {}
|
|
219
|
+
action blah() {
|
|
220
|
+
allof(Super).rel #{operator} allof(Sub)
|
|
221
|
+
}
|
|
222
|
+
adsl
|
|
223
|
+
end
|
|
224
|
+
stmt = spec.actions.first.block.statements.first
|
|
225
|
+
assert_equal spec.classes[0], stmt.objset1.klass
|
|
226
|
+
assert_equal spec.classes[1], stmt.objset2.klass
|
|
227
|
+
assert_equal spec.classes[0].relations.first, stmt.relation
|
|
228
|
+
|
|
229
|
+
assert_nothing_raised ADSLError do
|
|
230
|
+
spec = parser.parse <<-adsl
|
|
231
|
+
class Super { 1 Super rel }
|
|
232
|
+
class Sub extends Super {}
|
|
233
|
+
action blah() {
|
|
234
|
+
allof(Sub).rel #{operator} allof(Sub)
|
|
235
|
+
}
|
|
236
|
+
adsl
|
|
237
|
+
end
|
|
238
|
+
stmt = spec.actions.first.block.statements.first
|
|
239
|
+
assert_equal spec.classes[1], stmt.objset1.klass
|
|
240
|
+
assert_equal spec.classes[1], stmt.objset2.klass
|
|
241
|
+
assert_equal spec.classes[0].relations.first, stmt.relation
|
|
242
|
+
|
|
243
|
+
assert_nothing_raised ADSLError do
|
|
244
|
+
spec = parser.parse <<-adsl
|
|
245
|
+
class Super {}
|
|
246
|
+
class Sub extends Super { 1 Super rel }
|
|
247
|
+
action blah() {
|
|
248
|
+
allof(Sub).rel #{operator} allof(Sub)
|
|
249
|
+
}
|
|
250
|
+
adsl
|
|
251
|
+
end
|
|
252
|
+
stmt = spec.actions.first.block.statements.first
|
|
253
|
+
assert_equal spec.classes[1], stmt.objset1.klass
|
|
254
|
+
assert_equal spec.classes[1], stmt.objset2.klass
|
|
255
|
+
assert_equal spec.classes[1].relations.first, stmt.relation
|
|
256
|
+
|
|
257
|
+
assert_raise ADSLError do
|
|
258
|
+
parser.parse <<-adsl
|
|
259
|
+
class Super {}
|
|
260
|
+
class Sub extends Super { 1 Sub rel }
|
|
261
|
+
action blah() {
|
|
262
|
+
allof(Super).rel #{operator} allof(Super)
|
|
263
|
+
}
|
|
264
|
+
adsl
|
|
265
|
+
end
|
|
266
|
+
|
|
267
|
+
assert_raise ADSLError do
|
|
268
|
+
parser.parse <<-adsl
|
|
269
|
+
class Super {}
|
|
270
|
+
class Sub extends Super { 1 Sub rel }
|
|
271
|
+
action blah() {
|
|
272
|
+
allof(Sub).rel #{operator} allof(Super)
|
|
273
|
+
}
|
|
274
|
+
adsl
|
|
275
|
+
end
|
|
276
|
+
end
|
|
277
|
+
end
|
|
278
|
+
|
|
279
|
+
def test_action__superclass_settup_typecheck
|
|
280
|
+
parser = ADSLParser.new
|
|
281
|
+
|
|
282
|
+
spec = nil
|
|
283
|
+
assert_nothing_raised ADSLError do
|
|
284
|
+
spec = parser.parse <<-adsl
|
|
285
|
+
class Super { 1 Super rel }
|
|
286
|
+
class Sub extends Super {}
|
|
287
|
+
action blah() {
|
|
288
|
+
allof(Super).rel = allof(Sub)
|
|
289
|
+
}
|
|
290
|
+
adsl
|
|
291
|
+
end
|
|
292
|
+
stmt1 = spec.actions.first.block.statements.first
|
|
293
|
+
stmt2 = spec.actions.first.block.statements.last
|
|
294
|
+
assert_equal spec.classes[0], stmt1.objset1.klass
|
|
295
|
+
assert_equal spec.classes[0], stmt1.objset2.klass
|
|
296
|
+
assert_equal spec.classes[0].relations.first, stmt1.relation
|
|
297
|
+
assert_equal spec.classes[0], stmt2.objset1.klass
|
|
298
|
+
assert_equal spec.classes[1], stmt2.objset2.klass
|
|
299
|
+
assert_equal spec.classes[0].relations.first, stmt2.relation
|
|
300
|
+
|
|
301
|
+
assert_nothing_raised ADSLError do
|
|
302
|
+
spec = parser.parse <<-adsl
|
|
303
|
+
class Super { 1 Super rel }
|
|
304
|
+
class Sub extends Super {}
|
|
305
|
+
action blah() {
|
|
306
|
+
allof(Sub).rel = allof(Sub)
|
|
307
|
+
}
|
|
308
|
+
adsl
|
|
309
|
+
end
|
|
310
|
+
stmt1 = spec.actions.first.block.statements.first
|
|
311
|
+
stmt2 = spec.actions.first.block.statements.last
|
|
312
|
+
assert_equal spec.classes[1], stmt1.objset1.klass
|
|
313
|
+
assert_equal spec.classes[0], stmt1.objset2.klass
|
|
314
|
+
assert_equal spec.classes[0].relations.first, stmt1.relation
|
|
315
|
+
assert_equal spec.classes[1], stmt2.objset1.klass
|
|
316
|
+
assert_equal spec.classes[1], stmt2.objset2.klass
|
|
317
|
+
assert_equal spec.classes[0].relations.first, stmt2.relation
|
|
318
|
+
|
|
319
|
+
assert_nothing_raised ADSLError do
|
|
320
|
+
spec = parser.parse <<-adsl
|
|
321
|
+
class Super {}
|
|
322
|
+
class Sub extends Super { 1 Super rel }
|
|
323
|
+
action blah() {
|
|
324
|
+
allof(Sub).rel = allof(Sub)
|
|
325
|
+
}
|
|
326
|
+
adsl
|
|
327
|
+
end
|
|
328
|
+
stmt1 = spec.actions.first.block.statements.first
|
|
329
|
+
stmt2 = spec.actions.first.block.statements.last
|
|
330
|
+
assert_equal spec.classes[1], stmt1.objset1.klass
|
|
331
|
+
assert_equal spec.classes[0], stmt1.objset2.klass
|
|
332
|
+
assert_equal spec.classes[1].relations.first, stmt1.relation
|
|
333
|
+
assert_equal spec.classes[1], stmt2.objset1.klass
|
|
334
|
+
assert_equal spec.classes[1], stmt2.objset2.klass
|
|
335
|
+
assert_equal spec.classes[1].relations.first, stmt2.relation
|
|
336
|
+
|
|
337
|
+
assert_raise ADSLError do
|
|
338
|
+
parser.parse <<-adsl
|
|
339
|
+
class Super {}
|
|
340
|
+
class Sub extends Super { 1 Sub rel }
|
|
341
|
+
action blah() {
|
|
342
|
+
allof(Super).rel = allof(Super)
|
|
343
|
+
}
|
|
344
|
+
adsl
|
|
345
|
+
end
|
|
346
|
+
|
|
347
|
+
assert_raise ADSLError do
|
|
348
|
+
parser.parse <<-adsl
|
|
349
|
+
class Super {}
|
|
350
|
+
class Sub extends Super { 1 Sub rel }
|
|
351
|
+
action blah() {
|
|
352
|
+
allof(Sub).rel = allof(Super)
|
|
353
|
+
}
|
|
354
|
+
adsl
|
|
355
|
+
end
|
|
356
|
+
end
|
|
357
|
+
|
|
358
|
+
def test_action__args_cardinality
|
|
359
|
+
parser = ADSLParser.new
|
|
360
|
+
assert_nothing_raised ADSLError do
|
|
361
|
+
spec = parser.parse <<-adsl
|
|
362
|
+
class Class {}
|
|
363
|
+
action do_something(0..1 Class var1) {
|
|
364
|
+
}
|
|
365
|
+
adsl
|
|
366
|
+
spec = parser.parse <<-adsl
|
|
367
|
+
class Class {}
|
|
368
|
+
action do_something(1 Class var1) {
|
|
369
|
+
}
|
|
370
|
+
adsl
|
|
371
|
+
spec = parser.parse <<-adsl
|
|
372
|
+
class Class {}
|
|
373
|
+
action do_something(1..1 Class var1) {
|
|
374
|
+
}
|
|
375
|
+
adsl
|
|
376
|
+
spec = parser.parse <<-adsl
|
|
377
|
+
class Class {}
|
|
378
|
+
action do_something(0+ Class var1) {
|
|
379
|
+
}
|
|
380
|
+
adsl
|
|
381
|
+
spec = parser.parse <<-adsl
|
|
382
|
+
class Class {}
|
|
383
|
+
action do_something(1+ Class var1) {
|
|
384
|
+
}
|
|
385
|
+
adsl
|
|
386
|
+
end
|
|
387
|
+
assert_raise do
|
|
388
|
+
parser.parse <<-adsl
|
|
389
|
+
class Class{}
|
|
390
|
+
action do_something(1..0)
|
|
391
|
+
adsl
|
|
392
|
+
end
|
|
393
|
+
assert_raise do
|
|
394
|
+
parser.parse <<-adsl
|
|
395
|
+
class Class{}
|
|
396
|
+
action do_something(0)
|
|
397
|
+
adsl
|
|
398
|
+
end
|
|
399
|
+
assert_raise do
|
|
400
|
+
parser.parse <<-adsl
|
|
401
|
+
class Class{}
|
|
402
|
+
action do_something(0..0)
|
|
403
|
+
adsl
|
|
404
|
+
end
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
def test_action__ssa_by_default
|
|
408
|
+
parser = ADSLParser.new
|
|
409
|
+
spec = nil
|
|
410
|
+
assert_nothing_raised ADSLError do
|
|
411
|
+
spec = parser.parse <<-adsl
|
|
412
|
+
class Class {}
|
|
413
|
+
action do_something(0+ Class var1, 0+ Class var2) {
|
|
414
|
+
var2 = var1
|
|
415
|
+
}
|
|
416
|
+
adsl
|
|
417
|
+
end
|
|
418
|
+
|
|
419
|
+
arg1 = spec.actions.first.args.first
|
|
420
|
+
arg2 = spec.actions.first.args.last
|
|
421
|
+
redefined = spec.actions.first.statements.first.var
|
|
422
|
+
|
|
423
|
+
assert arg1 != arg2
|
|
424
|
+
assert arg2 != redefined
|
|
425
|
+
end
|
|
426
|
+
|
|
427
|
+
def test_action__allof_typecheck
|
|
428
|
+
parser = ADSLParser.new
|
|
429
|
+
spec = nil
|
|
430
|
+
assert_nothing_raised ADSLError do
|
|
431
|
+
spec = parser.parse <<-adsl
|
|
432
|
+
class Class { 0+ Class relation }
|
|
433
|
+
action do_something() {
|
|
434
|
+
var = allof(Class)
|
|
435
|
+
var.relation -= var
|
|
436
|
+
}
|
|
437
|
+
adsl
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
assert_equal 1, spec.actions.length
|
|
441
|
+
klass = spec.classes.first
|
|
442
|
+
relation = spec.classes.first.relations.first
|
|
443
|
+
|
|
444
|
+
assert_equal relation, spec.actions.first.block.statements.last.relation
|
|
445
|
+
|
|
446
|
+
assert_raise ADSLError do
|
|
447
|
+
parser.parse <<-adsl
|
|
448
|
+
class Class { 0+ Class relation }
|
|
449
|
+
class Class2 {}
|
|
450
|
+
action do_something() {
|
|
451
|
+
var1 = allof(Class)
|
|
452
|
+
var2 = allof(Class2)
|
|
453
|
+
var1.relation -= var2
|
|
454
|
+
}
|
|
455
|
+
adsl
|
|
456
|
+
end
|
|
457
|
+
end
|
|
458
|
+
|
|
459
|
+
def test_action__subset_typecheck
|
|
460
|
+
parser = ADSLParser.new
|
|
461
|
+
spec = nil
|
|
462
|
+
assert_nothing_raised ADSLError do
|
|
463
|
+
spec = parser.parse <<-adsl
|
|
464
|
+
class Class { 0+ Class relation }
|
|
465
|
+
action do_something() {
|
|
466
|
+
var = subset(allof(Class))
|
|
467
|
+
var.relation -= var
|
|
468
|
+
}
|
|
469
|
+
adsl
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
assert_equal 1, spec.actions.length
|
|
473
|
+
klass = spec.classes.first
|
|
474
|
+
relation = spec.classes.first.relations.first
|
|
475
|
+
|
|
476
|
+
assert_equal relation, spec.actions.first.block.statements.last.relation
|
|
477
|
+
|
|
478
|
+
assert_raise ADSLError do
|
|
479
|
+
parser.parse <<-adsl
|
|
480
|
+
class Class { 0+ Class relation }
|
|
481
|
+
class Class2 {}
|
|
482
|
+
action do_something() {
|
|
483
|
+
var1 = allof(Class)
|
|
484
|
+
var2 = subset(allof(Class2))
|
|
485
|
+
var1.relation -= var2
|
|
486
|
+
}
|
|
487
|
+
adsl
|
|
488
|
+
end
|
|
489
|
+
end
|
|
490
|
+
|
|
491
|
+
def test_action__oneof_typecheck
|
|
492
|
+
parser = ADSLParser.new
|
|
493
|
+
spec = nil
|
|
494
|
+
assert_nothing_raised ADSLError do
|
|
495
|
+
spec = parser.parse <<-adsl
|
|
496
|
+
class Class { 0+ Class relation }
|
|
497
|
+
action do_something() {
|
|
498
|
+
var = oneof(allof(Class))
|
|
499
|
+
var.relation -= var
|
|
500
|
+
}
|
|
501
|
+
adsl
|
|
502
|
+
end
|
|
503
|
+
|
|
504
|
+
assert_equal 1, spec.actions.length
|
|
505
|
+
klass = spec.classes.first
|
|
506
|
+
relation = spec.classes.first.relations.first
|
|
507
|
+
|
|
508
|
+
assert_equal relation, spec.actions.first.block.statements.last.relation
|
|
509
|
+
|
|
510
|
+
assert_raise ADSLError do
|
|
511
|
+
parser.parse <<-adsl
|
|
512
|
+
class Class { 0+ Class relation }
|
|
513
|
+
class Class2 {}
|
|
514
|
+
action do_something() {
|
|
515
|
+
var1 = allof(Class)
|
|
516
|
+
var2 = oneof(allof(Class2))
|
|
517
|
+
var1.relation -= var2
|
|
518
|
+
}
|
|
519
|
+
adsl
|
|
520
|
+
end
|
|
521
|
+
end
|
|
522
|
+
|
|
523
|
+
def test_action__deref_typecheck
|
|
524
|
+
parser = ADSLParser.new
|
|
525
|
+
spec = nil
|
|
526
|
+
assert_nothing_raised ADSLError do
|
|
527
|
+
spec = parser.parse <<-adsl
|
|
528
|
+
class Class1 { 0+ Class2 relation }
|
|
529
|
+
class Class2 { 0+ Class2 other_relation }
|
|
530
|
+
action do_something() {
|
|
531
|
+
allof(Class1).relation.other_relation -= allof(Class2)
|
|
532
|
+
}
|
|
533
|
+
adsl
|
|
534
|
+
end
|
|
535
|
+
|
|
536
|
+
assert_equal 1, spec.actions.length
|
|
537
|
+
klass2 = spec.classes.last
|
|
538
|
+
relation = klass2.relations.first
|
|
539
|
+
|
|
540
|
+
stmt = spec.actions.first.block.statements.last
|
|
541
|
+
assert_equal klass2, stmt.objset1.type
|
|
542
|
+
assert_equal relation, stmt.relation
|
|
543
|
+
|
|
544
|
+
assert_raise ADSLError do
|
|
545
|
+
parser.parse <<-adsl
|
|
546
|
+
class Class1 { 0+ Class2 relation }
|
|
547
|
+
class Class2 { 0+ Class2 other_relation }
|
|
548
|
+
action do_something() {
|
|
549
|
+
allof(Class1).relation.relation -= allof(Class2)
|
|
550
|
+
}
|
|
551
|
+
adsl
|
|
552
|
+
end
|
|
553
|
+
end
|
|
554
|
+
|
|
555
|
+
def test_action__deref_superclass_typecheck
|
|
556
|
+
parser = ADSLParser.new
|
|
557
|
+
spec = nil
|
|
558
|
+
|
|
559
|
+
assert_nothing_raised ADSLError do
|
|
560
|
+
spec = parser.parse <<-adsl
|
|
561
|
+
class Class1 { 0+ Class2 relation }
|
|
562
|
+
class Class2 extends Class1 { 0+ Class2 other_relation }
|
|
563
|
+
action do_something() {
|
|
564
|
+
allof(Class1).relation.other_relation -= allof(Class2)
|
|
565
|
+
}
|
|
566
|
+
adsl
|
|
567
|
+
end
|
|
568
|
+
klass2 = spec.classes.last
|
|
569
|
+
relation = klass2.relations.first
|
|
570
|
+
stmt = spec.actions.first.block.statements.last
|
|
571
|
+
assert_equal klass2, stmt.objset1.type
|
|
572
|
+
assert_equal relation, stmt.relation
|
|
573
|
+
|
|
574
|
+
assert_nothing_raised ADSLError do
|
|
575
|
+
spec = parser.parse <<-adsl
|
|
576
|
+
class Class1 { 0+ Class2 relation }
|
|
577
|
+
class Class2 extends Class1 { 0+ Class2 other_relation }
|
|
578
|
+
action do_something() {
|
|
579
|
+
allof(Class2).relation.other_relation -= allof(Class2)
|
|
580
|
+
}
|
|
581
|
+
adsl
|
|
582
|
+
end
|
|
583
|
+
klass2 = spec.classes.last
|
|
584
|
+
relation = klass2.relations.first
|
|
585
|
+
stmt = spec.actions.first.block.statements.last
|
|
586
|
+
assert_equal klass2, stmt.objset1.type
|
|
587
|
+
assert_equal relation, stmt.relation
|
|
588
|
+
end
|
|
589
|
+
|
|
590
|
+
def test_action__subblocks
|
|
591
|
+
parser = ADSLParser.new
|
|
592
|
+
spec = parser.parse <<-adsl
|
|
593
|
+
class Class { 0+ Class relation }
|
|
594
|
+
action do_something() {
|
|
595
|
+
var = allof(Class)
|
|
596
|
+
foreach subvar: var {
|
|
597
|
+
var.relation -= subvar
|
|
598
|
+
}
|
|
599
|
+
either {
|
|
600
|
+
delete var
|
|
601
|
+
} or {
|
|
602
|
+
create(Class)
|
|
603
|
+
}
|
|
604
|
+
foreach subvar: var {}
|
|
605
|
+
}
|
|
606
|
+
adsl
|
|
607
|
+
|
|
608
|
+
assert_equal 1, spec.actions.length
|
|
609
|
+
stmts = spec.actions.first.block.statements
|
|
610
|
+
var = stmts[0].var
|
|
611
|
+
klass = spec.classes.first
|
|
612
|
+
|
|
613
|
+
assert_equal var, stmts[1].objset
|
|
614
|
+
|
|
615
|
+
assert_equal var, stmts[2].blocks[0].statements.first.objset
|
|
616
|
+
|
|
617
|
+
assert_equal klass, stmts[2].blocks[1].statements.first.klass
|
|
618
|
+
end
|
|
619
|
+
|
|
620
|
+
def test_action__subblocks_dont_undefine_variables
|
|
621
|
+
parser = ADSLParser.new
|
|
622
|
+
assert_nothing_raised ADSLError do
|
|
623
|
+
parser.parse <<-adsl
|
|
624
|
+
class Class {}
|
|
625
|
+
action do_something() {
|
|
626
|
+
var = allof(Class)
|
|
627
|
+
either {
|
|
628
|
+
var = allof(Class)
|
|
629
|
+
} or {
|
|
630
|
+
}
|
|
631
|
+
var = var
|
|
632
|
+
}
|
|
633
|
+
adsl
|
|
634
|
+
end
|
|
635
|
+
end
|
|
636
|
+
|
|
637
|
+
def test_action__types_are_static
|
|
638
|
+
parser = ADSLParser.new
|
|
639
|
+
assert_raise ADSLError do
|
|
640
|
+
parser.parse <<-adsl
|
|
641
|
+
class Class {}
|
|
642
|
+
class Class2 {}
|
|
643
|
+
action do_something() {
|
|
644
|
+
var = allof(Class)
|
|
645
|
+
var = allof(Class2)
|
|
646
|
+
}
|
|
647
|
+
adsl
|
|
648
|
+
end
|
|
649
|
+
end
|
|
650
|
+
|
|
651
|
+
def test_action__either_variable_number_of_blocks
|
|
652
|
+
parser = ADSLParser.new
|
|
653
|
+
assert_raise do
|
|
654
|
+
parser.parse <<-adsl
|
|
655
|
+
class Class {}
|
|
656
|
+
action do_something() {
|
|
657
|
+
either {}
|
|
658
|
+
}
|
|
659
|
+
adsl
|
|
660
|
+
end
|
|
661
|
+
spec = parser.parse <<-adsl
|
|
662
|
+
class Class {}
|
|
663
|
+
action do_something() {
|
|
664
|
+
either {
|
|
665
|
+
} or {
|
|
666
|
+
create(Class)
|
|
667
|
+
}
|
|
668
|
+
}
|
|
669
|
+
adsl
|
|
670
|
+
either = spec.actions.first.block.statements.first
|
|
671
|
+
assert_equal 2, either.blocks.length
|
|
672
|
+
assert_equal 0, either.blocks[0].statements.length
|
|
673
|
+
assert_equal 1, either.blocks[1].statements.length
|
|
674
|
+
|
|
675
|
+
spec = parser.parse <<-adsl
|
|
676
|
+
class Class {}
|
|
677
|
+
action do_something() {
|
|
678
|
+
either {
|
|
679
|
+
} or {
|
|
680
|
+
create(Class)
|
|
681
|
+
} or {
|
|
682
|
+
create(Class)
|
|
683
|
+
create(Class)
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
adsl
|
|
687
|
+
either = spec.actions.first.block.statements.first
|
|
688
|
+
assert_equal 3, either.blocks.length
|
|
689
|
+
assert_equal 0, either.blocks[0].statements.length
|
|
690
|
+
assert_equal 1, either.blocks[1].statements.length
|
|
691
|
+
assert_equal 2, either.blocks[2].statements.length
|
|
692
|
+
end
|
|
693
|
+
|
|
694
|
+
def test_action__unmatching_types_in_either
|
|
695
|
+
parser = ADSLParser.new
|
|
696
|
+
assert_raise ADSLError do
|
|
697
|
+
parser.parse <<-adsl
|
|
698
|
+
class Class {}
|
|
699
|
+
class Class2 {}
|
|
700
|
+
action do_something() {
|
|
701
|
+
var = allof(Class)
|
|
702
|
+
either {
|
|
703
|
+
var = allof(Class)
|
|
704
|
+
} or {
|
|
705
|
+
var = allof(Class2)
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
adsl
|
|
709
|
+
end
|
|
710
|
+
end
|
|
711
|
+
|
|
712
|
+
def test_action__unmatching_types_in_either_but_inside
|
|
713
|
+
parser = ADSLParser.new
|
|
714
|
+
assert_nothing_raised ADSLError do
|
|
715
|
+
parser.parse <<-adsl
|
|
716
|
+
class Class {}
|
|
717
|
+
class Class2 {}
|
|
718
|
+
action do_something() {
|
|
719
|
+
either {
|
|
720
|
+
var = allof(Class2)
|
|
721
|
+
} or {
|
|
722
|
+
var = allof(Class)
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
adsl
|
|
726
|
+
end
|
|
727
|
+
end
|
|
728
|
+
|
|
729
|
+
def test_action__foreach_iterator_var_typecheck
|
|
730
|
+
parser = ADSLParser.new
|
|
731
|
+
assert_nothing_raised ADSLError do
|
|
732
|
+
parser.parse <<-adsl
|
|
733
|
+
class Class { 0+ Class relation }
|
|
734
|
+
action do_something() {
|
|
735
|
+
foreach var: allof(Class) {
|
|
736
|
+
var.relation -= allof(Class)
|
|
737
|
+
}
|
|
738
|
+
}
|
|
739
|
+
adsl
|
|
740
|
+
end
|
|
741
|
+
assert_raise ADSLError do
|
|
742
|
+
parser.parse <<-adsl
|
|
743
|
+
class Class {}
|
|
744
|
+
class Class2 { 0+ Class2 relation }
|
|
745
|
+
action do_something() {
|
|
746
|
+
foreach var: allof(Class) {
|
|
747
|
+
var.relation -= allof(Class)
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
adsl
|
|
751
|
+
end
|
|
752
|
+
end
|
|
753
|
+
|
|
754
|
+
def test_action__foreach_does_not_redefine_var
|
|
755
|
+
parser = ADSLParser.new
|
|
756
|
+
assert_nothing_raised ADSLError do
|
|
757
|
+
spec = parser.parse <<-adsl
|
|
758
|
+
class Class { 0+ Class relation }
|
|
759
|
+
action do_something(0+ Class var) {
|
|
760
|
+
foreach var: var {
|
|
761
|
+
}
|
|
762
|
+
}
|
|
763
|
+
adsl
|
|
764
|
+
end
|
|
765
|
+
end
|
|
766
|
+
|
|
767
|
+
def test_action__flat_for_each_is_by_default
|
|
768
|
+
parser = ADSLParser.new
|
|
769
|
+
spec = parser.parse <<-adsl
|
|
770
|
+
class Class { 0+ Class relation }
|
|
771
|
+
action do_something() {
|
|
772
|
+
foreach o: allof(Class) {
|
|
773
|
+
}
|
|
774
|
+
}
|
|
775
|
+
adsl
|
|
776
|
+
assert spec.actions.first.statements.map{ |c| c.class }.include? DSFlatForEach
|
|
777
|
+
end
|
|
778
|
+
|
|
779
|
+
def test_action__either_lambda_works
|
|
780
|
+
parser = ADSLParser.new
|
|
781
|
+
spec = nil
|
|
782
|
+
assert_nothing_raised ADSLError do
|
|
783
|
+
spec = parser.parse <<-adsl
|
|
784
|
+
class Class { 0+ Class relation }
|
|
785
|
+
action do_something() {
|
|
786
|
+
var = allof(Class)
|
|
787
|
+
either {
|
|
788
|
+
var = subset(var)
|
|
789
|
+
} or {
|
|
790
|
+
var = subset(var)
|
|
791
|
+
}
|
|
792
|
+
var = var
|
|
793
|
+
}
|
|
794
|
+
adsl
|
|
795
|
+
end
|
|
796
|
+
|
|
797
|
+
action = spec.actions.first
|
|
798
|
+
orig_def = action.statements[0].var
|
|
799
|
+
inside_def1 = action.statements[1].blocks[0].statements.first.var
|
|
800
|
+
inside_def2 = action.statements[1].blocks[1].statements.first.var
|
|
801
|
+
after_def = action.statements[2].objset
|
|
802
|
+
|
|
803
|
+
assert orig_def != inside_def1
|
|
804
|
+
assert orig_def != inside_def2
|
|
805
|
+
assert inside_def1 != after_def
|
|
806
|
+
assert inside_def2 != after_def
|
|
807
|
+
assert inside_def1 != inside_def2
|
|
808
|
+
assert orig_def != after_def
|
|
809
|
+
assert_equal after_def.vars[0], inside_def1
|
|
810
|
+
assert_equal after_def.vars[1], inside_def2
|
|
811
|
+
end
|
|
812
|
+
|
|
813
|
+
def test_action__foreach_pre_lambda
|
|
814
|
+
get_pre_lambdas = lambda do |for_each|
|
|
815
|
+
for_each.block.statements.select do |stat|
|
|
816
|
+
stat.kind_of?(DSAssignment) and stat.objset.kind_of?(DSForEachPreLambdaObjset)
|
|
817
|
+
end
|
|
818
|
+
end
|
|
819
|
+
|
|
820
|
+
parser = ADSLParser.new
|
|
821
|
+
spec = parser.parse <<-adsl
|
|
822
|
+
class Class {}
|
|
823
|
+
action do_something() {
|
|
824
|
+
foreach var: allof(Class) {}
|
|
825
|
+
}
|
|
826
|
+
adsl
|
|
827
|
+
assert_equal 0, get_pre_lambdas.call(spec.actions.first.block.statements[0]).length
|
|
828
|
+
|
|
829
|
+
spec = parser.parse <<-adsl
|
|
830
|
+
class Class {}
|
|
831
|
+
action do_something() {
|
|
832
|
+
foreach var: allof(Class) {
|
|
833
|
+
var = allof(Class)
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
adsl
|
|
837
|
+
assert_equal 0, get_pre_lambdas.call(spec.actions.first.block.statements[0]).length
|
|
838
|
+
|
|
839
|
+
spec = parser.parse <<-adsl
|
|
840
|
+
class Class {}
|
|
841
|
+
action do_something() {
|
|
842
|
+
var = allof(Class)
|
|
843
|
+
foreach a: allof(Class) {
|
|
844
|
+
var = subset(var)
|
|
845
|
+
var = subset(var)
|
|
846
|
+
}
|
|
847
|
+
}
|
|
848
|
+
adsl
|
|
849
|
+
pre_lambdas = get_pre_lambdas.call(spec.actions.first.block.statements[1])
|
|
850
|
+
assert_equal 1, pre_lambdas.length
|
|
851
|
+
assert_equal spec.actions.first.block.statements[0].var, pre_lambdas.first.objset.before_var
|
|
852
|
+
assert_equal spec.actions.first.block.statements[1], pre_lambdas.first.objset.for_each
|
|
853
|
+
assert_equal spec.actions.first.block.statements[1].block.statements.last.var, pre_lambdas.first.objset.inside_var
|
|
854
|
+
|
|
855
|
+
spec = parser.parse <<-adsl
|
|
856
|
+
class Class {}
|
|
857
|
+
action do_something() {
|
|
858
|
+
var = allof(Class)
|
|
859
|
+
foreach var: allof(Class) {
|
|
860
|
+
var = allof(Class)
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
adsl
|
|
864
|
+
assert_equal 0, get_pre_lambdas.call(spec.actions.first.block.statements[1]).length
|
|
865
|
+
end
|
|
866
|
+
|
|
867
|
+
def test_action__empty_set__typecheck
|
|
868
|
+
parser = ADSLParser.new
|
|
869
|
+
|
|
870
|
+
assert_nothing_raised ADSLError do
|
|
871
|
+
parser.parse <<-adsl
|
|
872
|
+
class Class {
|
|
873
|
+
1 Class klass
|
|
874
|
+
}
|
|
875
|
+
class Class2 {
|
|
876
|
+
1 Class2 klass2
|
|
877
|
+
}
|
|
878
|
+
action do_something() {
|
|
879
|
+
allof(Class).klass += empty
|
|
880
|
+
allof(Class2).klass2 += empty
|
|
881
|
+
}
|
|
882
|
+
adsl
|
|
883
|
+
end
|
|
884
|
+
|
|
885
|
+
assert_raise ADSLError do
|
|
886
|
+
parser.parse <<-adsl
|
|
887
|
+
action do_something() {
|
|
888
|
+
empty.some_relation += empty
|
|
889
|
+
}
|
|
890
|
+
adsl
|
|
891
|
+
end
|
|
892
|
+
|
|
893
|
+
assert_nothing_raised ADSLError do
|
|
894
|
+
parser.parse <<-adsl
|
|
895
|
+
class Class {
|
|
896
|
+
1 Class klass
|
|
897
|
+
}
|
|
898
|
+
action do_something() {
|
|
899
|
+
foreach c: empty {
|
|
900
|
+
allof(Class).klass += c
|
|
901
|
+
}
|
|
902
|
+
}
|
|
903
|
+
adsl
|
|
904
|
+
end
|
|
905
|
+
|
|
906
|
+
assert_raise ADSLError do
|
|
907
|
+
parser.parse <<-adsl
|
|
908
|
+
class Class {
|
|
909
|
+
1 Class klass
|
|
910
|
+
}
|
|
911
|
+
action do_something() {
|
|
912
|
+
foreach c: empty {
|
|
913
|
+
c.klass += allof(Class)
|
|
914
|
+
}
|
|
915
|
+
}
|
|
916
|
+
adsl
|
|
917
|
+
end
|
|
918
|
+
end
|
|
919
|
+
|
|
920
|
+
def test_action__empty_set_and_var_types
|
|
921
|
+
parser = ADSLParser.new
|
|
922
|
+
|
|
923
|
+
assert_nothing_raised ADSLError do
|
|
924
|
+
parser.parse <<-adsl
|
|
925
|
+
class Class {
|
|
926
|
+
1 Class klass
|
|
927
|
+
}
|
|
928
|
+
action do_something() {
|
|
929
|
+
a = empty
|
|
930
|
+
a = allof(Class)
|
|
931
|
+
a.klass += a
|
|
932
|
+
}
|
|
933
|
+
adsl
|
|
934
|
+
end
|
|
935
|
+
assert_nothing_raised ADSLError do
|
|
936
|
+
parser.parse <<-adsl
|
|
937
|
+
class Class {
|
|
938
|
+
1 Class klass
|
|
939
|
+
}
|
|
940
|
+
action do_something() {
|
|
941
|
+
a = empty
|
|
942
|
+
a = allof(Class)
|
|
943
|
+
a.klass += a
|
|
944
|
+
}
|
|
945
|
+
adsl
|
|
946
|
+
end
|
|
947
|
+
assert_nothing_raised ADSLError do
|
|
948
|
+
parser.parse <<-adsl
|
|
949
|
+
class Class {
|
|
950
|
+
1 Class klass
|
|
951
|
+
}
|
|
952
|
+
action do_something() {
|
|
953
|
+
a = allof(Class)
|
|
954
|
+
a = empty
|
|
955
|
+
a.klass += a
|
|
956
|
+
}
|
|
957
|
+
adsl
|
|
958
|
+
end
|
|
959
|
+
assert_nothing_raised ADSLError do
|
|
960
|
+
parser.parse <<-adsl
|
|
961
|
+
class Class {
|
|
962
|
+
1 Class klass
|
|
963
|
+
}
|
|
964
|
+
action do_something() {
|
|
965
|
+
a = allof(Class)
|
|
966
|
+
a = empty
|
|
967
|
+
b = a
|
|
968
|
+
b.klass += a
|
|
969
|
+
}
|
|
970
|
+
adsl
|
|
971
|
+
end
|
|
972
|
+
end
|
|
973
|
+
|
|
974
|
+
def test_action__entity_class_writes
|
|
975
|
+
parser = ADSLParser.new
|
|
976
|
+
spec = nil
|
|
977
|
+
assert_nothing_raised ADSLError do
|
|
978
|
+
spec = parser.parse <<-adsl
|
|
979
|
+
class Class {}
|
|
980
|
+
class Class2 {}
|
|
981
|
+
action do_something() {
|
|
982
|
+
create(Class)
|
|
983
|
+
}
|
|
984
|
+
adsl
|
|
985
|
+
end
|
|
986
|
+
assert_equal Set[spec.classes.first], spec.actions.first.block.list_entity_classes_written_to
|
|
987
|
+
|
|
988
|
+
assert_nothing_raised ADSLError do
|
|
989
|
+
spec = parser.parse <<-adsl
|
|
990
|
+
class Class {}
|
|
991
|
+
class Class2 {}
|
|
992
|
+
action do_something() {
|
|
993
|
+
create(Class)
|
|
994
|
+
either {
|
|
995
|
+
foreach a: allof(Class) {
|
|
996
|
+
delete allof(Class2)
|
|
997
|
+
}
|
|
998
|
+
} or {}
|
|
999
|
+
}
|
|
1000
|
+
adsl
|
|
1001
|
+
end
|
|
1002
|
+
assert_equal Set[*spec.classes], spec.actions.first.block.list_entity_classes_written_to
|
|
1003
|
+
assert_equal Set[spec.classes.first], spec.actions.first.block.statements.first.list_entity_classes_written_to
|
|
1004
|
+
assert_equal Set[spec.classes.second], spec.actions.first.block.statements.last.list_entity_classes_written_to
|
|
1005
|
+
end
|
|
1006
|
+
|
|
1007
|
+
def test_action__entity_class_reads
|
|
1008
|
+
parser = ADSLParser.new
|
|
1009
|
+
spec = nil
|
|
1010
|
+
assert_nothing_raised ADSLError do
|
|
1011
|
+
spec = parser.parse <<-adsl
|
|
1012
|
+
class Class {}
|
|
1013
|
+
class Class2 {}
|
|
1014
|
+
action do_something() {
|
|
1015
|
+
delete allof(Class)
|
|
1016
|
+
}
|
|
1017
|
+
adsl
|
|
1018
|
+
end
|
|
1019
|
+
assert_equal Set[spec.classes.first], spec.actions.first.block.list_entity_classes_read
|
|
1020
|
+
|
|
1021
|
+
assert_nothing_raised ADSLError do
|
|
1022
|
+
spec = parser.parse <<-adsl
|
|
1023
|
+
class Class {}
|
|
1024
|
+
class Class2 {}
|
|
1025
|
+
action do_something() {
|
|
1026
|
+
create(Class)
|
|
1027
|
+
either {
|
|
1028
|
+
foreach a: allof(Class) {
|
|
1029
|
+
delete allof(Class2)
|
|
1030
|
+
}
|
|
1031
|
+
} or {}
|
|
1032
|
+
}
|
|
1033
|
+
adsl
|
|
1034
|
+
end
|
|
1035
|
+
assert_equal Set[*spec.classes], spec.actions.first.block.list_entity_classes_read
|
|
1036
|
+
assert_equal Set[], spec.actions.first.block.statements.first.list_entity_classes_read
|
|
1037
|
+
assert_equal Set[*spec.classes], spec.actions.first.block.statements.last.list_entity_classes_read
|
|
1038
|
+
end
|
|
1039
|
+
end
|
|
1040
|
+
end
|