abstract_mapper 0.0.2 → 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/.travis.yml +0 -4
- data/CHANGELOG.md +26 -0
- data/README.md +5 -5
- data/Rakefile +1 -1
- data/abstract_mapper.gemspec +1 -0
- data/lib/abstract_mapper.rb +4 -15
- data/lib/abstract_mapper/ast.rb +16 -0
- data/lib/abstract_mapper/ast/branch.rb +121 -0
- data/lib/abstract_mapper/ast/node.rb +91 -0
- data/lib/abstract_mapper/builder.rb +2 -2
- data/lib/abstract_mapper/commands.rb +4 -2
- data/lib/abstract_mapper/commands/base.rb +69 -0
- data/lib/abstract_mapper/dsl.rb +2 -2
- data/lib/abstract_mapper/errors.rb +17 -0
- data/lib/abstract_mapper/errors/wrong_node.rb +1 -1
- data/lib/abstract_mapper/errors/wrong_rule.rb +1 -1
- data/lib/abstract_mapper/optimizer.rb +1 -1
- data/lib/abstract_mapper/rules.rb +10 -5
- data/lib/abstract_mapper/rules/base.rb +74 -0
- data/lib/abstract_mapper/rules/pair.rb +68 -0
- data/lib/abstract_mapper/rules/sole.rb +60 -0
- data/lib/abstract_mapper/settings.rb +22 -30
- data/lib/abstract_mapper/version.rb +1 -1
- data/lib/rspec/nodes.rb +2 -2
- data/spec/integration/faceter.rb +4 -4
- data/spec/integration/rspec_examples_spec.rb +0 -6
- data/spec/unit/abstract_mapper/{branch_spec.rb → ast/branch_spec.rb} +28 -61
- data/spec/unit/abstract_mapper/{node_spec.rb → ast/node_spec.rb} +16 -53
- data/spec/unit/abstract_mapper/builder_spec.rb +9 -24
- data/spec/unit/abstract_mapper/{command_spec.rb → commands/base_spec.rb} +10 -25
- data/spec/unit/abstract_mapper/commands_spec.rb +9 -14
- data/spec/unit/abstract_mapper/dsl_spec.rb +23 -15
- data/spec/unit/abstract_mapper/errors/unknown_command_spec.rb +1 -4
- data/spec/unit/abstract_mapper/errors/wrong_node_spec.rb +5 -4
- data/spec/unit/abstract_mapper/errors/wrong_rule_spec.rb +5 -5
- data/spec/unit/abstract_mapper/functions/compact_spec.rb +0 -2
- data/spec/unit/abstract_mapper/functions/filter_spec.rb +0 -2
- data/spec/unit/abstract_mapper/functions/identity_spec.rb +0 -2
- data/spec/unit/abstract_mapper/functions/restrict_spec.rb +0 -3
- data/spec/unit/abstract_mapper/functions/subclass_spec.rb +0 -2
- data/spec/unit/abstract_mapper/optimizer_spec.rb +13 -17
- data/spec/unit/abstract_mapper/{rule_spec.rb → rules/base_spec.rb} +17 -34
- data/spec/unit/abstract_mapper/{pair_rule_spec.rb → rules/pair_spec.rb} +8 -8
- data/spec/unit/abstract_mapper/{sole_rule_spec.rb → rules/sole_spec.rb} +5 -5
- data/spec/unit/abstract_mapper/rules_spec.rb +24 -37
- data/spec/unit/abstract_mapper/settings_spec.rb +38 -32
- data/spec/unit/abstract_mapper_spec.rb +9 -16
- metadata +37 -22
- data/lib/abstract_mapper/attributes.rb +0 -65
- data/lib/abstract_mapper/branch.rb +0 -120
- data/lib/abstract_mapper/command.rb +0 -68
- data/lib/abstract_mapper/node.rb +0 -87
- data/lib/abstract_mapper/pair_rule.rb +0 -64
- data/lib/abstract_mapper/rule.rb +0 -73
- data/lib/abstract_mapper/sole_rule.rb +0 -56
@@ -1,21 +1,19 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
describe AbstractMapper::
|
3
|
+
describe AbstractMapper::Rules::Base do
|
4
4
|
|
5
5
|
let(:rule) { test.new(*nodes) }
|
6
|
-
let(:test) {
|
6
|
+
let(:test) { Class.new(described_class) }
|
7
7
|
let(:nodes) { [node] }
|
8
|
-
let(:node) { AbstractMapper::Node.new }
|
8
|
+
let(:node) { AbstractMapper::AST::Node.new }
|
9
9
|
|
10
10
|
describe ".new" do
|
11
|
-
|
12
11
|
subject { rule }
|
13
|
-
it { is_expected.to be_frozen }
|
14
12
|
|
13
|
+
it { is_expected.to be_frozen }
|
15
14
|
end # describe .new
|
16
15
|
|
17
16
|
describe "#nodes" do
|
18
|
-
|
19
17
|
subject { rule.nodes }
|
20
18
|
|
21
19
|
it { is_expected.to eql nodes }
|
@@ -24,52 +22,44 @@ describe AbstractMapper::Rule do
|
|
24
22
|
it "doesn't freeze the source" do
|
25
23
|
expect { subject }.not_to change { nodes.frozen? }
|
26
24
|
end
|
27
|
-
|
28
25
|
end # describe #nodes
|
29
26
|
|
30
27
|
describe "#call" do
|
31
|
-
|
32
28
|
subject { rule.call }
|
33
29
|
|
34
30
|
context "by default" do
|
35
|
-
|
36
31
|
it { is_expected.to eql nodes }
|
37
|
-
|
38
|
-
end # context
|
32
|
+
end
|
39
33
|
|
40
34
|
context "when #optimize? returns true" do
|
41
|
-
|
42
35
|
before { test.send(:define_method, :optimize?) { true } }
|
43
|
-
it { is_expected.to eql nodes }
|
44
36
|
|
45
|
-
|
37
|
+
it { is_expected.to eql nodes }
|
38
|
+
end
|
46
39
|
|
47
40
|
context "when #optimize is defined" do
|
48
|
-
|
49
41
|
before { test.send(:define_method, :optimize) { :foo } }
|
50
|
-
it { is_expected.to eql nodes }
|
51
42
|
|
52
|
-
|
43
|
+
it { is_expected.to eql nodes }
|
44
|
+
end
|
53
45
|
|
54
46
|
context "when #optimize? returns true and #optimize is defined" do
|
55
|
-
|
56
47
|
before { test.send(:define_method, :optimize?) { true } }
|
57
48
|
before { test.send(:define_method, :optimize) { :foo } }
|
58
|
-
it { is_expected.to eql [:foo] }
|
59
49
|
|
60
|
-
|
50
|
+
it { is_expected.to eql [:foo] }
|
51
|
+
end
|
61
52
|
|
62
53
|
context "when #optimize returns nils" do
|
63
|
-
|
64
54
|
before { test.send(:define_method, :optimize?) { true } }
|
65
55
|
before { test.send(:define_method, :optimize) { [nil, nil] } }
|
66
|
-
it { is_expected.to eql [] }
|
67
|
-
|
68
|
-
end # context
|
69
56
|
|
57
|
+
it { is_expected.to eql [] }
|
58
|
+
end
|
70
59
|
end # describe #call
|
71
60
|
|
72
61
|
describe ".transproc" do
|
62
|
+
subject { test.transproc[array] }
|
73
63
|
|
74
64
|
before do
|
75
65
|
test.send(:define_method, :optimize?) { true }
|
@@ -79,21 +69,14 @@ describe AbstractMapper::Rule do
|
|
79
69
|
let(:array) { [1, 2, 3] }
|
80
70
|
|
81
71
|
context "with default composer" do
|
82
|
-
|
83
|
-
subject { test.transproc[array] }
|
84
72
|
it { is_expected.to eql array }
|
85
|
-
|
86
|
-
end # context
|
73
|
+
end
|
87
74
|
|
88
75
|
context "with another composer" do
|
89
|
-
|
90
76
|
before { allow(test).to receive(:composer) { :compact } }
|
91
77
|
|
92
|
-
subject { test.transproc[array] }
|
93
78
|
it { is_expected.to eql [2, 3, 1] }
|
94
|
-
|
95
|
-
end # context
|
96
|
-
|
79
|
+
end
|
97
80
|
end # describe .transproc
|
98
81
|
|
99
|
-
end # describe AbstractMapper::
|
82
|
+
end # describe AbstractMapper::Rules::Base
|
@@ -1,18 +1,18 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
describe AbstractMapper::
|
3
|
+
describe AbstractMapper::Rules::Pair do
|
4
4
|
|
5
|
-
let(:rule) { test.new(left, right)
|
6
|
-
let(:test) {
|
7
|
-
let(:nodes) { [left, right]
|
8
|
-
let(:left) { AbstractMapper::Node.new
|
9
|
-
let(:right) { AbstractMapper::Node.new
|
5
|
+
let(:rule) { test.new(left, right) }
|
6
|
+
let(:test) { Class.new(described_class) }
|
7
|
+
let(:nodes) { [left, right] }
|
8
|
+
let(:left) { AbstractMapper::AST::Node.new }
|
9
|
+
let(:right) { AbstractMapper::AST::Node.new }
|
10
10
|
|
11
11
|
describe ".new" do
|
12
12
|
|
13
13
|
subject { rule }
|
14
14
|
|
15
|
-
it { is_expected.to be_kind_of AbstractMapper::
|
15
|
+
it { is_expected.to be_kind_of AbstractMapper::Rules::Base }
|
16
16
|
it { is_expected.to be_frozen }
|
17
17
|
|
18
18
|
it "requires second argument" do
|
@@ -49,4 +49,4 @@ describe AbstractMapper::PairRule do
|
|
49
49
|
|
50
50
|
end # describe #transproc
|
51
51
|
|
52
|
-
end # describe AbstractMapper::
|
52
|
+
end # describe AbstractMapper::Rules::Pair
|
@@ -1,17 +1,17 @@
|
|
1
1
|
# encoding: utf-8
|
2
2
|
|
3
|
-
describe AbstractMapper::
|
3
|
+
describe AbstractMapper::Rules::Sole do
|
4
4
|
|
5
5
|
let(:rule) { test.new(node) }
|
6
|
-
let(:test) {
|
6
|
+
let(:test) { Class.new(described_class) }
|
7
7
|
let(:nodes) { [node] }
|
8
|
-
let(:node) { AbstractMapper::Node.new }
|
8
|
+
let(:node) { AbstractMapper::AST::Node.new }
|
9
9
|
|
10
10
|
describe ".new" do
|
11
11
|
|
12
12
|
subject { rule }
|
13
13
|
|
14
|
-
it { is_expected.to be_kind_of AbstractMapper::
|
14
|
+
it { is_expected.to be_kind_of AbstractMapper::Rules::Base }
|
15
15
|
it { is_expected.to be_frozen }
|
16
16
|
|
17
17
|
it "denies second argument" do
|
@@ -41,4 +41,4 @@ describe AbstractMapper::SoleRule do
|
|
41
41
|
|
42
42
|
end # describe #transproc
|
43
43
|
|
44
|
-
end # describe AbstractMapper::
|
44
|
+
end # describe AbstractMapper::Rules::Sole
|
@@ -3,86 +3,73 @@
|
|
3
3
|
describe AbstractMapper::Rules do
|
4
4
|
|
5
5
|
let(:rules) { described_class.new }
|
6
|
-
let(:foo)
|
7
|
-
let(:bar)
|
6
|
+
let(:foo) { Class.new(AbstractMapper::Rules::Sole) }
|
7
|
+
let(:bar) { Class.new(AbstractMapper::Rules::Pair) }
|
8
8
|
|
9
9
|
describe ".new" do
|
10
|
-
|
11
10
|
subject { rules }
|
12
|
-
it { is_expected.to be_frozen }
|
13
11
|
|
12
|
+
it { is_expected.to be_frozen }
|
14
13
|
end # describe .new
|
15
14
|
|
16
15
|
describe "#registry" do
|
17
|
-
|
18
16
|
subject { rules.registry }
|
19
17
|
|
20
18
|
context "by default" do
|
21
|
-
|
22
19
|
let(:rules) { described_class.new }
|
20
|
+
|
23
21
|
it { is_expected.to eql [] }
|
24
22
|
it { is_expected.to be_frozen }
|
25
|
-
|
26
|
-
end # context
|
23
|
+
end
|
27
24
|
|
28
25
|
context "initialized" do
|
29
|
-
|
30
26
|
let(:rules) { described_class.new registry }
|
31
|
-
let(:registry) { [foo, bar]
|
27
|
+
let(:registry) { [foo, bar] }
|
32
28
|
|
33
29
|
it { is_expected.to eql registry }
|
34
30
|
it { is_expected.to be_frozen }
|
35
|
-
|
36
|
-
it "doesn't freezes the source" do
|
31
|
+
it "doesn't freeze a source" do
|
37
32
|
expect { subject }.not_to change { registry.frozen? }
|
38
33
|
end
|
39
|
-
|
40
|
-
end # context
|
41
|
-
|
34
|
+
end
|
42
35
|
end # describe #registry
|
43
36
|
|
44
37
|
describe "#<<" do
|
45
|
-
|
46
38
|
subject { rules << bar }
|
47
39
|
|
48
40
|
let(:rules) { described_class.new [foo] }
|
49
41
|
|
50
|
-
it "
|
42
|
+
it "returns a collection" do
|
51
43
|
expect(subject).to be_kind_of described_class
|
52
|
-
expect(subject.registry).to eql [foo, bar]
|
53
44
|
end
|
54
45
|
|
46
|
+
it "updates the registry" do
|
47
|
+
expect(subject.registry).to eql [foo, bar]
|
48
|
+
end
|
55
49
|
end # describe #<<
|
56
50
|
|
57
51
|
describe "#[]" do
|
52
|
+
subject { rules[nodes] }
|
58
53
|
|
59
|
-
|
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
|
54
|
+
let(:nodes) { [1, 1, 2, 5] }
|
65
55
|
|
66
56
|
context "when no rule is set" do
|
67
|
-
|
68
|
-
let(:nodes) { [1, 1, 2, 5] }
|
69
|
-
|
70
|
-
subject { rules[nodes] }
|
71
57
|
it { is_expected.to eql nodes }
|
72
|
-
|
73
|
-
end # context
|
58
|
+
end
|
74
59
|
|
75
60
|
context "when rules are set" do
|
76
|
-
|
77
61
|
let(:rules) { described_class.new [foo, bar, foo] }
|
78
|
-
let(:nodes) { [1, 1, 2] }
|
79
62
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
63
|
+
before do
|
64
|
+
foo.send(:define_method, :optimize?) { true }
|
65
|
+
foo.send(:define_method, :optimize) { node + 1 }
|
66
|
+
bar.send(:define_method, :optimize?) { left == right }
|
67
|
+
bar.send(:define_method, :optimize) { left + right }
|
68
|
+
end
|
85
69
|
|
70
|
+
it { is_expected.to eql [5, 4, 7] }
|
71
|
+
# [1, 1, 2, 5] -foo-> [2, 2, 3, 6] -bar-> [4, 3, 6] -foo-> [5, 4, 7]
|
72
|
+
end
|
86
73
|
end # describe #[]
|
87
74
|
|
88
75
|
end # describe AbstractMapper::Rules
|
@@ -4,30 +4,27 @@ class AbstractMapper
|
|
4
4
|
|
5
5
|
describe AbstractMapper::Settings do
|
6
6
|
|
7
|
-
let!(:
|
8
|
-
let!(:
|
7
|
+
let!(:foo) { Test::Foo = Class.new(AST::Node) { attribute :foo } }
|
8
|
+
let!(:bar) { Test::Bar = Class.new(AST::Node) { attribute :bar } }
|
9
|
+
|
10
|
+
let!(:baz) { Test::Baz = Class.new(Rules::Sole) }
|
11
|
+
let!(:qux) { Test::Qux = Class.new(Rules::Sole) }
|
9
12
|
|
10
13
|
let(:settings) do
|
11
14
|
described_class.new do
|
12
|
-
command
|
13
|
-
|
14
|
-
end
|
15
|
-
|
16
|
-
rule Test::Rule
|
15
|
+
command(:foo, Test::Foo) { |value| { foo: value } }
|
16
|
+
rule Test::Baz
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
20
20
|
describe ".new" do
|
21
|
-
|
22
21
|
context "with a valid block" do
|
23
|
-
|
24
22
|
subject { settings }
|
25
|
-
it { is_expected.to be_frozen }
|
26
23
|
|
27
|
-
|
24
|
+
it { is_expected.to be_frozen }
|
25
|
+
end
|
28
26
|
|
29
27
|
context "with invalid command" do
|
30
|
-
|
31
28
|
subject { described_class.new { command :foo, String } }
|
32
29
|
|
33
30
|
it "fails" do
|
@@ -36,11 +33,9 @@ class AbstractMapper
|
|
36
33
|
expect(error.message).to include "String"
|
37
34
|
end
|
38
35
|
end
|
39
|
-
|
40
|
-
end # context
|
36
|
+
end
|
41
37
|
|
42
38
|
context "with invalid rule" do
|
43
|
-
|
44
39
|
subject { described_class.new { rule String } }
|
45
40
|
|
46
41
|
it "fails" do
|
@@ -49,48 +44,39 @@ class AbstractMapper
|
|
49
44
|
expect(error.message).to include "String"
|
50
45
|
end
|
51
46
|
end
|
52
|
-
|
53
|
-
end # context
|
47
|
+
end
|
54
48
|
|
55
49
|
context "without a block" do
|
56
|
-
|
57
50
|
subject { described_class.new }
|
58
51
|
|
59
52
|
it "doesn't fail" do
|
60
53
|
expect { subject }.not_to raise_error
|
61
54
|
end
|
62
|
-
|
63
|
-
end # context
|
64
|
-
|
55
|
+
end
|
65
56
|
end # describe .new
|
66
57
|
|
67
58
|
describe "#commands" do
|
68
|
-
|
69
59
|
subject { settings.commands }
|
70
60
|
|
71
61
|
it { is_expected.to be_kind_of Commands }
|
72
62
|
|
73
63
|
it "contains registered commands" do
|
74
|
-
node = subject[:foo].call(:
|
75
|
-
expect(node.inspect).to eql "<
|
64
|
+
node = subject[:foo].call(:FOO)
|
65
|
+
expect(node.inspect).to eql "<Foo(foo: :FOO)>"
|
76
66
|
end
|
77
|
-
|
78
67
|
end # describe #commands
|
79
68
|
|
80
69
|
describe "#rules" do
|
81
|
-
|
82
70
|
subject { settings.rules }
|
83
71
|
|
84
72
|
it { is_expected.to be_kind_of Rules }
|
85
73
|
|
86
74
|
it "contains registered rules" do
|
87
|
-
expect(subject.registry).to eql [
|
75
|
+
expect(subject.registry).to eql [baz]
|
88
76
|
end
|
89
|
-
|
90
77
|
end # describe #rules
|
91
78
|
|
92
79
|
describe "#builder" do
|
93
|
-
|
94
80
|
subject { settings.builder }
|
95
81
|
|
96
82
|
it "subclasses Builder" do
|
@@ -100,11 +86,9 @@ class AbstractMapper
|
|
100
86
|
it "uses registered commands" do
|
101
87
|
expect(subject.commands).to eql settings.commands
|
102
88
|
end
|
103
|
-
|
104
89
|
end # describe #builder
|
105
90
|
|
106
91
|
describe "#optimizer" do
|
107
|
-
|
108
92
|
subject { settings.optimizer }
|
109
93
|
|
110
94
|
it { is_expected.to be_kind_of Optimizer }
|
@@ -112,9 +96,31 @@ class AbstractMapper
|
|
112
96
|
it "uses registered rules" do
|
113
97
|
expect(subject.rules).to eql settings.rules
|
114
98
|
end
|
115
|
-
|
116
99
|
end # describe #optimizer
|
117
100
|
|
101
|
+
describe "#update" do
|
102
|
+
subject do
|
103
|
+
settings.update do
|
104
|
+
command(:bar, Test::Bar) { |value| { bar: value } }
|
105
|
+
rule Test::Qux
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
it { is_expected.to be_kind_of described_class }
|
110
|
+
|
111
|
+
it "updates commands" do
|
112
|
+
node = subject.commands[:foo].call(:FOO)
|
113
|
+
expect(node.inspect).to eql "<Foo(foo: :FOO)>"
|
114
|
+
|
115
|
+
node = subject.commands[:bar].call(:BAR)
|
116
|
+
expect(node.inspect).to eql "<Bar(bar: :BAR)>"
|
117
|
+
end
|
118
|
+
|
119
|
+
it "updates rules" do
|
120
|
+
expect(subject.rules.registry).to eql [baz, qux]
|
121
|
+
end
|
122
|
+
end # describe #update
|
123
|
+
|
118
124
|
end # describe Settings
|
119
125
|
|
120
126
|
end # class AbstractMapper
|
@@ -2,17 +2,13 @@
|
|
2
2
|
|
3
3
|
describe AbstractMapper do
|
4
4
|
|
5
|
-
|
6
|
-
allow(test).to receive(:finalize) { tree }
|
7
|
-
test.new
|
8
|
-
end
|
9
|
-
|
10
|
-
let(:test) { Class.new(described_class) }
|
11
|
-
|
12
|
-
let(:tree) { klass.new }
|
5
|
+
before { allow(test).to receive(:finalize) { tree } }
|
13
6
|
|
14
|
-
let(:
|
15
|
-
|
7
|
+
let(:test) { Class.new(described_class) }
|
8
|
+
let(:mapper) { test.new }
|
9
|
+
let(:tree) { branch.new }
|
10
|
+
let(:branch) do
|
11
|
+
Class.new(AbstractMapper::AST::Branch) do
|
16
12
|
def transproc
|
17
13
|
-> v { "called: #{v}" }
|
18
14
|
end
|
@@ -20,25 +16,22 @@ describe AbstractMapper do
|
|
20
16
|
end
|
21
17
|
|
22
18
|
describe ".new" do
|
23
|
-
|
24
19
|
subject { mapper }
|
25
|
-
it { is_expected.to be_frozen }
|
26
20
|
|
21
|
+
it { is_expected.to be_frozen }
|
27
22
|
end # describe .new
|
28
23
|
|
29
24
|
describe "#tree" do
|
30
|
-
|
31
25
|
subject { mapper.tree }
|
26
|
+
|
32
27
|
it { is_expected.to eql tree }
|
33
28
|
it { is_expected.to be_frozen }
|
34
|
-
|
35
29
|
end # describe #tree
|
36
30
|
|
37
31
|
describe "#call" do
|
38
|
-
|
39
32
|
subject { mapper.call :foo }
|
40
|
-
it { is_expected.to eql "called: foo" }
|
41
33
|
|
34
|
+
it { is_expected.to eql "called: foo" }
|
42
35
|
end # describe #call
|
43
36
|
|
44
37
|
end # describe AbstractMapper
|