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.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +0 -4
  3. data/CHANGELOG.md +26 -0
  4. data/README.md +5 -5
  5. data/Rakefile +1 -1
  6. data/abstract_mapper.gemspec +1 -0
  7. data/lib/abstract_mapper.rb +4 -15
  8. data/lib/abstract_mapper/ast.rb +16 -0
  9. data/lib/abstract_mapper/ast/branch.rb +121 -0
  10. data/lib/abstract_mapper/ast/node.rb +91 -0
  11. data/lib/abstract_mapper/builder.rb +2 -2
  12. data/lib/abstract_mapper/commands.rb +4 -2
  13. data/lib/abstract_mapper/commands/base.rb +69 -0
  14. data/lib/abstract_mapper/dsl.rb +2 -2
  15. data/lib/abstract_mapper/errors.rb +17 -0
  16. data/lib/abstract_mapper/errors/wrong_node.rb +1 -1
  17. data/lib/abstract_mapper/errors/wrong_rule.rb +1 -1
  18. data/lib/abstract_mapper/optimizer.rb +1 -1
  19. data/lib/abstract_mapper/rules.rb +10 -5
  20. data/lib/abstract_mapper/rules/base.rb +74 -0
  21. data/lib/abstract_mapper/rules/pair.rb +68 -0
  22. data/lib/abstract_mapper/rules/sole.rb +60 -0
  23. data/lib/abstract_mapper/settings.rb +22 -30
  24. data/lib/abstract_mapper/version.rb +1 -1
  25. data/lib/rspec/nodes.rb +2 -2
  26. data/spec/integration/faceter.rb +4 -4
  27. data/spec/integration/rspec_examples_spec.rb +0 -6
  28. data/spec/unit/abstract_mapper/{branch_spec.rb → ast/branch_spec.rb} +28 -61
  29. data/spec/unit/abstract_mapper/{node_spec.rb → ast/node_spec.rb} +16 -53
  30. data/spec/unit/abstract_mapper/builder_spec.rb +9 -24
  31. data/spec/unit/abstract_mapper/{command_spec.rb → commands/base_spec.rb} +10 -25
  32. data/spec/unit/abstract_mapper/commands_spec.rb +9 -14
  33. data/spec/unit/abstract_mapper/dsl_spec.rb +23 -15
  34. data/spec/unit/abstract_mapper/errors/unknown_command_spec.rb +1 -4
  35. data/spec/unit/abstract_mapper/errors/wrong_node_spec.rb +5 -4
  36. data/spec/unit/abstract_mapper/errors/wrong_rule_spec.rb +5 -5
  37. data/spec/unit/abstract_mapper/functions/compact_spec.rb +0 -2
  38. data/spec/unit/abstract_mapper/functions/filter_spec.rb +0 -2
  39. data/spec/unit/abstract_mapper/functions/identity_spec.rb +0 -2
  40. data/spec/unit/abstract_mapper/functions/restrict_spec.rb +0 -3
  41. data/spec/unit/abstract_mapper/functions/subclass_spec.rb +0 -2
  42. data/spec/unit/abstract_mapper/optimizer_spec.rb +13 -17
  43. data/spec/unit/abstract_mapper/{rule_spec.rb → rules/base_spec.rb} +17 -34
  44. data/spec/unit/abstract_mapper/{pair_rule_spec.rb → rules/pair_spec.rb} +8 -8
  45. data/spec/unit/abstract_mapper/{sole_rule_spec.rb → rules/sole_spec.rb} +5 -5
  46. data/spec/unit/abstract_mapper/rules_spec.rb +24 -37
  47. data/spec/unit/abstract_mapper/settings_spec.rb +38 -32
  48. data/spec/unit/abstract_mapper_spec.rb +9 -16
  49. metadata +37 -22
  50. data/lib/abstract_mapper/attributes.rb +0 -65
  51. data/lib/abstract_mapper/branch.rb +0 -120
  52. data/lib/abstract_mapper/command.rb +0 -68
  53. data/lib/abstract_mapper/node.rb +0 -87
  54. data/lib/abstract_mapper/pair_rule.rb +0 -64
  55. data/lib/abstract_mapper/rule.rb +0 -73
  56. data/lib/abstract_mapper/sole_rule.rb +0 -56
@@ -1,21 +1,19 @@
1
1
  # encoding: utf-8
2
2
 
3
- describe AbstractMapper::Rule do
3
+ describe AbstractMapper::Rules::Base do
4
4
 
5
5
  let(:rule) { test.new(*nodes) }
6
- let(:test) { AbstractMapper::Test::Rule = Class.new(described_class) }
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
- end # context
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
- end # context
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
- end # context
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::Rule
82
+ end # describe AbstractMapper::Rules::Base
@@ -1,18 +1,18 @@
1
1
  # encoding: utf-8
2
2
 
3
- describe AbstractMapper::PairRule do
3
+ describe AbstractMapper::Rules::Pair do
4
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) { 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::Rule }
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::PairRule
52
+ end # describe AbstractMapper::Rules::Pair
@@ -1,17 +1,17 @@
1
1
  # encoding: utf-8
2
2
 
3
- describe AbstractMapper::SoleRule do
3
+ describe AbstractMapper::Rules::Sole do
4
4
 
5
5
  let(:rule) { test.new(node) }
6
- let(:test) { AbstractMapper::Test::Rule = Class.new(described_class) }
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::Rule }
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::SoleRule
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) { AbstractMapper::Test::Foo = Class.new(AbstractMapper::SoleRule) }
7
- let(:bar) { AbstractMapper::Test::Bar = Class.new(AbstractMapper::PairRule) }
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 "updates the registry" do
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
- 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
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
- subject { rules[nodes] }
81
- it { is_expected.to eql [5, 4] }
82
- # [1, 1, 2] -foo-> [2, 2, 3] -bar-> [4, 3] -foo-> [5, 4]
83
-
84
- end # context
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!(:rule) { Test::Rule = Class.new(SoleRule) }
8
- let!(:node) { Test::Node = Class.new(Node) { attribute :foo } }
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 :foo, Test::Node do |value|
13
- { foo: value }
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
- end # context
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(:bar)
75
- expect(node.inspect).to eql "<Node(foo: :bar)>"
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 [rule]
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
- let(:mapper) do
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(:klass) do
15
- Class.new(AbstractMapper::Branch) do
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