abstract_mapper 0.0.1
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 +7 -0
- data/.coveralls.yml +2 -0
- data/.gitignore +9 -0
- data/.metrics +9 -0
- data/.rspec +2 -0
- data/.rubocop.yml +2 -0
- data/.travis.yml +19 -0
- data/.yardopts +3 -0
- data/CHANGELOG.md +3 -0
- data/Gemfile +9 -0
- data/Guardfile +14 -0
- data/LICENSE +21 -0
- data/README.md +239 -0
- data/Rakefile +34 -0
- data/abstract_mapper.gemspec +26 -0
- data/config/metrics/STYLEGUIDE +230 -0
- data/config/metrics/cane.yml +5 -0
- data/config/metrics/churn.yml +6 -0
- data/config/metrics/flay.yml +2 -0
- data/config/metrics/metric_fu.yml +15 -0
- data/config/metrics/reek.yml +1 -0
- data/config/metrics/roodi.yml +24 -0
- data/config/metrics/rubocop.yml +76 -0
- data/config/metrics/saikuro.yml +3 -0
- data/config/metrics/simplecov.yml +6 -0
- data/config/metrics/yardstick.yml +37 -0
- data/lib/abstract_mapper/branch.rb +110 -0
- data/lib/abstract_mapper/builder.rb +84 -0
- data/lib/abstract_mapper/commands.rb +71 -0
- data/lib/abstract_mapper/dsl.rb +62 -0
- data/lib/abstract_mapper/errors/unknown_command.rb +25 -0
- data/lib/abstract_mapper/errors/wrong_node.rb +23 -0
- data/lib/abstract_mapper/errors/wrong_rule.rb +23 -0
- data/lib/abstract_mapper/functions.rb +76 -0
- data/lib/abstract_mapper/node.rb +76 -0
- data/lib/abstract_mapper/optimizer.rb +48 -0
- data/lib/abstract_mapper/pair_rule.rb +66 -0
- data/lib/abstract_mapper/rspec.rb +7 -0
- data/lib/abstract_mapper/rule.rb +52 -0
- data/lib/abstract_mapper/rules.rb +61 -0
- data/lib/abstract_mapper/settings.rb +95 -0
- data/lib/abstract_mapper/sole_rule.rb +58 -0
- data/lib/abstract_mapper/version.rb +9 -0
- data/lib/abstract_mapper.rb +82 -0
- data/lib/rspec/functions.rb +25 -0
- data/lib/rspec/mapper.rb +40 -0
- data/lib/rspec/nodes.rb +58 -0
- data/lib/rspec/rules.rb +59 -0
- data/spec/integration/faceter.rb +62 -0
- data/spec/integration/mapper_definition_spec.rb +33 -0
- data/spec/integration/rspec_examples_spec.rb +77 -0
- data/spec/spec_helper.rb +20 -0
- data/spec/unit/abstract_mapper/branch_spec.rb +126 -0
- data/spec/unit/abstract_mapper/builder_spec.rb +78 -0
- data/spec/unit/abstract_mapper/commands_spec.rb +105 -0
- data/spec/unit/abstract_mapper/dsl_spec.rb +82 -0
- data/spec/unit/abstract_mapper/errors/unknown_command_spec.rb +21 -0
- data/spec/unit/abstract_mapper/errors/wrong_node_spec.rb +21 -0
- data/spec/unit/abstract_mapper/errors/wrong_rule_spec.rb +23 -0
- data/spec/unit/abstract_mapper/functions/compact_spec.rb +25 -0
- data/spec/unit/abstract_mapper/functions/filter_spec.rb +26 -0
- data/spec/unit/abstract_mapper/functions/subclass_spec.rb +66 -0
- data/spec/unit/abstract_mapper/node_spec.rb +84 -0
- data/spec/unit/abstract_mapper/optimizer_spec.rb +48 -0
- data/spec/unit/abstract_mapper/pair_rule_spec.rb +59 -0
- data/spec/unit/abstract_mapper/rule_spec.rb +83 -0
- data/spec/unit/abstract_mapper/rules_spec.rb +88 -0
- data/spec/unit/abstract_mapper/settings_spec.rb +113 -0
- data/spec/unit/abstract_mapper/sole_rule_spec.rb +51 -0
- data/spec/unit/abstract_mapper_spec.rb +36 -0
- metadata +171 -0
@@ -0,0 +1,66 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require "abstract_mapper/rspec"
|
4
|
+
|
5
|
+
describe AbstractMapper::Functions, "#subclass?" do
|
6
|
+
|
7
|
+
let(:klass) { Class.new }
|
8
|
+
let(:modul) { Module.new }
|
9
|
+
|
10
|
+
it_behaves_like :transforming_immutable_data do
|
11
|
+
let(:arguments) { [:subclass?, klass] }
|
12
|
+
|
13
|
+
let(:input) { Class.new }
|
14
|
+
let(:output) { false }
|
15
|
+
end
|
16
|
+
|
17
|
+
it_behaves_like :transforming_immutable_data do
|
18
|
+
let(:arguments) { [:subclass?, klass] }
|
19
|
+
|
20
|
+
let(:input) { Class.new(Class.new(klass)) }
|
21
|
+
let(:output) { true }
|
22
|
+
end
|
23
|
+
|
24
|
+
it_behaves_like :transforming_immutable_data do
|
25
|
+
let(:arguments) { [:subclass?, modul] }
|
26
|
+
|
27
|
+
let(:input) { Class.new }
|
28
|
+
let(:output) { false }
|
29
|
+
end
|
30
|
+
|
31
|
+
it_behaves_like :transforming_immutable_data do
|
32
|
+
let(:arguments) { [:subclass?, modul] }
|
33
|
+
|
34
|
+
let(:input) { Class.new.send :include, modul }
|
35
|
+
let(:output) { true }
|
36
|
+
end
|
37
|
+
|
38
|
+
it_behaves_like :transforming_immutable_data do
|
39
|
+
let(:arguments) { [:subclass?, modul] }
|
40
|
+
|
41
|
+
let(:input) { Class.new.send :extend, modul }
|
42
|
+
let(:output) { false }
|
43
|
+
end
|
44
|
+
|
45
|
+
it_behaves_like :transforming_immutable_data do
|
46
|
+
let(:arguments) { [:subclass?, modul] }
|
47
|
+
|
48
|
+
let(:input) { Module.new }
|
49
|
+
let(:output) { false }
|
50
|
+
end
|
51
|
+
|
52
|
+
it_behaves_like :transforming_immutable_data do
|
53
|
+
let(:arguments) { [:subclass?, modul] }
|
54
|
+
|
55
|
+
let(:input) { Module.new.send :include, modul }
|
56
|
+
let(:output) { true }
|
57
|
+
end
|
58
|
+
|
59
|
+
it_behaves_like :transforming_immutable_data do
|
60
|
+
let(:arguments) { [:subclass?, modul] }
|
61
|
+
|
62
|
+
let(:input) { Module.new.send :extend, modul }
|
63
|
+
let(:output) { false }
|
64
|
+
end
|
65
|
+
|
66
|
+
end # describe AbstractMapper::Functions#subclass?
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
describe AbstractMapper::Node do
|
4
|
+
|
5
|
+
let(:test) { AbstractMapper::Test::Node = Class.new(described_class) }
|
6
|
+
let(:node) { test.new(*attributes) }
|
7
|
+
let(:attributes) { [:foo, :bar] }
|
8
|
+
|
9
|
+
describe ".new" do
|
10
|
+
|
11
|
+
subject { node }
|
12
|
+
it { is_expected.to be_frozen }
|
13
|
+
|
14
|
+
end # describe .new
|
15
|
+
|
16
|
+
describe "#attributes" do
|
17
|
+
|
18
|
+
subject { node.attributes }
|
19
|
+
|
20
|
+
it { is_expected.to eql attributes }
|
21
|
+
it { is_expected.to be_frozen }
|
22
|
+
|
23
|
+
it "doesn't freeze the source" do
|
24
|
+
expect { subject }.not_to change { attributes.frozen? }
|
25
|
+
end
|
26
|
+
|
27
|
+
end # describe #attributes
|
28
|
+
|
29
|
+
describe "#block" do
|
30
|
+
|
31
|
+
subject { node.block }
|
32
|
+
|
33
|
+
context "when block is absent" do
|
34
|
+
|
35
|
+
let(:node) { test.new(*attributes) }
|
36
|
+
it { is_expected.to eql nil }
|
37
|
+
|
38
|
+
end # context
|
39
|
+
|
40
|
+
context "when block is present" do
|
41
|
+
|
42
|
+
let(:block) { proc { :foo } }
|
43
|
+
let(:node) { test.new(*attributes, &block) }
|
44
|
+
it { is_expected.to eql block }
|
45
|
+
|
46
|
+
end # context
|
47
|
+
|
48
|
+
end # describe #block
|
49
|
+
|
50
|
+
describe "#to_s" do
|
51
|
+
|
52
|
+
subject { node.to_s }
|
53
|
+
|
54
|
+
context "without attributes" do
|
55
|
+
|
56
|
+
let(:node) { test.new }
|
57
|
+
it { is_expected.to eql "Node" }
|
58
|
+
|
59
|
+
end # context
|
60
|
+
|
61
|
+
context "with attributes" do
|
62
|
+
|
63
|
+
let(:node) { test.new(*attributes) }
|
64
|
+
it { is_expected.to eql "Node(:foo, :bar)" }
|
65
|
+
|
66
|
+
end # context
|
67
|
+
|
68
|
+
end # describe #to_s
|
69
|
+
|
70
|
+
describe "#inspect" do
|
71
|
+
|
72
|
+
subject { node.inspect }
|
73
|
+
it { is_expected.to eql "<Node(:foo, :bar)>" }
|
74
|
+
|
75
|
+
end # describe #inspect
|
76
|
+
|
77
|
+
describe "#transproc" do
|
78
|
+
|
79
|
+
subject { node.transproc[:foo] }
|
80
|
+
it { is_expected.to eql :foo }
|
81
|
+
|
82
|
+
end # describe #transproc
|
83
|
+
|
84
|
+
end # describe AbstractMapper::Node
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
describe AbstractMapper::Optimizer do
|
4
|
+
|
5
|
+
let(:optimizer) { test.new rules }
|
6
|
+
let(:test) { Class.new(described_class) }
|
7
|
+
let(:rules) { AbstractMapper::Rules.new }
|
8
|
+
|
9
|
+
describe ".new" do
|
10
|
+
|
11
|
+
subject { optimizer }
|
12
|
+
it { is_expected.to be_frozen }
|
13
|
+
|
14
|
+
end # describe .new
|
15
|
+
|
16
|
+
describe "#rules" do
|
17
|
+
|
18
|
+
subject { optimizer.rules }
|
19
|
+
it { is_expected.to eql rules }
|
20
|
+
|
21
|
+
end # describe #rules
|
22
|
+
|
23
|
+
describe "#update" do
|
24
|
+
|
25
|
+
subject { optimizer.update(tree) }
|
26
|
+
|
27
|
+
let(:rules) { AbstractMapper::Rules.new([rule]) }
|
28
|
+
let(:rule) { Class.new(AbstractMapper::PairRule) }
|
29
|
+
let(:tree) { AbstractMapper::Branch.new { [node3, node4] } }
|
30
|
+
let(:node1) { AbstractMapper::Node.new(1) }
|
31
|
+
let(:node2) { AbstractMapper::Node.new(2) }
|
32
|
+
let(:node3) { AbstractMapper::Node.new(3) }
|
33
|
+
let(:node4) { AbstractMapper::Test::Foo.new(4) { [node1, node2] } }
|
34
|
+
|
35
|
+
before { AbstractMapper::Test::Foo = Class.new(AbstractMapper::Branch) }
|
36
|
+
before { rule.send(:define_method, :optimize?) { true } }
|
37
|
+
before { rule.send(:define_method, :optimize) { nodes.reverse } }
|
38
|
+
|
39
|
+
it "optimizes the tree deeply" do
|
40
|
+
expect(tree.inspect)
|
41
|
+
.to eql "<Root [<Node(3)>, <Foo(4) [<Node(1)>, <Node(2)>]>]>"
|
42
|
+
expect(subject.inspect)
|
43
|
+
.to eql "<Root [<Foo(4) [<Node(2)>, <Node(1)>]>, <Node(3)>]>"
|
44
|
+
end
|
45
|
+
|
46
|
+
end # describe #update
|
47
|
+
|
48
|
+
end # describe AbstractMapper::Optimize
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
describe AbstractMapper::PairRule do
|
4
|
+
|
5
|
+
let(:rule) { test.new(left, right) }
|
6
|
+
let(:test) { AbstractMapper::Test::Rule = Class.new(described_class) }
|
7
|
+
let(:nodes) { [left, right] }
|
8
|
+
let(:left) { double }
|
9
|
+
let(:right) { double }
|
10
|
+
|
11
|
+
describe ".composer" do
|
12
|
+
|
13
|
+
subject { test.composer }
|
14
|
+
it { is_expected.to eql :compact }
|
15
|
+
|
16
|
+
end # describe .pair?
|
17
|
+
|
18
|
+
describe ".new" do
|
19
|
+
|
20
|
+
subject { rule }
|
21
|
+
|
22
|
+
it { is_expected.to be_kind_of AbstractMapper::Rule }
|
23
|
+
it { is_expected.to be_frozen }
|
24
|
+
|
25
|
+
it "requires second argument" do
|
26
|
+
expect { test.new(left) }.to raise_error(ArgumentError)
|
27
|
+
end
|
28
|
+
|
29
|
+
end # describe .new
|
30
|
+
|
31
|
+
describe "#left" do
|
32
|
+
|
33
|
+
subject { rule.left }
|
34
|
+
it { is_expected.to eql left }
|
35
|
+
|
36
|
+
end # describe #left
|
37
|
+
|
38
|
+
describe "#right" do
|
39
|
+
|
40
|
+
subject { rule.right }
|
41
|
+
it { is_expected.to eql right }
|
42
|
+
|
43
|
+
end # describe #right
|
44
|
+
|
45
|
+
describe "#transproc" do
|
46
|
+
|
47
|
+
before do
|
48
|
+
test.send(:define_method, :optimize?) { left == right }
|
49
|
+
test.send(:define_method, :optimize) { left + right }
|
50
|
+
end
|
51
|
+
|
52
|
+
subject { test.transproc[array] }
|
53
|
+
|
54
|
+
let(:array) { [1, 1, 2, 5] }
|
55
|
+
it { is_expected.to eql [4, 5] }
|
56
|
+
|
57
|
+
end # describe #transproc
|
58
|
+
|
59
|
+
end # describe AbstractMapper::PairRule
|
@@ -0,0 +1,83 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
describe AbstractMapper::Rule do
|
4
|
+
|
5
|
+
let(:rule) { test.new(*nodes) }
|
6
|
+
let(:test) { AbstractMapper::Test::Rule = Class.new(described_class) }
|
7
|
+
let(:nodes) { [node] }
|
8
|
+
let(:node) { double }
|
9
|
+
|
10
|
+
describe ".new" do
|
11
|
+
|
12
|
+
subject { rule }
|
13
|
+
it { is_expected.to be_frozen }
|
14
|
+
|
15
|
+
end # describe .new
|
16
|
+
|
17
|
+
describe "#nodes" do
|
18
|
+
|
19
|
+
subject { rule.nodes }
|
20
|
+
|
21
|
+
it { is_expected.to eql nodes }
|
22
|
+
it { is_expected.to be_frozen }
|
23
|
+
|
24
|
+
it "doesn't freeze the source" do
|
25
|
+
expect { subject }.not_to change { nodes.frozen? }
|
26
|
+
end
|
27
|
+
|
28
|
+
end # describe #nodes
|
29
|
+
|
30
|
+
describe "#call" do
|
31
|
+
|
32
|
+
subject { rule.call }
|
33
|
+
|
34
|
+
before { test.send(:define_method, :optimize?) { true } }
|
35
|
+
before { test.send(:define_method, :optimize) { [:foo] } }
|
36
|
+
|
37
|
+
context "when #optimize? returns true" do
|
38
|
+
|
39
|
+
before { test.send(:define_method, :optimize?) { true } }
|
40
|
+
it { is_expected.to eql [:foo] }
|
41
|
+
|
42
|
+
end # context
|
43
|
+
|
44
|
+
context "when #optimize? returns false" do
|
45
|
+
|
46
|
+
before { test.send(:define_method, :optimize?) { false } }
|
47
|
+
it { is_expected.to eql [node] }
|
48
|
+
|
49
|
+
end # context
|
50
|
+
|
51
|
+
context "when #optimize returns non-array" do
|
52
|
+
|
53
|
+
before { test.send(:define_method, :optimize) { :foo } }
|
54
|
+
it { is_expected.to eql [:foo] }
|
55
|
+
|
56
|
+
end # contex
|
57
|
+
|
58
|
+
context "when #optimize returns nils" do
|
59
|
+
|
60
|
+
before { test.send(:define_method, :optimize) { [nil, nil] } }
|
61
|
+
it { is_expected.to eql [] }
|
62
|
+
|
63
|
+
end # contex
|
64
|
+
|
65
|
+
end # describe #call
|
66
|
+
|
67
|
+
describe ".transproc" do
|
68
|
+
|
69
|
+
before do
|
70
|
+
test.send(:define_method, :optimize?) { true }
|
71
|
+
test.send(:define_method, :optimize) { nodes.reverse }
|
72
|
+
allow(test).to receive(:composer) { :compact }
|
73
|
+
end
|
74
|
+
|
75
|
+
subject { test.transproc[array] }
|
76
|
+
|
77
|
+
let(:array) { [1, 2, 3] }
|
78
|
+
|
79
|
+
it { is_expected.to eql [2, 3, 1] }
|
80
|
+
|
81
|
+
end # describe .transproc
|
82
|
+
|
83
|
+
end # describe AbstractMapper::Rule
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
describe AbstractMapper::Rules do
|
4
|
+
|
5
|
+
let(:rules) { described_class.new }
|
6
|
+
let(:foo) { AbstractMapper::Test::Foo = Class.new(AbstractMapper::SoleRule) }
|
7
|
+
let(:bar) { AbstractMapper::Test::Bar = Class.new(AbstractMapper::PairRule) }
|
8
|
+
|
9
|
+
describe ".new" do
|
10
|
+
|
11
|
+
subject { rules }
|
12
|
+
it { is_expected.to be_frozen }
|
13
|
+
|
14
|
+
end # describe .new
|
15
|
+
|
16
|
+
describe "#registry" do
|
17
|
+
|
18
|
+
subject { rules.registry }
|
19
|
+
|
20
|
+
context "by default" do
|
21
|
+
|
22
|
+
let(:rules) { described_class.new }
|
23
|
+
it { is_expected.to eql [] }
|
24
|
+
it { is_expected.to be_frozen }
|
25
|
+
|
26
|
+
end # context
|
27
|
+
|
28
|
+
context "initialized" do
|
29
|
+
|
30
|
+
let(:rules) { described_class.new registry }
|
31
|
+
let(:registry) { [foo, bar] }
|
32
|
+
|
33
|
+
it { is_expected.to eql registry }
|
34
|
+
it { is_expected.to be_frozen }
|
35
|
+
|
36
|
+
it "doesn't freezes the source" do
|
37
|
+
expect { subject }.not_to change { registry.frozen? }
|
38
|
+
end
|
39
|
+
|
40
|
+
end # context
|
41
|
+
|
42
|
+
end # describe #registry
|
43
|
+
|
44
|
+
describe "#<<" do
|
45
|
+
|
46
|
+
subject { rules << bar }
|
47
|
+
|
48
|
+
let(:rules) { described_class.new [foo] }
|
49
|
+
|
50
|
+
it "updates the registry" do
|
51
|
+
expect(subject).to be_kind_of described_class
|
52
|
+
expect(subject.registry).to eql [foo, bar]
|
53
|
+
end
|
54
|
+
|
55
|
+
end # describe #<<
|
56
|
+
|
57
|
+
describe "#[]" do
|
58
|
+
|
59
|
+
before do
|
60
|
+
foo.send(:define_method, :optimize?) { true }
|
61
|
+
foo.send(:define_method, :optimize) { node + 1 }
|
62
|
+
bar.send(:define_method, :optimize?) { left == right }
|
63
|
+
bar.send(:define_method, :optimize) { left + right }
|
64
|
+
end
|
65
|
+
|
66
|
+
context "when no rule is set" do
|
67
|
+
|
68
|
+
let(:nodes) { [1, 1, 2, 5] }
|
69
|
+
|
70
|
+
subject { rules[nodes] }
|
71
|
+
it { is_expected.to eql nodes }
|
72
|
+
|
73
|
+
end # context
|
74
|
+
|
75
|
+
context "when rules are set" do
|
76
|
+
|
77
|
+
let(:rules) { described_class.new [foo, bar, foo] }
|
78
|
+
let(:nodes) { [1, 1, 2] }
|
79
|
+
|
80
|
+
subject { rules[nodes] }
|
81
|
+
it { is_expected.to eql [6, 4] }
|
82
|
+
# [1, 1, 2] -foo-> [2, 2, 3] -foo-> [3, 3, 4] -bar-> [6, 4]
|
83
|
+
|
84
|
+
end # context
|
85
|
+
|
86
|
+
end # describe #[]
|
87
|
+
|
88
|
+
end # describe AbstractMapper::Rules
|
@@ -0,0 +1,113 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
describe AbstractMapper::Settings do
|
4
|
+
|
5
|
+
let!(:rule) do
|
6
|
+
AbstractMapper::Test::Rule = Class.new(AbstractMapper::SoleRule)
|
7
|
+
end
|
8
|
+
let!(:node) do
|
9
|
+
AbstractMapper::Test::Node = Class.new(AbstractMapper::Node)
|
10
|
+
end
|
11
|
+
|
12
|
+
let(:settings) do
|
13
|
+
described_class.new do
|
14
|
+
command :foo, AbstractMapper::Test::Node
|
15
|
+
rule AbstractMapper::Test::Rule
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
describe ".new" do
|
20
|
+
|
21
|
+
context "with a valid block" do
|
22
|
+
|
23
|
+
subject { settings }
|
24
|
+
it { is_expected.to be_frozen }
|
25
|
+
|
26
|
+
end # context
|
27
|
+
|
28
|
+
context "with invalid command" do
|
29
|
+
|
30
|
+
subject { described_class.new { command :foo, String } }
|
31
|
+
it "fails" do
|
32
|
+
expect { subject }.to raise_error do |error|
|
33
|
+
expect(error).to be_kind_of AbstractMapper::Errors::WrongNode
|
34
|
+
expect(error.message).to include "String"
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
end # context
|
39
|
+
|
40
|
+
context "with invalid rule" do
|
41
|
+
|
42
|
+
subject { described_class.new { rule String } }
|
43
|
+
it "fails" do
|
44
|
+
expect { subject }.to raise_error do |error|
|
45
|
+
expect(error).to be_kind_of AbstractMapper::Errors::WrongRule
|
46
|
+
expect(error.message).to include "String"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
end # context
|
51
|
+
|
52
|
+
context "without a block" do
|
53
|
+
|
54
|
+
subject { described_class.new }
|
55
|
+
it "doesn't fail" do
|
56
|
+
expect { subject }.not_to raise_error
|
57
|
+
end
|
58
|
+
|
59
|
+
end # context
|
60
|
+
|
61
|
+
end # describe .new
|
62
|
+
|
63
|
+
describe "#commands" do
|
64
|
+
|
65
|
+
subject { settings.commands }
|
66
|
+
|
67
|
+
it { is_expected.to be_kind_of AbstractMapper::Commands }
|
68
|
+
|
69
|
+
it "contains registered commands" do
|
70
|
+
expect(subject.registry).to eql(foo: node)
|
71
|
+
end
|
72
|
+
|
73
|
+
end # describe #commands
|
74
|
+
|
75
|
+
describe "#rules" do
|
76
|
+
|
77
|
+
subject { settings.rules }
|
78
|
+
|
79
|
+
it { is_expected.to be_kind_of AbstractMapper::Rules }
|
80
|
+
|
81
|
+
it "contains registered rules" do
|
82
|
+
expect(subject.registry).to eql [rule]
|
83
|
+
end
|
84
|
+
|
85
|
+
end # describe #rules
|
86
|
+
|
87
|
+
describe "#builder" do
|
88
|
+
|
89
|
+
subject { settings.builder }
|
90
|
+
|
91
|
+
it "subclasses AbstractMapper::Builder" do
|
92
|
+
expect(subject.superclass).to eql AbstractMapper::Builder
|
93
|
+
end
|
94
|
+
|
95
|
+
it "uses registered commands" do
|
96
|
+
expect(subject.commands).to eql settings.commands
|
97
|
+
end
|
98
|
+
|
99
|
+
end # describe #builder
|
100
|
+
|
101
|
+
describe "#optimizer" do
|
102
|
+
|
103
|
+
subject { settings.optimizer }
|
104
|
+
|
105
|
+
it { is_expected.to be_kind_of AbstractMapper::Optimizer }
|
106
|
+
|
107
|
+
it "uses registered rules" do
|
108
|
+
expect(subject.rules).to eql settings.rules
|
109
|
+
end
|
110
|
+
|
111
|
+
end # describe #optimizer
|
112
|
+
|
113
|
+
end # describe AbstractMapper::Settings
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
describe AbstractMapper::SoleRule do
|
4
|
+
|
5
|
+
let(:rule) { test.new(node) }
|
6
|
+
let(:test) { AbstractMapper::Test::Rule = Class.new(described_class) }
|
7
|
+
let(:nodes) { [node] }
|
8
|
+
let(:node) { double }
|
9
|
+
|
10
|
+
describe ".composer" do
|
11
|
+
|
12
|
+
subject { test.composer }
|
13
|
+
it { is_expected.to eql :filter }
|
14
|
+
|
15
|
+
end # describe .pair?
|
16
|
+
|
17
|
+
describe ".new" do
|
18
|
+
|
19
|
+
subject { rule }
|
20
|
+
|
21
|
+
it { is_expected.to be_kind_of AbstractMapper::Rule }
|
22
|
+
it { is_expected.to be_frozen }
|
23
|
+
|
24
|
+
it "denies second argument" do
|
25
|
+
expect { test.new(node, node) }.to raise_error(ArgumentError)
|
26
|
+
end
|
27
|
+
|
28
|
+
end # describe .new
|
29
|
+
|
30
|
+
describe "#node" do
|
31
|
+
|
32
|
+
subject { rule.node }
|
33
|
+
it { is_expected.to eql node }
|
34
|
+
|
35
|
+
end # describe #node
|
36
|
+
|
37
|
+
describe "#transproc" do
|
38
|
+
|
39
|
+
before do
|
40
|
+
test.send(:define_method, :optimize?) { node > 3 }
|
41
|
+
test.send(:define_method, :optimize) { -node if node < 7 }
|
42
|
+
end
|
43
|
+
|
44
|
+
subject { test.transproc[array] }
|
45
|
+
|
46
|
+
let(:array) { [5, 1, 38, 4] }
|
47
|
+
it { is_expected.to eql [-5, 1, -4] }
|
48
|
+
|
49
|
+
end # describe #transproc
|
50
|
+
|
51
|
+
end # describe AbstractMapper::SoleRule
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
describe AbstractMapper do
|
4
|
+
|
5
|
+
let(:test) { Class.new(described_class) }
|
6
|
+
let(:tree) { double transproc: transproc }
|
7
|
+
let(:transproc) { double }
|
8
|
+
|
9
|
+
let(:mapper) do
|
10
|
+
allow(transproc).to receive(:call) { |input| "called: #{input}" }
|
11
|
+
allow(test).to receive(:finalize) { tree }
|
12
|
+
test.new
|
13
|
+
end
|
14
|
+
|
15
|
+
describe ".new" do
|
16
|
+
|
17
|
+
subject { mapper }
|
18
|
+
it { is_expected.to be_frozen }
|
19
|
+
|
20
|
+
end # describe .new
|
21
|
+
|
22
|
+
describe "#tree" do
|
23
|
+
|
24
|
+
subject { mapper.tree }
|
25
|
+
it { is_expected.to eql tree }
|
26
|
+
|
27
|
+
end # describe #tree
|
28
|
+
|
29
|
+
describe "#call" do
|
30
|
+
|
31
|
+
subject { mapper.call :foo }
|
32
|
+
it { is_expected.to eql "called: foo" }
|
33
|
+
|
34
|
+
end # describe #call
|
35
|
+
|
36
|
+
end # describe AbstractMapper
|