monolens 0.6.0 → 0.6.1

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 836c097ee70c9517d08ce544cbd1cd9b600a846b
4
- data.tar.gz: 1af2f7a32e00bef2e3d69a0451f94c367e83d5d6
2
+ SHA256:
3
+ metadata.gz: aea34c867c10c00a01b0f7d986d7aaa76df80048d828d9ebd7083d9aa35853e9
4
+ data.tar.gz: cb611d504ff32059dd57736c0964acade1983b7e962d69504f1873fb7100a4d7
5
5
  SHA512:
6
- metadata.gz: dd6e356d995c5e1d28b9f46491abec5a95ccaa8f1efaa463600dbe4b146a97ad5ef56ecb19b69be000c24f91a4bb74afde5cbf0ce15ebcda8fd9b7b262e72e53
7
- data.tar.gz: e78d2ce7b2cfc47d83bd53ae179b1ae29d24c9edc78a131b1d2b085ab6a1d35cf2cdb3edccca256c58a937510b7d0de4440847a15b56e2d288ff2e5e9b0140a9
6
+ metadata.gz: cbecb6300c62e819c18ae4b4d8926041acb60519cfa8b33aea9e93b9c2826484c479069513e3903547ae13619e06e699b9b8c7e8f766982e97040f195388a214
7
+ data.tar.gz: '079b220b7dacd7ee54f7a3b668351f832b37ee70c2c5a9c17cf21ed6c10324eff2da4f291e0fe75e0a1f59c2932fccbdfa1cbaf66d95e742079869477920149b'
@@ -0,0 +1,95 @@
1
+ require 'minitest'
2
+ require 'paint'
3
+ module Monolens
4
+ class Command
5
+ class Tester
6
+ include Minitest::Assertions
7
+
8
+ def initialize(command)
9
+ @command = command
10
+ @nb_tests = 0
11
+ @nb_successes = 0
12
+ @nb_errors = 0
13
+ @nb_failures = 0
14
+ Paint.mode = command.use_paint? ? Paint.detect_mode : 0
15
+ end
16
+ attr_accessor :nb_tests, :nb_successes, :nb_errors, :nb_failures
17
+
18
+ def call(lens)
19
+ fail!("No tests found (#{lens.class})") unless lens.is_a?(Monolens::File)
20
+
21
+ self.nb_tests = lens.examples.size
22
+ details = []
23
+ lens.examples.each_with_index do |example, i|
24
+ test_one(lens, example, i, details)
25
+ end
26
+
27
+ stdout.puts("\n")
28
+ stdout.puts("\n") unless details.empty?
29
+ details.each do |message|
30
+ stdout.puts(message)
31
+ end
32
+
33
+ success = nb_errors == 0 && nb_failures == 0
34
+ stdout.puts(success ? green(last_sentence) : red(last_sentence))
35
+
36
+ do_exit(1) unless success
37
+ end
38
+
39
+ private
40
+
41
+ def last_sentence
42
+ sentence = "\n"
43
+ sentence << plural('test', nb_tests) << ". "
44
+ sentence << plural('success', nb_successes) << ", "
45
+ sentence << plural('failure', nb_failures) << ", "
46
+ sentence << plural('error', nb_errors) << "."
47
+ end
48
+
49
+ def test_one(lens, example, i, details = [])
50
+ input, output = example[:input], example[:output]
51
+ result = lens.call(input)
52
+ if result == output
53
+ self.nb_successes += 1
54
+ stdout.print(green ".")
55
+ else
56
+ self.nb_failures += 1
57
+ stdout.print(red "F")
58
+ details << "Failure on example #{1+i}:\n#{diff output, result}"
59
+ end
60
+ rescue Monolens::Error => ex
61
+ self.nb_errors += 1
62
+ stdout.print("E")
63
+ details << "Error on example #{1+i}: #{ex.message}"
64
+ end
65
+
66
+ def green(s)
67
+ Paint[s, :green]
68
+ end
69
+
70
+ def red(s)
71
+ Paint[s, :red]
72
+ end
73
+
74
+ def plural(who, nb)
75
+ if nb > 1
76
+ "#{nb} #{who}s"
77
+ else
78
+ "#{nb} #{who}"
79
+ end
80
+ end
81
+
82
+ [
83
+ :stdout,
84
+ :stderr,
85
+ :do_exit,
86
+ :fail!
87
+ ].each do |name|
88
+ define_method(name) do |*args, &bl|
89
+ @command.send(name, *args, &bl)
90
+ end
91
+ end
92
+
93
+ end
94
+ end
95
+ end
@@ -16,14 +16,21 @@ module Monolens
16
16
  @stream = false
17
17
  @fail_strategy = 'fail'
18
18
  @override = false
19
+ @execute_tests = false
19
20
  #
20
21
  @input_file = nil
21
22
  @use_stdin = false
23
+ #
24
+ @use_paint = true
22
25
  end
23
26
  attr_reader :argv, :stdin, :stdout, :stderr
24
27
  attr_reader :pretty, :stream, :override
25
28
  attr_reader :enclose_map, :fail_strategy
26
29
  attr_reader :input_file, :use_stdin
30
+ attr_reader :use_paint
31
+ alias :use_paint? :use_paint
32
+ attr_reader :execute_tests
33
+ alias :execute_tests? :execute_tests
27
34
 
28
35
  def self.call(argv, stdin = $stdin, stdout = $stdout, stderr = $stderr)
29
36
  new(argv, stdin, stdout, stderr).call
@@ -31,21 +38,30 @@ module Monolens
31
38
 
32
39
  def call
33
40
  lens, @input_file = options.parse!(argv)
34
- show_help_and_exit if lens.nil? || (@input_file.nil? && !use_stdin)
41
+ show_help_and_exit if lens.nil? || (@input_file.nil? && !use_stdin && !execute_tests?)
35
42
 
36
- lens_data, input = read_file(lens), read_input
37
- lens = build_lens(lens_data)
38
- error_handler = ErrorHandler.new
39
- result = lens.call(input, error_handler: error_handler)
43
+ lens = build_lens(read_file(lens))
44
+ if execute_tests?
45
+ execute_tests!(lens)
46
+ else
47
+ input = read_input
48
+ error_handler = ErrorHandler.new
49
+ result = lens.call(input, error_handler: error_handler)
40
50
 
41
- unless error_handler.empty?
42
- stderr.puts(error_handler.report)
43
- end
51
+ unless error_handler.empty?
52
+ stderr.puts(error_handler.report)
53
+ end
44
54
 
45
- output_result(result) if result
55
+ output_result(result) if result
56
+ end
46
57
  rescue Monolens::LensError => ex
47
58
  stderr.puts("[#{ex.location.join('/')}] #{ex.message}")
48
- do_exit(-2)
59
+ do_exit(1)
60
+ end
61
+
62
+ def execute_tests!(lens)
63
+ require_relative 'command/tester'
64
+ Tester.new(self).call(lens)
49
65
  end
50
66
 
51
67
  def read_input
@@ -130,6 +146,12 @@ module Monolens
130
146
  opts.on('--override', 'Write output back to the input file') do
131
147
  @override = true
132
148
  end
149
+ opts.on('--test', 'Execute tests embedded in the lens file') do
150
+ @execute_tests = true
151
+ end
152
+ opts.on('--[no-]paint', 'Do (not) paint error messages') do |flag|
153
+ @use_paint = flag
154
+ end
133
155
  end
134
156
  end
135
157
 
@@ -150,7 +172,7 @@ module Monolens
150
172
  }
151
173
  }
152
174
  end
153
- end
175
+ end unless execute_tests?
154
176
  Monolens.lens(lens_data)
155
177
  end
156
178
 
data/lib/monolens/file.rb CHANGED
@@ -6,10 +6,15 @@ module Monolens
6
6
  version: [Type::Any, true],
7
7
  macros: [Type::Map.of(Type::Name, Type::Any), false],
8
8
  lenses: [Type::Lenses, true],
9
+ examples: [Type::Array.of(Type::Map.of(Type::Name, Type::Any)), false],
9
10
  })
10
11
 
11
12
  def call(arg, world = {})
12
13
  option(:lenses).call(arg, world)
13
14
  end
15
+
16
+ def examples
17
+ option(:examples, [])
18
+ end
14
19
  end
15
20
  end
@@ -2,7 +2,7 @@ module Monolens
2
2
  module Version
3
3
  MAJOR = 0
4
4
  MINOR = 6
5
- TINY = 0
5
+ TINY = 1
6
6
  end
7
7
  VERSION = "#{Version::MAJOR}.#{Version::MINOR}.#{Version::TINY}"
8
8
  end
@@ -0,0 +1,15 @@
1
+ ---
2
+ version: '1.0'
3
+ lenses:
4
+ - array.map:
5
+ lenses:
6
+ - core.literal:
7
+ defn:
8
+ name: $.name
9
+ examples:
10
+ - input:
11
+ - name: Monolens
12
+ - name: Bmg
13
+ output:
14
+ - name: Monolens
15
+ - name: BMG
@@ -0,0 +1,13 @@
1
+ ---
2
+ version: '1.0'
3
+ lenses:
4
+ - str.upcase
5
+ examples:
6
+ - input:
7
+ Monolens
8
+ output:
9
+ Monolens
10
+ - input:
11
+ Monolens
12
+ output:
13
+ MONOLENS
@@ -0,0 +1,9 @@
1
+ ---
2
+ version: '1.0'
3
+ lenses:
4
+ - str.upcase
5
+ examples:
6
+ - input:
7
+ Monolens
8
+ output:
9
+ MONOLENS
@@ -235,13 +235,46 @@ module Monolens
235
235
  end
236
236
  end
237
237
 
238
+ context 'with --paint --test (ignoring --map, --literal)' do
239
+ let(:argv) do
240
+ ['--map', '--literal', '--paint', '--test', FIXTURES/'test-ok.lens.yml']
241
+ end
242
+
243
+ it 'works as expected' do
244
+ expect(stdout.string).to match(/1 test. 1 success, 0 failure, 0 error./)
245
+ expect(exit_status).to be_nil
246
+ end
247
+ end
248
+
249
+ context 'with --no-paint --test' do
250
+ let(:argv) do
251
+ ['--no-paint', '--test', FIXTURES/'test-ok.lens.yml']
252
+ end
253
+
254
+ it 'works as expected' do
255
+ expect(stdout.string).to eql(".\n\n1 test. 1 success, 0 failure, 0 error.\n")
256
+ expect(exit_status).to be_nil
257
+ end
258
+ end
259
+
260
+ context 'with --no-paint --test with failures' do
261
+ let(:argv) do
262
+ ['--no-paint', '--test', FIXTURES/'test-ko.lens.yml']
263
+ end
264
+
265
+ it 'works as expected' do
266
+ expect(stdout.string).to eql("F.\n\nFailure on example 1:\nExpected: \"Monolens\"\n Actual: \"MONOLENS\"\n\n2 tests. 1 success, 1 failure, 0 error.\n")
267
+ expect(exit_status).to eql(1)
268
+ end
269
+ end
270
+
238
271
  context 'when yielding an error' do
239
272
  let(:argv) do
240
273
  [FIXTURES/'map-upcase.lens.yml', FIXTURES/'names-with-null.json']
241
274
  end
242
275
 
243
276
  it 'works as expected' do
244
- expect(exit_status).to eql(-2)
277
+ expect(exit_status).to eql(1)
245
278
  expect(stdout.string).to eql('')
246
279
  expect(stderr.string).to eql("[1] String expected, got NilClass\n")
247
280
  end
metadata CHANGED
@@ -1,15 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: monolens
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.0
4
+ version: 0.6.1
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-07-08 00:00:00.000000000 Z
11
+ date: 2022-07-15 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: minitest
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '5.16'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '5.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: paint
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '2.3'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '2.3'
13
41
  - !ruby/object:Gem::Dependency
14
42
  name: rake
15
43
  requirement: !ruby/object:Gem::Requirement
@@ -80,6 +108,7 @@ files:
80
108
  - bin/monolens
81
109
  - lib/monolens.rb
82
110
  - lib/monolens/command.rb
111
+ - lib/monolens/command/tester.rb
83
112
  - lib/monolens/error.rb
84
113
  - lib/monolens/error_handler.rb
85
114
  - lib/monolens/file.rb
@@ -154,6 +183,9 @@ files:
154
183
  - spec/monolens/command/names-with-null.json
155
184
  - spec/monolens/command/names.json
156
185
  - spec/monolens/command/robust-map-upcase.lens.yml
186
+ - spec/monolens/command/test-ko-complex.yml
187
+ - spec/monolens/command/test-ko.lens.yml
188
+ - spec/monolens/command/test-ok.lens.yml
157
189
  - spec/monolens/command/upcase.lens.yml
158
190
  - spec/monolens/lens/test_options.rb
159
191
  - spec/monolens/lens/test_signature.rb
@@ -210,8 +242,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
210
242
  - !ruby/object:Gem::Version
211
243
  version: '0'
212
244
  requirements: []
213
- rubyforge_project:
214
- rubygems_version: 2.6.14.4
245
+ rubygems_version: 3.1.4
215
246
  signing_key:
216
247
  specification_version: 4
217
248
  summary: Data transformations inspired by Cambria lenses