faceter 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 (125) 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 +18 -0
  8. data/.yardopts +3 -0
  9. data/CHANGELOG.md +3 -0
  10. data/Gemfile +9 -0
  11. data/Guardfile +10 -0
  12. data/LICENSE +21 -0
  13. data/README.md +295 -0
  14. data/Rakefile +37 -0
  15. data/benchmark/data.json +1 -0
  16. data/benchmark/faceter.rb +73 -0
  17. data/benchmark/rom.rb +85 -0
  18. data/benchmark/run.rb +54 -0
  19. data/config/metrics/STYLEGUIDE +230 -0
  20. data/config/metrics/cane.yml +5 -0
  21. data/config/metrics/churn.yml +6 -0
  22. data/config/metrics/flay.yml +2 -0
  23. data/config/metrics/metric_fu.yml +14 -0
  24. data/config/metrics/reek.yml +1 -0
  25. data/config/metrics/roodi.yml +24 -0
  26. data/config/metrics/rubocop.yml +75 -0
  27. data/config/metrics/saikuro.yml +3 -0
  28. data/config/metrics/simplecov.yml +6 -0
  29. data/config/metrics/yardstick.yml +37 -0
  30. data/faceter.gemspec +29 -0
  31. data/lib/faceter.rb +54 -0
  32. data/lib/faceter/coercers.rb +68 -0
  33. data/lib/faceter/functions.rb +30 -0
  34. data/lib/faceter/functions/add_prefix.rb +25 -0
  35. data/lib/faceter/functions/claster.rb +27 -0
  36. data/lib/faceter/functions/clean.rb +27 -0
  37. data/lib/faceter/functions/drop_prefix.rb +29 -0
  38. data/lib/faceter/functions/exclude.rb +27 -0
  39. data/lib/faceter/functions/group.rb +41 -0
  40. data/lib/faceter/functions/keep_symbol.rb +27 -0
  41. data/lib/faceter/functions/split.rb +28 -0
  42. data/lib/faceter/functions/ungroup.rb +31 -0
  43. data/lib/faceter/functions/unwrap.rb +32 -0
  44. data/lib/faceter/functions/wrap.rb +32 -0
  45. data/lib/faceter/mapper.rb +38 -0
  46. data/lib/faceter/nodes/add_prefix.rb +21 -0
  47. data/lib/faceter/nodes/change_prefix.rb +51 -0
  48. data/lib/faceter/nodes/create.rb +43 -0
  49. data/lib/faceter/nodes/exclude.rb +25 -0
  50. data/lib/faceter/nodes/field.rb +25 -0
  51. data/lib/faceter/nodes/fold.rb +25 -0
  52. data/lib/faceter/nodes/group.rb +26 -0
  53. data/lib/faceter/nodes/list.rb +25 -0
  54. data/lib/faceter/nodes/remove_prefix.rb +21 -0
  55. data/lib/faceter/nodes/rename.rb +25 -0
  56. data/lib/faceter/nodes/stringify_keys.rb +26 -0
  57. data/lib/faceter/nodes/symbolize_keys.rb +26 -0
  58. data/lib/faceter/nodes/unfold.rb +25 -0
  59. data/lib/faceter/nodes/ungroup.rb +26 -0
  60. data/lib/faceter/nodes/unwrap.rb +26 -0
  61. data/lib/faceter/nodes/wrap.rb +26 -0
  62. data/lib/faceter/rules/append_nested.rb +28 -0
  63. data/lib/faceter/rules/merge_branches.rb +41 -0
  64. data/lib/faceter/rules/merge_excludes.rb +29 -0
  65. data/lib/faceter/rules/merge_renames.rb +27 -0
  66. data/lib/faceter/rules/order_fields.rb +27 -0
  67. data/lib/faceter/rules/prepend_nested.rb +51 -0
  68. data/lib/faceter/version.rb +11 -0
  69. data/spec/integration/commands/add_prefix_spec.rb +37 -0
  70. data/spec/integration/commands/create_spec.rb +33 -0
  71. data/spec/integration/commands/exclude_spec.rb +55 -0
  72. data/spec/integration/commands/fold_spec.rb +41 -0
  73. data/spec/integration/commands/group_spec.rb +64 -0
  74. data/spec/integration/commands/remove_prefix_spec.rb +63 -0
  75. data/spec/integration/commands/rename_spec.rb +45 -0
  76. data/spec/integration/commands/stringify_keys_spec.rb +65 -0
  77. data/spec/integration/commands/symbolize_keys_spec.rb +49 -0
  78. data/spec/integration/commands/unfold_spec.rb +41 -0
  79. data/spec/integration/commands/ungroup_spec.rb +64 -0
  80. data/spec/integration/commands/unwrap_spec.rb +51 -0
  81. data/spec/integration/commands/wrap_spec.rb +51 -0
  82. data/spec/integration/rom_spec.rb +39 -0
  83. data/spec/spec_helper.rb +25 -0
  84. data/spec/unit/coercers/create_spec.rb +16 -0
  85. data/spec/unit/coercers/exclude_spec.rb +31 -0
  86. data/spec/unit/coercers/field_spec.rb +11 -0
  87. data/spec/unit/coercers/fold_spec.rb +11 -0
  88. data/spec/unit/coercers/prefix_spec.rb +38 -0
  89. data/spec/unit/coercers/rename_spec.rb +11 -0
  90. data/spec/unit/coercers/unfold_spec.rb +11 -0
  91. data/spec/unit/coercers/unwrap_spec.rb +35 -0
  92. data/spec/unit/coercers/wrap_spec.rb +35 -0
  93. data/spec/unit/functions/add_prefix_spec.rb +12 -0
  94. data/spec/unit/functions/claster_spec.rb +12 -0
  95. data/spec/unit/functions/clean_spec.rb +18 -0
  96. data/spec/unit/functions/drop_prefix_spec.rb +33 -0
  97. data/spec/unit/functions/exclude_spec.rb +64 -0
  98. data/spec/unit/functions/group_spec.rb +176 -0
  99. data/spec/unit/functions/keep_symbol_spec.rb +21 -0
  100. data/spec/unit/functions/split_spec.rb +64 -0
  101. data/spec/unit/functions/ungroup_spec.rb +87 -0
  102. data/spec/unit/functions/unwrap_spec.rb +54 -0
  103. data/spec/unit/functions/wrap_spec.rb +67 -0
  104. data/spec/unit/nodes/add_prefix_spec.rb +62 -0
  105. data/spec/unit/nodes/create_spec.rb +53 -0
  106. data/spec/unit/nodes/exclude_spec.rb +18 -0
  107. data/spec/unit/nodes/field_spec.rb +30 -0
  108. data/spec/unit/nodes/fold_spec.rb +19 -0
  109. data/spec/unit/nodes/group_spec.rb +163 -0
  110. data/spec/unit/nodes/list_spec.rb +27 -0
  111. data/spec/unit/nodes/remove_prefix_spec.rb +62 -0
  112. data/spec/unit/nodes/rename_spec.rb +16 -0
  113. data/spec/unit/nodes/stringify_keys_spec.rb +21 -0
  114. data/spec/unit/nodes/symbolize_keys_spec.rb +21 -0
  115. data/spec/unit/nodes/unfold_spec.rb +19 -0
  116. data/spec/unit/nodes/ungroup_spec.rb +92 -0
  117. data/spec/unit/nodes/unwrap_spec.rb +47 -0
  118. data/spec/unit/nodes/wrap_spec.rb +33 -0
  119. data/spec/unit/rules/append_nested_spec.rb +41 -0
  120. data/spec/unit/rules/merge_branches_spec.rb +58 -0
  121. data/spec/unit/rules/merge_excludes_spec.rb +31 -0
  122. data/spec/unit/rules/merge_renames_spec.rb +29 -0
  123. data/spec/unit/rules/order_fields_spec.rb +31 -0
  124. data/spec/unit/rules/prepend_nested_spec.rb +41 -0
  125. metadata +315 -0
@@ -0,0 +1,51 @@
1
+ # encoding: utf-8
2
+
3
+ module Faceter
4
+
5
+ module Rules
6
+
7
+ # Optimizes AST by moving nested nodes from the array level to one
8
+ # level deeper:
9
+ #
10
+ # @example Removes unnecessary iterations by items of the same array.
11
+ # prefix "foo", nested: true
12
+ # list do
13
+ # # ...
14
+ # end
15
+ #
16
+ # # Becomes:
17
+ # list do
18
+ # prefix "foo", nested: true
19
+ # # ...
20
+ # end
21
+ #
22
+ # @example Removes "flat" operation that cannot be applied to non-hashes
23
+ # prefix "foo", nested: false
24
+ # list do
25
+ # # ...
26
+ # end
27
+ #
28
+ # # Becomes:
29
+ # list do
30
+ # # ...
31
+ # end
32
+ #
33
+ # @api private
34
+ #
35
+ class PrependNested < AbstractMapper::PairRule
36
+
37
+ # @private
38
+ def optimize?
39
+ left.respond_to?(:nested) && right.instance_of?(Nodes::List)
40
+ end
41
+
42
+ # @private
43
+ def optimize
44
+ Nodes::List.new { (left.nested ? [left] : []) + right.entries }
45
+ end
46
+
47
+ end # class PrependNested
48
+
49
+ end # module Rules
50
+
51
+ end # module Faceter
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ require "delegate"
4
+
5
+ module Faceter
6
+
7
+ # The semantic version of the module.
8
+ # @see http://semver.org/ Semantic versioning 2.0
9
+ VERSION = "0.0.1".freeze
10
+
11
+ end # module Faceter
@@ -0,0 +1,37 @@
1
+ # encoding: utf-8
2
+
3
+ describe "add_prefix" do
4
+
5
+ subject { mapper.new.call input }
6
+
7
+ let(:input) do
8
+ [
9
+ {
10
+ "id" => 1, "name" => "joe",
11
+ "contacts" => [{ "email" => "joe@example.com" }]
12
+ }
13
+ ]
14
+ end
15
+
16
+ let(:output) do
17
+ [
18
+ {
19
+ "id" => 1, "user-name" => "joe",
20
+ "user-contacts" => [{ "user-email" => "joe@example.com" }]
21
+ }
22
+ ]
23
+ end
24
+
25
+ let(:mapper) do
26
+ Class.new(Faceter::Mapper) do
27
+ list do
28
+ add_prefix "user", separator: "-", except: "id", nested: true
29
+ end
30
+ end
31
+ end
32
+
33
+ it "works" do
34
+ expect(subject).to eql output
35
+ end
36
+
37
+ end # describe add_prefix
@@ -0,0 +1,33 @@
1
+ # encoding: utf-8
2
+
3
+ describe "create" do
4
+
5
+ subject { mapper.new.call input }
6
+
7
+ let(:input) do
8
+ [{ foo: 1, bar: 3 }]
9
+ end
10
+
11
+ let(:output) do
12
+ [{ foo: 1, bar: 3, baz: [1, 3], qux: 4, quxx: 3 }]
13
+ end
14
+
15
+ let(:mapper) do
16
+ Class.new(Faceter::Mapper) do
17
+ list do
18
+ create :baz, from: [:foo, :bar]
19
+
20
+ create :qux, from: [:foo, :bar] do |foo, bar|
21
+ foo + bar
22
+ end
23
+
24
+ create :quxx, from: :bar
25
+ end
26
+ end
27
+ end
28
+
29
+ it "works" do
30
+ expect(subject).to eql output
31
+ end
32
+
33
+ end # describe create
@@ -0,0 +1,55 @@
1
+ # encoding: utf-8
2
+
3
+ describe "exclude" do
4
+
5
+ subject { mapper.new.call input }
6
+
7
+ let(:input) do
8
+ [
9
+ {
10
+ user: {
11
+ id: 1,
12
+ name: "joe",
13
+ contacts: [{ email: "joe@doe.com", type: "job" }]
14
+ },
15
+ role: "admin"
16
+ },
17
+ {
18
+ user: {
19
+ id: 2,
20
+ name: "jane",
21
+ contacts: [{ email: "jane@doe.com", type: "job" }]
22
+ },
23
+ role: "admin"
24
+ }
25
+ ]
26
+ end
27
+
28
+ let(:output) do
29
+ [
30
+ { user: { name: "joe", contacts: [{ email: "joe@doe.com" }] } },
31
+ { user: { name: "jane", contacts: [{ email: "jane@doe.com" }] } }
32
+ ]
33
+ end
34
+
35
+ let(:mapper) do
36
+ Class.new(Faceter::Mapper) do
37
+ list do
38
+ exclude :role
39
+
40
+ field :user do
41
+ exclude only: :id # alternative syntax
42
+
43
+ field :contacts do
44
+ list { exclude except: :email }
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ it "works" do
52
+ expect(subject).to eql output
53
+ end
54
+
55
+ end # describe exclude
@@ -0,0 +1,41 @@
1
+ # encoding: utf-8
2
+
3
+ describe "fold" do
4
+
5
+ subject { mapper.new.call input }
6
+
7
+ let(:input) do
8
+ [
9
+ { name: "Joe", emails: ["joe@doe.com", "joe@doe.org"] },
10
+ { name: "Jane", emails: ["jane@doe.com"] }
11
+ ]
12
+ end
13
+
14
+ let(:output) do
15
+ [
16
+ {
17
+ name: "Joe",
18
+ emails: [{ address: "joe@doe.com" }, { address: "joe@doe.org" }]
19
+ },
20
+ {
21
+ name: "Jane",
22
+ emails: [{ address: "jane@doe.com" }]
23
+ }
24
+ ]
25
+ end
26
+
27
+ let(:mapper) do
28
+ Class.new(Faceter::Mapper) do
29
+ list do
30
+ field :emails do
31
+ list { fold to: :address }
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ it "works" do
38
+ expect(subject).to eql output
39
+ end
40
+
41
+ end # describe fold
@@ -0,0 +1,64 @@
1
+ # encoding: utf-8
2
+
3
+ describe "group" do
4
+
5
+ subject { mapper.new.call input }
6
+
7
+ let(:input) do
8
+ [
9
+ {
10
+ name: "Joe",
11
+ role: "admin",
12
+ type: "job",
13
+ contacts: [{ email: "joe@doe.com" }, { email: "joe@doe.org" }]
14
+ },
15
+ {
16
+ name: "Ian",
17
+ role: "admin",
18
+ type: "job",
19
+ contacts: [{ email: "ian@doe.com" }, { email: "ian@doe.org" }]
20
+ }
21
+ ]
22
+ end
23
+
24
+ let(:output) do
25
+ [
26
+ {
27
+ role: "admin",
28
+ users: [
29
+ {
30
+ name: "Joe",
31
+ contacts: [
32
+ { email: "joe@doe.com", type: "job" },
33
+ { email: "joe@doe.org", type: "job" }
34
+ ]
35
+ },
36
+ {
37
+ name: "Ian",
38
+ contacts: [
39
+ { email: "ian@doe.com", type: "job" },
40
+ { email: "ian@doe.org", type: "job" }
41
+ ]
42
+ }
43
+ ]
44
+ }
45
+ ]
46
+ end
47
+
48
+ let(:mapper) do
49
+ Class.new(Faceter::Mapper) do
50
+ group :name, :contacts, :type, to: :users
51
+
52
+ list do
53
+ field :users do
54
+ group :type, to: :contacts
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ it "works" do
61
+ expect(subject).to eql output
62
+ end
63
+
64
+ end # describe group
@@ -0,0 +1,63 @@
1
+ # encoding: utf-8
2
+
3
+ describe "remove_prefix" do
4
+
5
+ subject { mapper.new.call input }
6
+
7
+ let(:input) do
8
+ [
9
+ {
10
+ user_id: 1,
11
+ "user_name" => "joe",
12
+ contacts: [
13
+ {
14
+ "contact.emails" => [
15
+ {
16
+ :"contact.address" => "joe@doe.com",
17
+ "contact.type" => "job"
18
+ }
19
+ ],
20
+ user_skype: "joe"
21
+ }
22
+ ]
23
+ }
24
+ ]
25
+ end
26
+
27
+ let(:output) do
28
+ [
29
+ {
30
+ id: 1,
31
+ "user_name" => "joe",
32
+ contacts: [
33
+ {
34
+ "emails" => [
35
+ {
36
+ address: "joe@doe.com",
37
+ "type" => "job"
38
+ }
39
+ ],
40
+ user_skype: "joe"
41
+ }
42
+ ]
43
+ }
44
+ ]
45
+ end
46
+
47
+ let(:mapper) do
48
+ Class.new(Faceter::Mapper) do
49
+ list do
50
+ remove_prefix "user", only: :user_id
51
+
52
+ field :contacts do
53
+ remove_prefix "contact", separator: ".", nested: true
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ it "works" do
60
+ expect(subject).to eql output
61
+ end
62
+
63
+ end # describe remove_prefix
@@ -0,0 +1,45 @@
1
+ # encoding: utf-8
2
+
3
+ describe "rename" do
4
+
5
+ subject { mapper.new.call input }
6
+
7
+ let(:input) do
8
+ [
9
+ { user: { name: "joe", contacts: [{ email: "joe@doe.com" }] } },
10
+ { user: { name: "jane", contacts: [{ email: "jane@doe.com" }] } }
11
+ ]
12
+ end
13
+
14
+ let(:output) do
15
+ [
16
+ { "user" => { "name" => "joe", emails: [{ address: "joe@doe.com" }] } },
17
+ { "user" => { "name" => "jane", emails: [{ address: "jane@doe.com" }] } }
18
+ ]
19
+ end
20
+
21
+ let(:mapper) do
22
+ Class.new(Faceter::Mapper) do
23
+ list do
24
+ field :user do
25
+ rename :name, to: "name"
26
+
27
+ field :contacts do
28
+ list do
29
+ rename :email, to: :address
30
+ end
31
+ end
32
+
33
+ rename :contacts, to: :emails
34
+ end
35
+
36
+ rename :user, to: "user"
37
+ end
38
+ end
39
+ end
40
+
41
+ it "works" do
42
+ expect(subject).to eql output
43
+ end
44
+
45
+ end # describe rename
@@ -0,0 +1,65 @@
1
+ # encoding: utf-8
2
+
3
+ describe "stringify_keys" do
4
+
5
+ subject { mapper.new.call input }
6
+
7
+ let(:input) do
8
+ [
9
+ {
10
+ id: 1,
11
+ user: {
12
+ name: "joe",
13
+ "emails" => [{ address: "joe@doe.com" }]
14
+ },
15
+ roles: [{ name: "admin" }]
16
+ },
17
+ {
18
+ id: 2,
19
+ user: {
20
+ name: "jane",
21
+ "emails" => [{ address: "jane@doe.com" }]
22
+ },
23
+ roles: [{ name: "admin" }]
24
+ }
25
+ ]
26
+ end
27
+
28
+ let(:output) do
29
+ [
30
+ {
31
+ "id" => 1,
32
+ "user" => {
33
+ "name" => "joe",
34
+ "emails" => [{ "address" => "joe@doe.com" }]
35
+ },
36
+ "roles" => [{ name: "admin" }]
37
+ },
38
+ {
39
+ "id" => 2,
40
+ "user" => {
41
+ "name" => "jane",
42
+ "emails" => [{ "address" => "jane@doe.com" }]
43
+ },
44
+ "roles" => [{ name: "admin" }]
45
+ }
46
+ ]
47
+ end
48
+
49
+ let(:mapper) do
50
+ Class.new(Faceter::Mapper) do
51
+ list do
52
+ stringify_keys nested: false
53
+
54
+ field "user" do
55
+ stringify_keys
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ it "works" do
62
+ expect(subject).to eql output
63
+ end
64
+
65
+ end # describe stringify_keys