monolens 0.1.0 → 0.4.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 (73) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +14 -4
  3. data/bin/monolens +11 -0
  4. data/lib/monolens/array/compact.rb +2 -2
  5. data/lib/monolens/array/join.rb +13 -0
  6. data/lib/monolens/array/map.rb +57 -0
  7. data/lib/monolens/array.rb +12 -0
  8. data/lib/monolens/coerce/date.rb +22 -6
  9. data/lib/monolens/coerce/date_time.rb +30 -6
  10. data/lib/monolens/coerce/integer.rb +15 -0
  11. data/lib/monolens/coerce/string.rb +13 -0
  12. data/lib/monolens/coerce.rb +12 -3
  13. data/lib/monolens/command.rb +87 -0
  14. data/lib/monolens/core/chain.rb +2 -2
  15. data/lib/monolens/core/dig.rb +52 -0
  16. data/lib/monolens/core/mapping.rb +15 -0
  17. data/lib/monolens/core.rb +10 -4
  18. data/lib/monolens/error.rb +9 -2
  19. data/lib/monolens/error_handler.rb +21 -0
  20. data/lib/monolens/file.rb +2 -7
  21. data/lib/monolens/lens/fetch_support.rb +19 -0
  22. data/lib/monolens/lens/location.rb +17 -0
  23. data/lib/monolens/lens/options.rb +41 -0
  24. data/lib/monolens/lens.rb +41 -18
  25. data/lib/monolens/object/extend.rb +53 -0
  26. data/lib/monolens/object/keys.rb +8 -10
  27. data/lib/monolens/object/rename.rb +3 -3
  28. data/lib/monolens/object/select.rb +58 -0
  29. data/lib/monolens/object/transform.rb +34 -12
  30. data/lib/monolens/object/values.rb +34 -10
  31. data/lib/monolens/object.rb +12 -0
  32. data/lib/monolens/skip/null.rb +1 -1
  33. data/lib/monolens/str/downcase.rb +2 -2
  34. data/lib/monolens/str/split.rb +14 -0
  35. data/lib/monolens/str/strip.rb +3 -1
  36. data/lib/monolens/str/upcase.rb +2 -2
  37. data/lib/monolens/str.rb +12 -6
  38. data/lib/monolens/version.rb +1 -1
  39. data/lib/monolens.rb +7 -1
  40. data/spec/fixtures/coerce.yml +3 -2
  41. data/spec/fixtures/transform.yml +5 -4
  42. data/spec/monolens/array/test_compact.rb +15 -0
  43. data/spec/monolens/array/test_join.rb +27 -0
  44. data/spec/monolens/array/test_map.rb +96 -0
  45. data/spec/monolens/coerce/test_date.rb +34 -4
  46. data/spec/monolens/coerce/test_datetime.rb +70 -7
  47. data/spec/monolens/coerce/test_integer.rb +46 -0
  48. data/spec/monolens/coerce/test_string.rb +15 -0
  49. data/spec/monolens/command/map-upcase.lens.yml +5 -0
  50. data/spec/monolens/command/names-with-null.json +5 -0
  51. data/spec/monolens/command/names.json +4 -0
  52. data/spec/monolens/command/robust-map-upcase.lens.yml +7 -0
  53. data/spec/monolens/core/test_dig.rb +78 -0
  54. data/spec/monolens/core/test_mapping.rb +76 -0
  55. data/spec/monolens/lens/test_options.rb +73 -0
  56. data/spec/monolens/object/test_extend.rb +94 -0
  57. data/spec/monolens/object/test_keys.rb +54 -22
  58. data/spec/monolens/object/test_rename.rb +1 -1
  59. data/spec/monolens/object/test_select.rb +202 -0
  60. data/spec/monolens/object/test_transform.rb +93 -6
  61. data/spec/monolens/object/test_values.rb +110 -12
  62. data/spec/monolens/skip/test_null.rb +2 -2
  63. data/spec/monolens/str/test_downcase.rb +13 -0
  64. data/spec/monolens/str/test_split.rb +39 -0
  65. data/spec/monolens/str/test_strip.rb +13 -0
  66. data/spec/monolens/str/test_upcase.rb +13 -0
  67. data/spec/monolens/test_command.rb +128 -0
  68. data/spec/monolens/test_error_traceability.rb +60 -0
  69. data/spec/monolens/test_lens.rb +1 -1
  70. data/spec/test_readme.rb +8 -6
  71. metadata +39 -5
  72. data/lib/monolens/core/map.rb +0 -18
  73. data/spec/monolens/core/test_map.rb +0 -11
@@ -0,0 +1,128 @@
1
+ require 'spec_helper'
2
+ require 'stringio'
3
+ require 'monolens'
4
+ require 'monolens/command'
5
+
6
+ module Monolens
7
+ class Exited < Monolens::Error
8
+ end
9
+ class Command
10
+ attr_reader :exit_status
11
+
12
+ def do_exit(status)
13
+ @exit_status = status
14
+ raise Exited
15
+ end
16
+ end
17
+ describe Command do
18
+ FIXTURES = (Path.dir/"command").expand_path
19
+
20
+ let(:command) do
21
+ Command.new(argv, stdin, stdout, stderr)
22
+ end
23
+
24
+ let(:stdin) do
25
+ StringIO.new
26
+ end
27
+
28
+ let(:stdout) do
29
+ StringIO.new
30
+ end
31
+
32
+ let(:stderr) do
33
+ StringIO.new
34
+ end
35
+
36
+ let(:file_args) do
37
+ [FIXTURES/'map-upcase.lens.yml', FIXTURES/'names.json']
38
+ end
39
+
40
+ subject do
41
+ begin
42
+ command.call
43
+ rescue Exited
44
+ end
45
+ end
46
+
47
+ before do
48
+ subject
49
+ end
50
+
51
+ def exit_status
52
+ command.exit_status
53
+ end
54
+
55
+ def reloaded_json
56
+ JSON.parse(stdout.string)
57
+ end
58
+
59
+ context 'with no option nor args' do
60
+ let(:argv) do
61
+ []
62
+ end
63
+
64
+ it 'prints the help and exits' do
65
+ expect(exit_status).to eql(0)
66
+ expect(stdout.string).to match(/monolens/)
67
+ end
68
+ end
69
+
70
+ context 'with --version' do
71
+ let(:argv) do
72
+ ['--version']
73
+ end
74
+
75
+ it 'prints the version and exits' do
76
+ expect(exit_status).to eql(0)
77
+ expect(stdout.string).to eql("Monolens v#{VERSION} - (c) Enspirit #{Date.today.year}\n")
78
+ end
79
+ end
80
+
81
+ context 'with a lens and a json input' do
82
+ let(:argv) do
83
+ file_args
84
+ end
85
+
86
+ it 'works as expected' do
87
+ expect(exit_status).to be_nil
88
+ expect(reloaded_json).to eql(['BERNARD', 'DAVID'])
89
+ end
90
+ end
91
+
92
+ context 'with --pretty' do
93
+ let(:argv) do
94
+ ['--pretty'] + file_args
95
+ end
96
+
97
+ it 'works as expected' do
98
+ expect(exit_status).to be_nil
99
+ expect(stdout.string).to match(/^\[\n/)
100
+ expect(reloaded_json).to eql(['BERNARD', 'DAVID'])
101
+ end
102
+ end
103
+
104
+ context 'when yielding an error' do
105
+ let(:argv) do
106
+ [FIXTURES/'map-upcase.lens.yml', FIXTURES/'names-with-null.json']
107
+ end
108
+
109
+ it 'works as expected' do
110
+ expect(exit_status).to eql(-2)
111
+ expect(stdout.string).to eql('')
112
+ expect(stderr.string).to eql("[1] String expected, got NilClass\n")
113
+ end
114
+ end
115
+
116
+ context 'when yielding an error on a robust lens' do
117
+ let(:argv) do
118
+ [FIXTURES/'robust-map-upcase.lens.yml', FIXTURES/'names-with-null.json']
119
+ end
120
+
121
+ it 'works as expected' do
122
+ expect(exit_status).to be_nil
123
+ expect(stdout.string).to eql('["BERNARD","DAVID"]'+"\n")
124
+ expect(stderr.string).to eql("[1] String expected, got NilClass\n")
125
+ end
126
+ end
127
+ end
128
+ end
@@ -0,0 +1,60 @@
1
+ require 'spec_helper'
2
+
3
+ describe Monolens, 'error traceability' do
4
+ context 'on a leaf monolens' do
5
+ let(:lens) do
6
+ Monolens.lens('str.upcase')
7
+ end
8
+
9
+ subject do
10
+ begin
11
+ lens.call(nil)
12
+ rescue => ex
13
+ ex
14
+ end
15
+ end
16
+
17
+ it 'works as expected' do
18
+ expect(subject).to be_a(Monolens::LensError)
19
+ expect(subject.location).to eql([])
20
+ end
21
+ end
22
+
23
+ context 'on array.map' do
24
+ let(:lens) do
25
+ Monolens.lens('array.map' => 'str.upcase')
26
+ end
27
+
28
+ subject do
29
+ begin
30
+ lens.call(['foo', nil])
31
+ rescue => ex
32
+ ex
33
+ end
34
+ end
35
+
36
+ it 'works as expected' do
37
+ expect(subject).to be_a(Monolens::LensError)
38
+ expect(subject.location).to eql([1])
39
+ end
40
+ end
41
+
42
+ context 'on array.map => object.values' do
43
+ let(:lens) do
44
+ Monolens.lens('array.map' => { lenses: { 'object.values' => 'str.upcase' } })
45
+ end
46
+
47
+ subject do
48
+ begin
49
+ lens.call([{ hello: 'foo' }, { hello: nil }])
50
+ rescue Monolens::LensError => ex
51
+ ex
52
+ end
53
+ end
54
+
55
+ it 'works as expected' do
56
+ expect(subject).to be_a(Monolens::LensError)
57
+ expect(subject.location).to eql([1, :hello])
58
+ end
59
+ end
60
+ end
@@ -16,7 +16,7 @@ describe Monolens, '.lens' do
16
16
  it 'preserves options' do
17
17
  got = Monolens.lens(:"coerce.date" => { formats: ['%Y'] })
18
18
  expect(got).to be_a(Monolens::Coerce::Date)
19
- expect(got.options).to eql({ formats: ['%Y'] })
19
+ expect(got.options.to_h).to eql({ formats: ['%Y'] })
20
20
  end
21
21
 
22
22
  it 'allows using an Array, factors a Chain with coercion recursion' do
data/spec/test_readme.rb CHANGED
@@ -21,14 +21,16 @@ describe "What's said in README" do
21
21
  ---
22
22
  version: 1.0
23
23
  lenses:
24
- - map:
24
+ - array.map:
25
25
  - object.transform:
26
- status:
27
- - str.upcase
28
- body:
29
- - str.strip
26
+ defn:
27
+ status:
28
+ - str.upcase
29
+ body:
30
+ - str.strip
30
31
  - object.rename:
31
- body: description
32
+ defn:
33
+ body: description
32
34
  YML
33
35
  }
34
36
 
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: monolens
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Bernard Lambeau
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-05-04 00:00:00.000000000 Z
11
+ date: 2022-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -62,41 +62,74 @@ files:
62
62
  - LICENSE.md
63
63
  - README.md
64
64
  - Rakefile
65
+ - bin/monolens
65
66
  - lib/monolens.rb
66
67
  - lib/monolens/array.rb
67
68
  - lib/monolens/array/compact.rb
69
+ - lib/monolens/array/join.rb
70
+ - lib/monolens/array/map.rb
68
71
  - lib/monolens/coerce.rb
69
72
  - lib/monolens/coerce/date.rb
70
73
  - lib/monolens/coerce/date_time.rb
74
+ - lib/monolens/coerce/integer.rb
75
+ - lib/monolens/coerce/string.rb
76
+ - lib/monolens/command.rb
71
77
  - lib/monolens/core.rb
72
78
  - lib/monolens/core/chain.rb
73
- - lib/monolens/core/map.rb
79
+ - lib/monolens/core/dig.rb
80
+ - lib/monolens/core/mapping.rb
74
81
  - lib/monolens/error.rb
82
+ - lib/monolens/error_handler.rb
75
83
  - lib/monolens/file.rb
76
84
  - lib/monolens/lens.rb
85
+ - lib/monolens/lens/fetch_support.rb
86
+ - lib/monolens/lens/location.rb
87
+ - lib/monolens/lens/options.rb
77
88
  - lib/monolens/object.rb
89
+ - lib/monolens/object/extend.rb
78
90
  - lib/monolens/object/keys.rb
79
91
  - lib/monolens/object/rename.rb
92
+ - lib/monolens/object/select.rb
80
93
  - lib/monolens/object/transform.rb
81
94
  - lib/monolens/object/values.rb
82
95
  - lib/monolens/skip.rb
83
96
  - lib/monolens/skip/null.rb
84
97
  - lib/monolens/str.rb
85
98
  - lib/monolens/str/downcase.rb
99
+ - lib/monolens/str/split.rb
86
100
  - lib/monolens/str/strip.rb
87
101
  - lib/monolens/str/upcase.rb
88
102
  - lib/monolens/version.rb
89
103
  - spec/fixtures/coerce.yml
90
104
  - spec/fixtures/simple.yml
91
105
  - spec/fixtures/transform.yml
106
+ - spec/monolens/array/test_compact.rb
107
+ - spec/monolens/array/test_join.rb
108
+ - spec/monolens/array/test_map.rb
92
109
  - spec/monolens/coerce/test_date.rb
93
110
  - spec/monolens/coerce/test_datetime.rb
94
- - spec/monolens/core/test_map.rb
111
+ - spec/monolens/coerce/test_integer.rb
112
+ - spec/monolens/coerce/test_string.rb
113
+ - spec/monolens/command/map-upcase.lens.yml
114
+ - spec/monolens/command/names-with-null.json
115
+ - spec/monolens/command/names.json
116
+ - spec/monolens/command/robust-map-upcase.lens.yml
117
+ - spec/monolens/core/test_dig.rb
118
+ - spec/monolens/core/test_mapping.rb
119
+ - spec/monolens/lens/test_options.rb
120
+ - spec/monolens/object/test_extend.rb
95
121
  - spec/monolens/object/test_keys.rb
96
122
  - spec/monolens/object/test_rename.rb
123
+ - spec/monolens/object/test_select.rb
97
124
  - spec/monolens/object/test_transform.rb
98
125
  - spec/monolens/object/test_values.rb
99
126
  - spec/monolens/skip/test_null.rb
127
+ - spec/monolens/str/test_downcase.rb
128
+ - spec/monolens/str/test_split.rb
129
+ - spec/monolens/str/test_strip.rb
130
+ - spec/monolens/str/test_upcase.rb
131
+ - spec/monolens/test_command.rb
132
+ - spec/monolens/test_error_traceability.rb
100
133
  - spec/monolens/test_lens.rb
101
134
  - spec/spec_helper.rb
102
135
  - spec/test_monolens.rb
@@ -122,7 +155,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
122
155
  - !ruby/object:Gem::Version
123
156
  version: '0'
124
157
  requirements: []
125
- rubygems_version: 3.1.4
158
+ rubyforge_project:
159
+ rubygems_version: 2.6.14.4
126
160
  signing_key:
127
161
  specification_version: 4
128
162
  summary: Data transformations inspired by Cambria lenses
@@ -1,18 +0,0 @@
1
- module Monolens
2
- module Core
3
- class Map
4
- include Lens
5
-
6
- def initialize(lens)
7
- super({})
8
- @lens = Monolens.lens(lens)
9
- end
10
-
11
- def call(arg, *rest)
12
- is_enumerable!(arg)
13
-
14
- arg.map { |a| @lens.call(a) }
15
- end
16
- end
17
- end
18
- end
@@ -1,11 +0,0 @@
1
- require 'spec_helper'
2
-
3
- describe Monolens, 'map' do
4
- subject do
5
- Monolens.lens('map' => ['str.upcase'])
6
- end
7
-
8
- it 'maps as expected' do
9
- expect(subject.call(['foo','bar'])).to eql(['FOO','BAR'])
10
- end
11
- end