monolens 0.5.1 → 0.6.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 (105) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +51 -82
  3. data/lib/monolens/command.rb +111 -14
  4. data/lib/monolens/error.rb +2 -0
  5. data/lib/monolens/file.rb +6 -0
  6. data/lib/monolens/jsonpath.rb +76 -0
  7. data/lib/monolens/lens/options.rb +26 -12
  8. data/lib/monolens/lens/signature/missing.rb +11 -0
  9. data/lib/monolens/lens/signature.rb +60 -0
  10. data/lib/monolens/lens.rb +25 -4
  11. data/lib/monolens/macros.rb +28 -0
  12. data/lib/monolens/namespace.rb +11 -0
  13. data/lib/monolens/registry.rb +77 -0
  14. data/lib/monolens/{array → stdlib/array}/compact.rb +2 -0
  15. data/lib/monolens/{array → stdlib/array}/join.rb +4 -0
  16. data/lib/monolens/{array → stdlib/array}/map.rb +13 -19
  17. data/lib/monolens/{array.rb → stdlib/array.rb} +8 -6
  18. data/lib/monolens/stdlib/check/not_empty.rb +30 -0
  19. data/lib/monolens/stdlib/check.rb +13 -0
  20. data/lib/monolens/{coerce → stdlib/coerce}/date.rb +6 -1
  21. data/lib/monolens/{coerce → stdlib/coerce}/date_time.rb +7 -2
  22. data/lib/monolens/{coerce → stdlib/coerce}/integer.rb +4 -0
  23. data/lib/monolens/{coerce → stdlib/coerce}/string.rb +2 -0
  24. data/lib/monolens/{coerce.rb → stdlib/coerce.rb} +10 -8
  25. data/lib/monolens/{core → stdlib/core}/chain.rb +5 -3
  26. data/lib/monolens/{core → stdlib/core}/dig.rb +5 -0
  27. data/lib/monolens/stdlib/core/literal.rb +68 -0
  28. data/lib/monolens/{core → stdlib/core}/mapping.rb +15 -5
  29. data/lib/monolens/stdlib/core.rb +31 -0
  30. data/lib/monolens/stdlib/object/allbut.rb +22 -0
  31. data/lib/monolens/{object → stdlib/object}/extend.rb +10 -5
  32. data/lib/monolens/{object → stdlib/object}/keys.rb +4 -0
  33. data/lib/monolens/stdlib/object/merge.rb +56 -0
  34. data/lib/monolens/{object → stdlib/object}/rename.rb +5 -1
  35. data/lib/monolens/{object → stdlib/object}/select.rb +9 -0
  36. data/lib/monolens/{object → stdlib/object}/transform.rb +8 -3
  37. data/lib/monolens/{object → stdlib/object}/values.rb +9 -4
  38. data/lib/monolens/stdlib/object.rb +55 -0
  39. data/lib/monolens/{skip → stdlib/skip}/null.rb +2 -0
  40. data/lib/monolens/{skip.rb → stdlib/skip.rb} +4 -2
  41. data/lib/monolens/{str → stdlib/str}/downcase.rb +2 -0
  42. data/lib/monolens/{str → stdlib/str}/split.rb +5 -1
  43. data/lib/monolens/{str → stdlib/str}/strip.rb +2 -0
  44. data/lib/monolens/{str → stdlib/str}/upcase.rb +2 -0
  45. data/lib/monolens/{str.rb → stdlib/str.rb} +10 -8
  46. data/lib/monolens/stdlib.rb +7 -0
  47. data/lib/monolens/type/any.rb +39 -0
  48. data/lib/monolens/type/array.rb +27 -0
  49. data/lib/monolens/type/boolean.rb +17 -0
  50. data/lib/monolens/type/callback.rb +17 -0
  51. data/lib/monolens/type/coercible.rb +10 -0
  52. data/lib/monolens/type/diggable.rb +9 -0
  53. data/lib/monolens/type/emptyable.rb +9 -0
  54. data/lib/monolens/type/integer.rb +18 -0
  55. data/lib/monolens/type/lenses.rb +17 -0
  56. data/lib/monolens/type/map.rb +30 -0
  57. data/lib/monolens/type/object.rb +17 -0
  58. data/lib/monolens/type/responding.rb +25 -0
  59. data/lib/monolens/type/strategy.rb +56 -0
  60. data/lib/monolens/type/string.rb +18 -0
  61. data/lib/monolens/type/symbol.rb +20 -0
  62. data/lib/monolens/type.rb +33 -0
  63. data/lib/monolens/version.rb +2 -2
  64. data/lib/monolens.rb +22 -65
  65. data/spec/fixtures/macro.yml +13 -0
  66. data/spec/fixtures/recursive.yml +15 -0
  67. data/spec/monolens/command/literal.yml +2 -0
  68. data/spec/monolens/command/literal2.yml +2 -0
  69. data/spec/monolens/command/upcase.lens.yml +4 -0
  70. data/spec/monolens/lens/test_options.rb +2 -14
  71. data/spec/monolens/lens/test_signature.rb +38 -0
  72. data/spec/monolens/{array → stdlib/array}/test_compact.rb +8 -0
  73. data/spec/monolens/{array → stdlib/array}/test_join.rb +0 -0
  74. data/spec/monolens/{array → stdlib/array}/test_map.rb +15 -0
  75. data/spec/monolens/stdlib/check/test_not_empty.rb +50 -0
  76. data/spec/monolens/{coerce → stdlib/coerce}/test_date.rb +0 -0
  77. data/spec/monolens/{coerce → stdlib/coerce}/test_datetime.rb +1 -1
  78. data/spec/monolens/{coerce → stdlib/coerce}/test_integer.rb +0 -0
  79. data/spec/monolens/{coerce → stdlib/coerce}/test_string.rb +0 -0
  80. data/spec/monolens/{core → stdlib/core}/test_dig.rb +0 -0
  81. data/spec/monolens/stdlib/core/test_literal.rb +73 -0
  82. data/spec/monolens/{core → stdlib/core}/test_mapping.rb +37 -1
  83. data/spec/monolens/stdlib/object/test_allbut.rb +31 -0
  84. data/spec/monolens/{object → stdlib/object}/test_extend.rb +0 -0
  85. data/spec/monolens/{object → stdlib/object}/test_keys.rb +0 -0
  86. data/spec/monolens/stdlib/object/test_merge.rb +133 -0
  87. data/spec/monolens/{object → stdlib/object}/test_rename.rb +0 -0
  88. data/spec/monolens/{object → stdlib/object}/test_select.rb +0 -0
  89. data/spec/monolens/{object → stdlib/object}/test_transform.rb +0 -0
  90. data/spec/monolens/{object → stdlib/object}/test_values.rb +0 -0
  91. data/spec/monolens/{skip → stdlib/skip}/test_null.rb +0 -0
  92. data/spec/monolens/{str → stdlib/str}/test_downcase.rb +0 -0
  93. data/spec/monolens/{str → stdlib/str}/test_split.rb +0 -0
  94. data/spec/monolens/{str → stdlib/str}/test_strip.rb +0 -0
  95. data/spec/monolens/{str → stdlib/str}/test_upcase.rb +0 -0
  96. data/spec/monolens/test_command.rb +145 -0
  97. data/spec/monolens/test_error_traceability.rb +1 -1
  98. data/spec/monolens/test_jsonpath.rb +88 -0
  99. data/spec/monolens/test_lens.rb +1 -1
  100. data/spec/test_documentation.rb +52 -0
  101. data/spec/test_monolens.rb +20 -0
  102. data/tasks/test.rake +1 -1
  103. metadata +91 -50
  104. data/lib/monolens/core.rb +0 -23
  105. data/lib/monolens/object.rb +0 -41
data/lib/monolens.rb CHANGED
@@ -1,81 +1,38 @@
1
1
  require 'yaml'
2
+ require 'date'
3
+ require 'ostruct'
4
+
2
5
  module Monolens
3
- NAMESPACES = { }
6
+ require_relative 'monolens/version'
7
+ require_relative 'monolens/error'
8
+ require_relative 'monolens/error_handler'
9
+ require_relative 'monolens/type'
10
+ require_relative 'monolens/jsonpath'
11
+ require_relative 'monolens/lens'
12
+ require_relative 'monolens/namespace'
13
+ require_relative 'monolens/registry'
14
+ require_relative 'monolens/macros'
15
+
16
+ STDLIB = Registry.new
4
17
 
5
18
  class << self
6
- require_relative 'monolens/version'
7
- require_relative 'monolens/error'
8
- require_relative 'monolens/error_handler'
9
- require_relative 'monolens/lens'
10
-
11
19
  def define_namespace(name, impl_module)
12
- NAMESPACES[name] = impl_module
20
+ STDLIB.define_namespace(name, impl_module)
13
21
  end
14
22
 
15
- require_relative 'monolens/file'
16
- require_relative 'monolens/core'
17
- require_relative 'monolens/skip'
18
- require_relative 'monolens/str'
19
- require_relative 'monolens/array'
20
- require_relative 'monolens/object'
21
- require_relative 'monolens/coerce'
22
-
23
23
  def load_file(file)
24
- Monolens::File.new(YAML.safe_load(::File.read(file)))
24
+ STDLIB.load_file(file)
25
25
  end
26
26
 
27
- def load_yaml(yaml)
28
- Monolens::File.new(YAML.safe_load(yaml))
27
+ def load_yaml(yaml_str)
28
+ STDLIB.load_yaml(yaml_str)
29
29
  end
30
30
 
31
31
  def lens(arg)
32
- case arg
33
- when Lens then arg
34
- when ::Array then chain(arg)
35
- when ::String, ::Symbol then leaf_lens(arg)
36
- when ::Hash then hash_lens(arg)
37
- else
38
- raise Error, "No such lens #{arg} (#{arg.class})"
39
- end
40
- end
41
-
42
- def chain(lenses)
43
- Core::Chain.new(lenses.map{|l| lens(l) })
44
- end
45
- private :chain
46
-
47
- def file_lens(arg)
48
- File.new(arg)
32
+ STDLIB.lens(arg)
49
33
  end
50
-
51
- def leaf_lens(arg)
52
- namespace_name, lens_name = arg.to_s.split('.')
53
- factor_lens(namespace_name, lens_name, {})
54
- end
55
- private :leaf_lens
56
-
57
- def hash_lens(arg)
58
- return file_lens(arg) if arg['version'] || arg[:version]
59
- raise "Invalid lens #{arg}" unless arg.size == 1
60
-
61
- name, options = arg.to_a.first
62
- namespace_name, lens_name = if name =~ /^[a-z]+\.[a-z]+$/
63
- name.to_s.split('.')
64
- else
65
- ['core', name]
66
- end
67
- factor_lens(namespace_name, lens_name, options)
68
- end
69
- private :hash_lens
70
-
71
- def factor_lens(namespace_name, lens_name, options)
72
- namespace = NAMESPACES[namespace_name]
73
- if namespace&.private_method_defined?(lens_name, false)
74
- namespace.send(lens_name, options)
75
- else
76
- raise Error, "No such lens #{[namespace_name, lens_name].join('.')}"
77
- end
78
- end
79
- private :factor_lens
80
34
  end
35
+
36
+ require_relative 'monolens/file'
37
+ require_relative 'monolens/stdlib'
81
38
  end
@@ -0,0 +1,13 @@
1
+ ---
2
+ version: "1.0"
3
+ #
4
+ macros:
5
+ join_them:
6
+ - array.map:
7
+ - str.strip
8
+ - str.upcase
9
+ - array.join: { separator: <.separator }
10
+ #
11
+ lenses:
12
+ - join_them:
13
+ separator: ', '
@@ -0,0 +1,15 @@
1
+ ---
2
+ version: "1.0"
3
+ #
4
+ macros:
5
+ join_them:
6
+ - array.map:
7
+ - str.strip
8
+ - str.upcase
9
+ - array.join: { separator: <.separator }
10
+ ## This is strictly forbidden
11
+ - join_them: { separator: ',' }
12
+ #
13
+ lenses:
14
+ - join_them:
15
+ separator: ', '
@@ -0,0 +1,2 @@
1
+ ---
2
+ $([0]) $([1])
@@ -0,0 +1,2 @@
1
+ ---
2
+ $
@@ -0,0 +1,4 @@
1
+ ---
2
+ version: '1.0'
3
+ lenses:
4
+ - str.upcase
@@ -4,7 +4,7 @@ module Monolens
4
4
  module Lens
5
5
  describe Options do
6
6
  subject do
7
- Options.new(input)
7
+ Options.new(input, STDLIB, Signature::MISSING)
8
8
  end
9
9
 
10
10
  describe 'initialize' do
@@ -28,19 +28,7 @@ module Monolens
28
28
  it 'converts it to lenses' do
29
29
  expect(subject.to_h.keys).to eql([:lenses])
30
30
  lenses = subject.to_h[:lenses]
31
- expect(lenses).to be_a(Core::Chain)
32
- end
33
- end
34
-
35
- context('when used with a String') do
36
- let(:input) do
37
- 'str.strip'
38
- end
39
-
40
- it 'converts it to lenses' do
41
- expect(subject.to_h.keys).to eql([:lenses])
42
- lenses = subject.to_h[:lenses]
43
- expect(lenses).to be_a(Str::Strip)
31
+ expect(lenses).to eql(input)
44
32
  end
45
33
  end
46
34
  end
@@ -0,0 +1,38 @@
1
+ require 'spec_helper'
2
+
3
+ module Monolens
4
+ module Lens
5
+ describe Signature do
6
+ let(:signature) do
7
+ Signature.new(Type::String, Type::String, {
8
+ separator: [Type::String, true],
9
+ help: [Type::String, false]
10
+ })
11
+ end
12
+
13
+ it 'is ok with valid options' do
14
+ expect {
15
+ signature.dress_options({ separator: ',' }, nil)
16
+ }.not_to raise_error
17
+ end
18
+
19
+ it 'detects a missing option' do
20
+ expect {
21
+ signature.dress_options({}, nil)
22
+ }.to raise_error(Error, /Missing option `separator`/)
23
+ end
24
+
25
+ it 'detects an extra option' do
26
+ expect {
27
+ signature.dress_options({ foo: 'bar' }, nil)
28
+ }.to raise_error(Error, /Invalid option `foo`/)
29
+ end
30
+
31
+ it 'detects an option of the wrong type' do
32
+ expect {
33
+ signature.dress_options({ separator: 12 }, nil)
34
+ }.to raise_error(Error, /Invalid option `separator`: Invalid string 12/)
35
+ end
36
+ end
37
+ end
38
+ end
@@ -12,4 +12,12 @@ describe Monolens, 'array.compact' do
12
12
  it 'supports empty arrays' do
13
13
  expect(subject.call([])).to eql([])
14
14
  end
15
+
16
+ describe 'signature checking' do
17
+ it 'detects unexisting options' do
18
+ expect {
19
+ Monolens.lens('array.compact' => { foo: 'bar' })
20
+ }.to raise_error(Monolens::Error, /Invalid option `foo`/)
21
+ end
22
+ end
15
23
  end
File without changes
@@ -58,6 +58,21 @@ describe Monolens, 'array.map' do
58
58
  end
59
59
  end
60
60
 
61
+ context 'keeping on error' do
62
+ subject do
63
+ Monolens.lens('array.map' => {
64
+ on_error: 'keep',
65
+ lenses: [ 'str.upcase' ]
66
+ })
67
+ end
68
+
69
+ it 'skips errors' do
70
+ input = [12, 'world']
71
+ expected = [12, 'WORLD']
72
+ expect(subject.call(input)).to eql(expected)
73
+ end
74
+ end
75
+
61
76
  context 'on error with :handler' do
62
77
  subject do
63
78
  Monolens.lens('array.map' => {
@@ -0,0 +1,50 @@
1
+ require 'spec_helper'
2
+
3
+ describe Monolens, 'check.notEmpty' do
4
+ subject do
5
+ Monolens.lens('check.notEmpty' => options)
6
+ end
7
+
8
+ context 'with default options' do
9
+ let(:options) do
10
+ {}
11
+ end
12
+
13
+ it 'works on non empty strings' do
14
+ input = '12'
15
+ expect(subject.call(input)).to be(input)
16
+ end
17
+
18
+ it 'works on non empty arrays' do
19
+ input = ['12']
20
+ expect(subject.call(input)).to be(input)
21
+ end
22
+
23
+ it 'raises on empty strings' do
24
+ input = ''
25
+ expect {
26
+ subject.call(input)
27
+ }.to raise_error(Monolens::LensError, 'Input may not be empty')
28
+ end
29
+
30
+ it 'raises on empty arrays' do
31
+ input = []
32
+ expect {
33
+ subject.call(input)
34
+ }.to raise_error(Monolens::LensError, 'Input may not be empty')
35
+ end
36
+ end
37
+
38
+ context 'with a specific error message' do
39
+ let(:options) do
40
+ { message: 'Hello failure!' }
41
+ end
42
+
43
+ it 'raises on empty strings' do
44
+ input = ''
45
+ expect {
46
+ subject.call(input)
47
+ }.to raise_error(Monolens::LensError, 'Hello failure!')
48
+ end
49
+ end
50
+ end
@@ -35,7 +35,7 @@ describe Monolens, 'coerce.datetime' do
35
35
  end
36
36
 
37
37
  let(:timezone) do
38
- Object.new
38
+ Struct.new(:parse, :strptime).new(1, 2)
39
39
  end
40
40
 
41
41
  before do
File without changes
@@ -0,0 +1,73 @@
1
+ require 'spec_helper'
2
+
3
+ describe Monolens, "core.literal" do
4
+ let(:lens) do
5
+ Monolens.lens('core.literal' => { defn: 'hello' })
6
+ end
7
+
8
+ it 'works' do
9
+ input = {}
10
+ expected = 'hello'
11
+ expect(lens.call(input)).to eql(expected)
12
+ end
13
+
14
+ context 'with a simple json path expressions' do
15
+ let(:lens) do
16
+ Monolens.lens('core.literal' => { defn: '$.foo' })
17
+ end
18
+
19
+ it 'works' do
20
+ input = { 'foo' => 'bar' }
21
+ expected = 'bar'
22
+ expect(lens.call(input)).to eql(expected)
23
+ end
24
+
25
+ it 'works with symbols too' do
26
+ input = { foo: 'bar' }
27
+ expected = 'bar'
28
+ expect(lens.call(input)).to eql(expected)
29
+ end
30
+ end
31
+
32
+ context 'with an object literal with json path expressions' do
33
+ let(:lens) do
34
+ Monolens.lens('core.literal' => {
35
+ defn: {
36
+ hobbies: [{
37
+ name: '$.foo'
38
+ }]
39
+ }
40
+ })
41
+ end
42
+
43
+ it 'works' do
44
+ input = { 'foo' => 'bar' }
45
+ expected = { hobbies: [{ name: 'bar' }] }
46
+ expect(lens.call(input)).to eql(expected)
47
+ end
48
+
49
+ it 'works with symbols too' do
50
+ input = { foo: 'bar' }
51
+ expected = { hobbies: [{ name: 'bar' }] }
52
+ expect(lens.call(input)).to eql(expected)
53
+ end
54
+ end
55
+
56
+ context 'changing the root symbol' do
57
+ let(:lens) do
58
+ Monolens.lens('core.literal' => {
59
+ defn: {
60
+ one: '<.foo',
61
+ interpolate: 'Hello <(.foo)'
62
+ },
63
+ jsonpath: { root_symbol: '<' }
64
+ })
65
+ end
66
+
67
+ it 'keeps working' do
68
+ input = { foo: 'bar' }
69
+ expected = { one: 'bar', interpolate: 'Hello bar' }
70
+ expect(lens.call(input)).to eql(expected)
71
+ end
72
+ end
73
+ end
@@ -2,7 +2,7 @@ require 'spec_helper'
2
2
 
3
3
  describe Monolens, 'core.mapping' do
4
4
  let(:mapping) do
5
- { 'values' => { 'todo' => 'open' } }
5
+ { 'defn' => { 'todo' => 'open' } }
6
6
  end
7
7
 
8
8
  context 'with default options' do
@@ -49,6 +49,20 @@ describe Monolens, 'core.mapping' do
49
49
  end
50
50
  end
51
51
 
52
+ context 'on_missing: keep' do
53
+ subject do
54
+ Monolens.lens('core.mapping' => mapping.merge('on_missing' => 'keep'))
55
+ end
56
+
57
+ it 'replaces the value by its mapped' do
58
+ expect(subject.call('todo')).to eql('open')
59
+ end
60
+
61
+ it 'returns nil if missing' do
62
+ expect(subject.call('nosuchone')).to eql('nosuchone')
63
+ end
64
+ end
65
+
52
66
  context 'on_missing: fallback' do
53
67
  subject do
54
68
  Monolens.lens('core.mapping' => mapping.merge(
@@ -90,4 +104,26 @@ describe Monolens, 'core.mapping' do
90
104
  expect(subject.location).to eql([1])
91
105
  end
92
106
  end
107
+
108
+ context 'backward compatibility' do
109
+ let(:mapping) do
110
+ { 'values' => { 'todo' => 'open' } }
111
+ end
112
+
113
+ context 'with using values instead of defn' do
114
+ subject do
115
+ Monolens.lens('core.mapping' => mapping)
116
+ end
117
+
118
+ it 'replaces the value by its mapped' do
119
+ expect(subject.call('todo')).to eql('open')
120
+ end
121
+
122
+ it 'raises if not found' do
123
+ expect {
124
+ subject.call('nosuchone')
125
+ }.to raise_error(Monolens::LensError)
126
+ end
127
+ end
128
+ end
93
129
  end
@@ -0,0 +1,31 @@
1
+ require 'spec_helper'
2
+
3
+ describe Monolens, 'object.allbut' do
4
+ subject do
5
+ Monolens.lens('object.allbut' => { defn: [ :lastname, :city ] })
6
+ end
7
+
8
+ it 'works as expected' do
9
+ input = {
10
+ 'firstname' => 'Bernard',
11
+ 'lastname' => 'Lambeau',
12
+ 'city' => 'Brussels'
13
+ }
14
+ expected = {
15
+ 'firstname' => 'Bernard',
16
+ }
17
+ expect(subject.call(input)).to eql(expected)
18
+ end
19
+
20
+ it 'works as expected with Symbol keys' do
21
+ input = {
22
+ firstname: 'Bernard',
23
+ lastname: 'Lambeau',
24
+ city: 'Brussels'
25
+ }
26
+ expected = {
27
+ firstname: 'Bernard',
28
+ }
29
+ expect(subject.call(input)).to eql(expected)
30
+ end
31
+ end
@@ -0,0 +1,133 @@
1
+ describe Monolens, 'object.merge' do
2
+ subject do
3
+ Monolens.lens('object.merge' => {
4
+ priority: priority,
5
+ deep: deep,
6
+ defn: {
7
+ name: 'Monolens',
8
+ version: "1.0",
9
+ links: {
10
+ github: "https://github.com/enspirit/monolens"
11
+ },
12
+ }
13
+ }.compact)
14
+ end
15
+
16
+ let(:priority) do
17
+ nil
18
+ end
19
+
20
+ let(:deep) do
21
+ nil
22
+ end
23
+
24
+ describe 'with default options' do
25
+ it 'works as expected on a flat structure' do
26
+ input = {
27
+ version: "1.2",
28
+ extra: "foo"
29
+ }
30
+ expected = {
31
+ name: 'Monolens',
32
+ version: "1.0",
33
+ links: {
34
+ github: "https://github.com/enspirit/monolens"
35
+ },
36
+ extra: "foo"
37
+ }
38
+ expect(subject.call(input)).to eql(expected)
39
+ end
40
+
41
+ it 'does not apply a deep merge' do
42
+ input = {
43
+ links: {
44
+ owner: "https://enspirit.be/"
45
+ },
46
+ }
47
+ expected = {
48
+ name: 'Monolens',
49
+ version: "1.0",
50
+ links: {
51
+ github: "https://github.com/enspirit/monolens"
52
+ }
53
+ }
54
+ expect(subject.call(input)).to eql(expected)
55
+ end
56
+ end
57
+
58
+ describe 'priority: input' do
59
+ let(:priority) do
60
+ 'input'
61
+ end
62
+
63
+ it 'reverse the logic on shared keys' do
64
+ input = {
65
+ version: "1.2",
66
+ extra: "foo",
67
+ }
68
+ expected = {
69
+ name: 'Monolens',
70
+ version: "1.2",
71
+ links: {
72
+ github: "https://github.com/enspirit/monolens"
73
+ },
74
+ extra: "foo"
75
+ }
76
+ expect(subject.call(input)).to eql(expected)
77
+ end
78
+ end
79
+
80
+ describe 'deep: true' do
81
+ let(:deep) do
82
+ true
83
+ end
84
+
85
+ it 'applies a deep merge' do
86
+ input = {
87
+ version: "1.2",
88
+ links: {
89
+ owner: "https://enspirit.be/",
90
+ github: "https://github.com/enspirit/monolens/"
91
+ },
92
+ }
93
+ expected = {
94
+ name: 'Monolens',
95
+ version: "1.0",
96
+ links: {
97
+ owner: "https://enspirit.be/",
98
+ github: "https://github.com/enspirit/monolens"
99
+ }
100
+ }
101
+ expect(subject.call(input)).to eql(expected)
102
+ end
103
+ end
104
+
105
+ describe 'deep: true, priority: input' do
106
+ let(:deep) do
107
+ true
108
+ end
109
+
110
+ let(:priority) do
111
+ 'input'
112
+ end
113
+
114
+ it 'applies a deep merge' do
115
+ input = {
116
+ version: "1.2",
117
+ links: {
118
+ owner: "https://enspirit.be/",
119
+ github: "https://github.com/enspirit/monolens/"
120
+ },
121
+ }
122
+ expected = {
123
+ name: 'Monolens',
124
+ version: "1.2",
125
+ links: {
126
+ owner: "https://enspirit.be/",
127
+ github: "https://github.com/enspirit/monolens/"
128
+ }
129
+ }
130
+ expect(subject.call(input)).to eql(expected)
131
+ end
132
+ end
133
+ end
File without changes
File without changes
File without changes
File without changes
File without changes