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.
Files changed (71) hide show
  1. checksums.yaml +7 -0
  2. data/.coveralls.yml +2 -0
  3. data/.gitignore +9 -0
  4. data/.metrics +9 -0
  5. data/.rspec +2 -0
  6. data/.rubocop.yml +2 -0
  7. data/.travis.yml +19 -0
  8. data/.yardopts +3 -0
  9. data/CHANGELOG.md +3 -0
  10. data/Gemfile +9 -0
  11. data/Guardfile +14 -0
  12. data/LICENSE +21 -0
  13. data/README.md +239 -0
  14. data/Rakefile +34 -0
  15. data/abstract_mapper.gemspec +26 -0
  16. data/config/metrics/STYLEGUIDE +230 -0
  17. data/config/metrics/cane.yml +5 -0
  18. data/config/metrics/churn.yml +6 -0
  19. data/config/metrics/flay.yml +2 -0
  20. data/config/metrics/metric_fu.yml +15 -0
  21. data/config/metrics/reek.yml +1 -0
  22. data/config/metrics/roodi.yml +24 -0
  23. data/config/metrics/rubocop.yml +76 -0
  24. data/config/metrics/saikuro.yml +3 -0
  25. data/config/metrics/simplecov.yml +6 -0
  26. data/config/metrics/yardstick.yml +37 -0
  27. data/lib/abstract_mapper/branch.rb +110 -0
  28. data/lib/abstract_mapper/builder.rb +84 -0
  29. data/lib/abstract_mapper/commands.rb +71 -0
  30. data/lib/abstract_mapper/dsl.rb +62 -0
  31. data/lib/abstract_mapper/errors/unknown_command.rb +25 -0
  32. data/lib/abstract_mapper/errors/wrong_node.rb +23 -0
  33. data/lib/abstract_mapper/errors/wrong_rule.rb +23 -0
  34. data/lib/abstract_mapper/functions.rb +76 -0
  35. data/lib/abstract_mapper/node.rb +76 -0
  36. data/lib/abstract_mapper/optimizer.rb +48 -0
  37. data/lib/abstract_mapper/pair_rule.rb +66 -0
  38. data/lib/abstract_mapper/rspec.rb +7 -0
  39. data/lib/abstract_mapper/rule.rb +52 -0
  40. data/lib/abstract_mapper/rules.rb +61 -0
  41. data/lib/abstract_mapper/settings.rb +95 -0
  42. data/lib/abstract_mapper/sole_rule.rb +58 -0
  43. data/lib/abstract_mapper/version.rb +9 -0
  44. data/lib/abstract_mapper.rb +82 -0
  45. data/lib/rspec/functions.rb +25 -0
  46. data/lib/rspec/mapper.rb +40 -0
  47. data/lib/rspec/nodes.rb +58 -0
  48. data/lib/rspec/rules.rb +59 -0
  49. data/spec/integration/faceter.rb +62 -0
  50. data/spec/integration/mapper_definition_spec.rb +33 -0
  51. data/spec/integration/rspec_examples_spec.rb +77 -0
  52. data/spec/spec_helper.rb +20 -0
  53. data/spec/unit/abstract_mapper/branch_spec.rb +126 -0
  54. data/spec/unit/abstract_mapper/builder_spec.rb +78 -0
  55. data/spec/unit/abstract_mapper/commands_spec.rb +105 -0
  56. data/spec/unit/abstract_mapper/dsl_spec.rb +82 -0
  57. data/spec/unit/abstract_mapper/errors/unknown_command_spec.rb +21 -0
  58. data/spec/unit/abstract_mapper/errors/wrong_node_spec.rb +21 -0
  59. data/spec/unit/abstract_mapper/errors/wrong_rule_spec.rb +23 -0
  60. data/spec/unit/abstract_mapper/functions/compact_spec.rb +25 -0
  61. data/spec/unit/abstract_mapper/functions/filter_spec.rb +26 -0
  62. data/spec/unit/abstract_mapper/functions/subclass_spec.rb +66 -0
  63. data/spec/unit/abstract_mapper/node_spec.rb +84 -0
  64. data/spec/unit/abstract_mapper/optimizer_spec.rb +48 -0
  65. data/spec/unit/abstract_mapper/pair_rule_spec.rb +59 -0
  66. data/spec/unit/abstract_mapper/rule_spec.rb +83 -0
  67. data/spec/unit/abstract_mapper/rules_spec.rb +88 -0
  68. data/spec/unit/abstract_mapper/settings_spec.rb +113 -0
  69. data/spec/unit/abstract_mapper/sole_rule_spec.rb +51 -0
  70. data/spec/unit/abstract_mapper_spec.rb +36 -0
  71. metadata +171 -0
@@ -0,0 +1,62 @@
1
+ # encoding: utf-8
2
+
3
+ shared_context "Faceter" do
4
+
5
+ before do
6
+ module Faceter
7
+
8
+ # Transproc functions
9
+ module Functions
10
+ extend Transproc::Registry
11
+
12
+ uses :map_array, from: Transproc::ArrayTransformations
13
+ uses :rename_keys, from: Transproc::HashTransformations
14
+ end
15
+
16
+ # Nodes
17
+ class List < AbstractMapper::Branch
18
+ def transproc
19
+ Functions[:map_array, super]
20
+ end
21
+ end
22
+
23
+ class Rename < AbstractMapper::Node
24
+ def initialize(old, options = {})
25
+ @old = old
26
+ @new = options.fetch(:to)
27
+ super
28
+ end
29
+
30
+ def transproc
31
+ Functions[:rename_keys, @old => @new]
32
+ end
33
+ end
34
+
35
+ # Rules
36
+ class CompactLists < AbstractMapper::PairRule
37
+ def optimize?
38
+ left.is_a?(List) && right.is_a?(List)
39
+ end
40
+
41
+ def optimize
42
+ List.new { left.entries + right.entries }
43
+ end
44
+ end
45
+
46
+ # Registry
47
+ class Mapper < AbstractMapper
48
+ configure do
49
+ command :list, Faceter::List
50
+ command :rename, Faceter::Rename
51
+
52
+ rule Faceter::CompactLists
53
+ end
54
+ end
55
+
56
+ end # module Faceter
57
+
58
+ end # before
59
+
60
+ after { Object.send :remove_const, :Faceter }
61
+
62
+ end # shared context
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative "faceter"
4
+
5
+ describe "mapper definition" do
6
+
7
+ include_context "Faceter"
8
+
9
+ before do
10
+ class MyMapper < Faceter::Mapper
11
+ list do
12
+ rename :foo, to: :baz
13
+ end
14
+
15
+ list do
16
+ rename :bar, to: :qux
17
+ end
18
+ end
19
+ end
20
+
21
+ let(:mapper) { MyMapper.new }
22
+ let(:input) { [{ foo: :FOO, bar: :FOO }, { foo: :BAR, bar: :BAR }] }
23
+ let(:output) { [{ baz: :FOO, qux: :FOO }, { baz: :BAR, qux: :BAR }] }
24
+
25
+ it "works" do
26
+ expect(mapper.tree.inspect)
27
+ .to eql "<Root [<List [<Rename(:foo, {:to=>:baz})>, <Rename(:bar, {:to=>:qux})>]>]>"
28
+ expect(mapper.call input).to eql output
29
+ end
30
+
31
+ after { Object.send :remove_const, :MyMapper }
32
+
33
+ end # describe mapper definition
@@ -0,0 +1,77 @@
1
+ # encoding: utf-8
2
+
3
+ require_relative "faceter"
4
+
5
+ require "abstract_mapper/rspec" # examples under the test
6
+
7
+ describe "rspec examples" do
8
+
9
+ include_context "Faceter"
10
+
11
+ describe "Faceter::Functions", "#rename_keys" do
12
+
13
+ let(:described_class) { Faceter::Functions }
14
+
15
+ it_behaves_like :transforming_immutable_data do
16
+ let(:arguments) { [:rename_keys, foo: :bar] }
17
+ let(:input) { { foo: :FOO, baz: :BAZ } }
18
+ let(:output) { { bar: :FOO, baz: :BAZ } }
19
+ end
20
+
21
+ end # describe Faceter::Functions
22
+
23
+ describe "Faceter::Rename" do
24
+
25
+ let(:described_class) { Faceter::Rename }
26
+
27
+ it_behaves_like :creating_immutable_node do
28
+ let(:attributes) { [:foo, to: :bar] }
29
+ end
30
+
31
+ it_behaves_like :mapping_immutable_input do
32
+ let(:attributes) { [:foo, to: :bar] }
33
+ let(:input) { { foo: :FOO, baz: :BAZ } }
34
+ let(:output) { { bar: :FOO, baz: :BAZ } }
35
+ end
36
+
37
+ end # describe Faceter::Rename
38
+
39
+ describe "Faceter::List" do
40
+
41
+ let(:described_class) { Faceter::List }
42
+
43
+ it_behaves_like :creating_immutable_branch
44
+
45
+ end # describe Faceter::List
46
+
47
+ describe "Faceter::CompactLists" do
48
+
49
+ let(:described_class) { Faceter::CompactLists }
50
+
51
+ it_behaves_like :skipping_nodes do
52
+ let(:input) { [Faceter::Rename.new(:foo, to: :bar), Faceter::List.new] }
53
+ end
54
+
55
+ it_behaves_like :optimizing_nodes do
56
+ let(:input) { [Faceter::List.new { [1] }, Faceter::List.new { [2] }] }
57
+ let(:output) { Faceter::List.new { [1, 2] } }
58
+ end
59
+
60
+ end # describe Faceter::CompactLists
61
+
62
+ describe "Faceter::Mapper" do
63
+
64
+ let(:described_class) { Faceter::Mapper }
65
+
66
+ it_behaves_like :defining_command do
67
+ let(:name) { :list }
68
+ let(:node) { Faceter::List }
69
+ end
70
+
71
+ it_behaves_like :defining_rule do
72
+ let(:rule) { Faceter::CompactLists }
73
+ end
74
+
75
+ end # describe Faceter::Mapper
76
+
77
+ end # describe mapper definition
@@ -0,0 +1,20 @@
1
+ # encoding: utf-8
2
+
3
+ begin
4
+ require "hexx-suit"
5
+ Hexx::Suit.load_metrics_for(self)
6
+ rescue LoadError
7
+ require "hexx-rspec"
8
+ Hexx::RSpec.load_metrics_for(self)
9
+ end
10
+
11
+ # Loads the code under test
12
+ require "abstract_mapper"
13
+
14
+ RSpec.configure do |config|
15
+ config.around do |example|
16
+ class AbstractMapper::Test; end
17
+ example.run
18
+ AbstractMapper.send :remove_const, :Test
19
+ end
20
+ end
@@ -0,0 +1,126 @@
1
+ # encoding: utf-8
2
+
3
+ describe AbstractMapper::Branch do
4
+
5
+ let(:branch) { test.new(:foo) { [node1, node2] } }
6
+ let(:test) { AbstractMapper::Test::Foo = Class.new(described_class) }
7
+ let(:tproc) { Transproc::Function.new -> v { "#{v}-1" }, {} }
8
+ let(:node1) { instance_double AbstractMapper::Node, transproc: tproc }
9
+ let(:node2) { instance_double AbstractMapper::Node, transproc: tproc }
10
+ let(:node3) { instance_double AbstractMapper::Node, transproc: tproc }
11
+
12
+ describe ".new" do
13
+
14
+ subject { branch }
15
+
16
+ it { is_expected.to be_kind_of Enumerable }
17
+ it { is_expected.to be_frozen }
18
+
19
+ context "without a block" do
20
+
21
+ subject { test.new(:foo).entries }
22
+ it { is_expected.to be_empty }
23
+
24
+ end # context
25
+
26
+ context "with a block" do
27
+
28
+ subject { test.new(:foo) { [node1, node2] }.entries }
29
+ it { is_expected.to eql [node1, node2] }
30
+
31
+ end # context
32
+
33
+ end # describe .new
34
+
35
+ describe "#block" do
36
+
37
+ subject { branch.block }
38
+ it { is_expected.to be_nil }
39
+
40
+ end # describe #block
41
+
42
+ describe "#rebuild" do
43
+
44
+ subject { branch.rebuild { [node2, node3] } }
45
+
46
+ it { is_expected.to be_kind_of test }
47
+
48
+ it "preserves attributes" do
49
+ expect(subject.attributes).to eql branch.attributes
50
+ end
51
+
52
+ it "assings new subnodes from a block" do
53
+ expect(subject.entries).to eql [node2, node3]
54
+ end
55
+
56
+ end # describe #rebuild
57
+
58
+ describe "#each" do
59
+
60
+ let(:subnodes) { [node1, node2] }
61
+
62
+ context "with a block" do
63
+
64
+ subject { branch.each { |item| item } }
65
+
66
+ it "looks over subnodes" do
67
+ expect(subject).to eql subnodes
68
+ end
69
+
70
+ end # context
71
+
72
+ context "without a block" do
73
+
74
+ subject { branch.each }
75
+
76
+ it "returns Enumerator for subnodes" do
77
+ expect(subject).to be_kind_of Enumerator
78
+ expect(subject.entries).to eql subnodes
79
+ end
80
+
81
+ end # context
82
+
83
+ end # describe #each
84
+
85
+ describe "#<<" do
86
+
87
+ subject { branch << node3 }
88
+
89
+ it "returns the branch with updated subnodes and the same attributes" do
90
+ expect(subject).to be_kind_of test
91
+ expect(subject.attributes).to eql branch.attributes
92
+ expect(subject.entries).to eql [node1, node2, node3]
93
+ end
94
+
95
+ end # describe #<<
96
+
97
+ describe "#transproc" do
98
+
99
+ let(:data) { "baz" }
100
+
101
+ subject { branch.transproc[data] }
102
+ it { is_expected.to eql "baz-1-1" }
103
+
104
+ end # describe #transproc
105
+
106
+ describe "#to_s" do
107
+
108
+ subject { branch.to_s }
109
+
110
+ context "of the root" do
111
+
112
+ let(:branch) { described_class.new { [node1, node2] } }
113
+ it { is_expected.to eql "Root [#{node1.inspect}, #{node2.inspect}]" }
114
+
115
+ end # context
116
+
117
+ context "of the specific node" do
118
+
119
+ let(:branch) { test.new(:foo) { [node1, node2] } }
120
+ it { is_expected.to eql "Foo(:foo) [#{node1.inspect}, #{node2.inspect}]" }
121
+
122
+ end # context
123
+
124
+ end # describe #to_s
125
+
126
+ end # describe Branch
@@ -0,0 +1,78 @@
1
+ # encoding: utf-8
2
+
3
+ describe AbstractMapper::Builder do
4
+
5
+ before do
6
+ AbstractMapper::Test::Builder = Class.new(described_class)
7
+ AbstractMapper::Test::Foo = Class.new(AbstractMapper::Node)
8
+ AbstractMapper::Test::Bar = Class.new(AbstractMapper::Branch)
9
+ end
10
+
11
+ let(:builder) { test.new tree }
12
+ let(:test) { AbstractMapper::Test::Builder }
13
+ let(:commands) { AbstractMapper::Commands.new(registry) }
14
+ let(:tree) { AbstractMapper::Test::Foo.new }
15
+ let(:registry) do
16
+ { foo: AbstractMapper::Test::Foo, bar: AbstractMapper::Test::Bar }
17
+ end
18
+
19
+ describe ".commands=" do
20
+
21
+ subject { test.commands = commands }
22
+
23
+ it "sets the commands" do
24
+ expect { subject }.to change { test.commands }.to commands
25
+ end
26
+
27
+ end # describe .commands=
28
+
29
+ describe ".update" do
30
+
31
+ before { test.commands = commands }
32
+
33
+ context "by default" do
34
+
35
+ subject { test.update }
36
+
37
+ it "is an empty branch" do
38
+ expect(subject).to be_instance_of AbstractMapper::Branch
39
+ expect(subject.entries).to be_empty
40
+ end
41
+
42
+ end # context
43
+
44
+ context "initialized" do
45
+
46
+ subject { test.update(tree) }
47
+ it { is_expected.to eql tree }
48
+
49
+ end # context
50
+
51
+ context "with a block" do
52
+
53
+ subject { test.update { bar { foo(:foo) { fail } } } }
54
+
55
+ it "is built" do
56
+ expect(subject.inspect).to eql "<Root [<Bar [<Foo(:foo)>]>]>"
57
+ expect(subject.first.first.block).not_to be_nil
58
+ end
59
+
60
+ end # context
61
+
62
+ end # describe .update
63
+
64
+ describe ".new" do
65
+
66
+ subject { builder }
67
+ it { is_expected.to be_frozen }
68
+
69
+ end # describe .new
70
+
71
+ describe "#respond_to?" do
72
+
73
+ subject { builder.respond_to? :arbitrary_method }
74
+ it { is_expected.to eql true }
75
+
76
+ end # describe #respond_to?
77
+
78
+ end # describe AbstractMapper::Builder
@@ -0,0 +1,105 @@
1
+ # encoding: utf-8
2
+
3
+ describe AbstractMapper::Commands do
4
+
5
+ let(:commands) { test.new }
6
+ let(:test) { Class.new(described_class) }
7
+ let(:branch) { Class.new(AbstractMapper::Branch) }
8
+
9
+ describe ".new" do
10
+
11
+ subject { commands }
12
+ it { is_expected.to be_frozen }
13
+
14
+ end # describe .new
15
+
16
+ describe "#registry" do
17
+
18
+ subject { commands.registry }
19
+
20
+ context "with a hash" do
21
+
22
+ let(:commands) { test.new(registry) }
23
+ let(:registry) { { foo: branch } }
24
+
25
+ it { is_expected.to eql registry }
26
+ it { is_expected.to be_frozen }
27
+
28
+ it "doesn't freeze the source" do
29
+ expect { subject }.not_to change { registry.frozen? }
30
+ end
31
+
32
+ end # context
33
+
34
+ context "without a hash" do
35
+
36
+ let(:commands) { test.new }
37
+
38
+ it { is_expected.to eql({}) }
39
+ it { is_expected.to be_frozen }
40
+
41
+ end # context
42
+
43
+ end # describe #builder
44
+
45
+ describe "#<<" do
46
+
47
+ let(:commands) { test.new(foo: branch) }
48
+
49
+ subject { commands << ["bar", branch] }
50
+
51
+ it "registers a command" do
52
+ expect(subject).to be_kind_of test
53
+ expect(subject.registry).to eql(foo: branch, bar: branch)
54
+ end
55
+
56
+ end # describe #<<
57
+
58
+ describe "#[]" do
59
+
60
+ let(:block) { proc { [:foo] } }
61
+ let(:args) { [:baz, qux: :QUX] }
62
+ let(:commands) do
63
+ test.new(foo: AbstractMapper::Node, bar: AbstractMapper::Branch)
64
+ end
65
+
66
+ context "simple node" do
67
+
68
+ subject { commands["foo", *args, &block] }
69
+
70
+ it "builds a node with a block" do
71
+ expect(subject).to be_kind_of AbstractMapper::Node
72
+ expect(subject.attributes).to eql args
73
+ expect(subject.block).to eql block
74
+ end
75
+
76
+ end # context
77
+
78
+ context "branch command" do
79
+
80
+ subject { commands["bar", *args, &block] }
81
+
82
+ it "builds a branch" do
83
+ expect(subject).to be_kind_of AbstractMapper::Node
84
+ expect(subject.attributes).to eql args
85
+ expect(subject.entries).to eql []
86
+ end
87
+
88
+ end # context
89
+
90
+ context "unknown command" do
91
+
92
+ subject { commands["baz"] }
93
+
94
+ it "fails" do
95
+ expect { subject }.to raise_error do |error|
96
+ expect(error).to be_kind_of AbstractMapper::Errors::UnknownCommand
97
+ expect(error.message).to include "baz"
98
+ end
99
+ end
100
+
101
+ end # context
102
+
103
+ end # describe #build
104
+
105
+ end # describe AbstractMapper::Commands
@@ -0,0 +1,82 @@
1
+ # encoding: utf-8
2
+
3
+ describe AbstractMapper::DSL do
4
+
5
+ let!(:bar) { AbstractMapper::Test::Bar = Class.new(AbstractMapper::Branch) }
6
+ let!(:foo) { AbstractMapper::Test::Foo = Class.new(AbstractMapper::Node) }
7
+ let!(:rule) do
8
+ AbstractMapper::Test::Rule = Class.new(AbstractMapper::PairRule) do
9
+ def optimize?
10
+ left.instance_of?(AbstractMapper::Test::Foo)
11
+ end
12
+
13
+ def optimize
14
+ AbstractMapper::Test::Foo.new(nodes.flat_map(&:attributes))
15
+ end
16
+ end
17
+ end
18
+ let!(:dsl) { Class.new { extend AbstractMapper::DSL } }
19
+
20
+ let!(:config) do
21
+ dsl.configure do
22
+ command :foo, AbstractMapper::Test::Foo
23
+ command :bar, AbstractMapper::Test::Bar
24
+ rule AbstractMapper::Test::Rule
25
+ end
26
+ end
27
+
28
+ describe "#configure" do
29
+
30
+ subject { config }
31
+
32
+ it { is_expected.to eql dsl }
33
+
34
+ it "configures settings" do
35
+ subject
36
+ expect(dsl.settings).to be_kind_of AbstractMapper::Settings
37
+ expect(dsl.settings.rules.registry).to eql [rule]
38
+ expect(dsl.settings.commands.registry).to eql(foo: foo, bar: bar)
39
+ end
40
+
41
+ end # describe #configure
42
+
43
+ describe "#finalize" do
44
+
45
+ before do
46
+ dsl.instance_eval do
47
+ bar :baz do
48
+ foo :qux
49
+ foo :quxx
50
+ end
51
+ foo :foo
52
+ end
53
+ end
54
+
55
+ subject { dsl.finalize }
56
+
57
+ it { is_expected.to be_kind_of AbstractMapper::Branch }
58
+
59
+ it "is optimized" do
60
+ expect(subject.inspect)
61
+ .to eql "<Root [<Bar(:baz) [<Foo([:qux, :quxx])>]>, <Foo(:foo)>]>"
62
+ end
63
+
64
+ end # describe #finalize
65
+
66
+ describe "#respond_to?" do
67
+
68
+ subject { dsl.respond_to? :anything }
69
+ it { is_expected.to eql true }
70
+
71
+ end # describe #respond_to?
72
+
73
+ describe ".inherited" do
74
+
75
+ let(:subklass) { Class.new(dsl) }
76
+ subject { subklass.settings }
77
+
78
+ it { is_expected.to eql dsl.settings }
79
+
80
+ end # describe .inherited
81
+
82
+ end # describe AbstractMapper::DSL
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ describe AbstractMapper::Errors::UnknownCommand do
4
+
5
+ subject(:error) { described_class.new :foo }
6
+
7
+ describe ".new" do
8
+
9
+ it { is_expected.to be_kind_of NameError }
10
+ it { is_expected.to be_frozen }
11
+
12
+ end # describe .new
13
+
14
+ describe "#message" do
15
+
16
+ subject { error.message }
17
+ it { is_expected.to eql "'foo' is not a registered DSL command" }
18
+
19
+ end # describe #message
20
+
21
+ end # describe AbstractMapper::Errors::UnknownCommand
@@ -0,0 +1,21 @@
1
+ # encoding: utf-8
2
+
3
+ describe AbstractMapper::Errors::WrongNode do
4
+
5
+ subject(:error) { described_class.new Symbol }
6
+
7
+ describe ".new" do
8
+
9
+ it { is_expected.to be_kind_of TypeError }
10
+ it { is_expected.to be_frozen }
11
+
12
+ end # describe .new
13
+
14
+ describe "#message" do
15
+
16
+ subject { error.message }
17
+ it { is_expected.to eql "Symbol is not a subclass of AbstractMapper::Node" }
18
+
19
+ end # describe #message
20
+
21
+ end # describe AbstractMapper::Errors::WrongNode
@@ -0,0 +1,23 @@
1
+ # encoding: utf-8
2
+
3
+ describe AbstractMapper::Errors::WrongRule do
4
+
5
+ subject(:error) { described_class.new Symbol }
6
+
7
+ describe ".new" do
8
+
9
+ it { is_expected.to be_kind_of TypeError }
10
+ it { is_expected.to be_frozen }
11
+
12
+ end # describe .new
13
+
14
+ describe "#message" do
15
+
16
+ subject { error.message }
17
+ it do
18
+ is_expected.to eql "Symbol is not a subclass of AbstractMapper::SoleRule"
19
+ end
20
+
21
+ end # describe #message
22
+
23
+ end # describe AbstractMapper::Errors::WrongRule
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+
3
+ require "abstract_mapper/rspec"
4
+
5
+ describe AbstractMapper::Functions, "#compact" do
6
+
7
+ let(:function) { -> a, b { (a == b) ? [a + b] : [a, b] } }
8
+ let(:arguments) { [:compact, function] }
9
+
10
+ it_behaves_like :transforming_immutable_data do
11
+ let(:input) { [] }
12
+ let(:output) { [] }
13
+ end
14
+
15
+ it_behaves_like :transforming_immutable_data do
16
+ let(:input) { [1] }
17
+ let(:output) { [1] }
18
+ end
19
+
20
+ it_behaves_like :transforming_immutable_data do
21
+ let(:input) { [1, 1, 2, 3, 3] }
22
+ let(:output) { [4, 6] }
23
+ end
24
+
25
+ end # describe AbstractMapper::Functions#compact
@@ -0,0 +1,26 @@
1
+ # encoding: utf-8
2
+
3
+ require "abstract_mapper/rspec"
4
+
5
+ describe AbstractMapper::Functions, "#filter" do
6
+
7
+ let(:arguments) { [:filter, -> v { v - 1 if v > 3 }] }
8
+
9
+ it_behaves_like :transforming_immutable_data do
10
+ let(:input) { [] }
11
+ let(:output) { [] }
12
+ end
13
+
14
+ it_behaves_like :transforming_immutable_data do
15
+ let(:input) { [1, 4, 9, 7, 2, 5] }
16
+ let(:output) { [3, 8, 6, 4] }
17
+ end
18
+
19
+ it_behaves_like :transforming_immutable_data do
20
+ let(:arguments) { [:filter, -> v { [v - 1] if v > 3 }] }
21
+
22
+ let(:input) { [1, 4, 9, 7, 2, 5] }
23
+ let(:output) { [3, 8, 6, 4] }
24
+ end
25
+
26
+ end # describe AbstractMapper::Functions#filter