nrser 0.0.29 → 0.0.30
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/nrser/enumerable.rb +80 -0
- data/lib/nrser/errors.rb +47 -0
- data/lib/nrser/refinements/enumerable.rb +15 -1
- data/lib/nrser/rspex.rb +60 -2
- data/lib/nrser/version.rb +1 -1
- data/spec/nrser/text/dedent/gotchas_spec.rb +61 -0
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: e894a45a17099589d7b23f53b7b2c416d448b6d3
|
4
|
+
data.tar.gz: 9e66a57ccee2dba38b1bf16e45a55197fa80ccac
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1132214b192658affc169b261f8d9840cbae0d2f3c33e2a7f48c64e2bfb6876411b50e5a3aa0b22a5245d82aa5dae5b48ef3c16fee9fa4b1ab295793b9ff7413
|
7
|
+
data.tar.gz: 1676e9d23b8182bc24447008410498aeace1b57a5c0400f02da39cb1e2e64cb2f24099253dc0ad3815c9fb00e9de24e899ee5a5c6389cffc219aa1e711211a6e
|
data/lib/nrser/enumerable.rb
CHANGED
@@ -204,5 +204,85 @@ module NRSER
|
|
204
204
|
end # #enumerate_as_values
|
205
205
|
|
206
206
|
|
207
|
+
# Count entries in an {Enumerable} by the value returned when they are
|
208
|
+
# passed to the block.
|
209
|
+
#
|
210
|
+
# @example Count array entries by class
|
211
|
+
#
|
212
|
+
# [1, 2, :three, 'four', 5, :six].count_by &:class
|
213
|
+
# # => {Fixnum=>3, Symbol=>2, String=>1}
|
214
|
+
#
|
215
|
+
# @param [Enumerable<E>] enum
|
216
|
+
# {Enumerable} (or other object with compatible `#each_with_object` and
|
217
|
+
# `#to_enum` methods) you want to count.
|
218
|
+
#
|
219
|
+
# @param [Proc<(E)=>C>] &block
|
220
|
+
# Block mapping entries in `enum` to the group to count them in.
|
221
|
+
#
|
222
|
+
# @return [Hash{C=>Integer}]
|
223
|
+
# Hash mapping groups to positive integer counts.
|
224
|
+
#
|
225
|
+
def count_by enum, &block
|
226
|
+
enum.each_with_object( Hash.new 0 ) do |entry, hash|
|
227
|
+
hash[block.call entry] += 1
|
228
|
+
end
|
229
|
+
end
|
230
|
+
|
231
|
+
|
232
|
+
# Like `Enumerable#find`, but wraps each call to `&block` in a
|
233
|
+
# `begin` / `rescue`, returning the result of the first call that doesn't
|
234
|
+
# raise an error.
|
235
|
+
#
|
236
|
+
# If no calls succeed, raises a {NRSER::MultipleErrors} containing the
|
237
|
+
# errors from the block calls.
|
238
|
+
#
|
239
|
+
# @param [Enumerable<E>] enum
|
240
|
+
# Values to call `&block` with.
|
241
|
+
#
|
242
|
+
# @param [Proc<E=>V>] &block
|
243
|
+
# Block to call, which is expected to raise an error if it fails.
|
244
|
+
#
|
245
|
+
# @return [V]
|
246
|
+
# Result of first call to `&block` that doesn't raise.
|
247
|
+
#
|
248
|
+
# @raise [ArgumentError]
|
249
|
+
# If `enum` was empty (`enum#each` never yielded).
|
250
|
+
#
|
251
|
+
# @raise [NRSER::MultipleErrors]
|
252
|
+
# If all calls to `&block` failed.
|
253
|
+
#
|
254
|
+
def try_find enum, &block
|
255
|
+
errors = []
|
256
|
+
|
257
|
+
enum.each do |*args|
|
258
|
+
begin
|
259
|
+
result = block.call *args
|
260
|
+
rescue Exception => error
|
261
|
+
errors << error
|
262
|
+
else
|
263
|
+
return result
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
if errors.empty?
|
268
|
+
raise ArgumentError,
|
269
|
+
"Appears that enumerable was empty: #{ enum.inspect }"
|
270
|
+
else
|
271
|
+
raise NRSER::MultipleErrors.new errors
|
272
|
+
end
|
273
|
+
end
|
274
|
+
|
275
|
+
|
276
|
+
# TODO It would be nice for this to work...
|
277
|
+
#
|
278
|
+
# def to_enum object, meth, *args
|
279
|
+
# unless object.respond_to?( meth )
|
280
|
+
# object = NRSER::Enumerable.new object
|
281
|
+
# end
|
282
|
+
#
|
283
|
+
# object.to_enum meth, *args
|
284
|
+
# end
|
285
|
+
|
286
|
+
|
207
287
|
end # class << self (Eigenclass)
|
208
288
|
end # module NRSER
|
data/lib/nrser/errors.rb
CHANGED
@@ -55,5 +55,52 @@ module NRSER
|
|
55
55
|
end # #initialize
|
56
56
|
|
57
57
|
end # class AbstractMethodError
|
58
|
+
|
59
|
+
|
60
|
+
# A wrapper error around a list of other errors.
|
61
|
+
#
|
62
|
+
class MultipleErrors < StandardError
|
63
|
+
|
64
|
+
# Attributes
|
65
|
+
# ======================================================================
|
66
|
+
|
67
|
+
# The individual errors that occurred.
|
68
|
+
#
|
69
|
+
# @return [Array<Exception>]
|
70
|
+
#
|
71
|
+
attr_reader :errors
|
72
|
+
|
73
|
+
|
74
|
+
# Constructor
|
75
|
+
# ======================================================================
|
76
|
+
|
77
|
+
# Instantiate a new `MultipleErrors`.
|
78
|
+
def initialize errors, headline: nil
|
79
|
+
@errors = errors
|
80
|
+
|
81
|
+
if headline.nil?
|
82
|
+
class_counts = NRSER.count_by( errors, &:class ).
|
83
|
+
map { |klass, count| "#{ klass } (#{ count })" }.
|
84
|
+
join( ', ' )
|
85
|
+
|
86
|
+
headline = "#{ errors.count } error(s) occurred - #{ class_counts }"
|
87
|
+
end
|
88
|
+
|
89
|
+
message = NRSER.erb binding, <<-END
|
90
|
+
<%= headline %>
|
91
|
+
|
92
|
+
<% errors.each_with_index do |error, index| %>
|
93
|
+
<%= (index.succ.to_s + ".").ljust( 3 ) %> <%= error.message %> (<%= error.class %>):
|
94
|
+
<%= error.backtrace.join( $/ ) %>
|
95
|
+
<% end %>
|
96
|
+
|
97
|
+
END
|
98
|
+
|
99
|
+
super message
|
100
|
+
end # #initialize
|
101
|
+
|
102
|
+
|
103
|
+
end # class MultipleErrors
|
104
|
+
|
58
105
|
|
59
106
|
end # module NRSER
|
@@ -32,20 +32,34 @@ module NRSER::Refinements::Enumerable
|
|
32
32
|
NRSER.to_h_by self, &block
|
33
33
|
end
|
34
34
|
|
35
|
+
|
35
36
|
# See {NRSER.enumerate_as_values}
|
36
37
|
def enumerate_as_values
|
37
38
|
NRSER.enumerate_as_values self
|
38
39
|
end
|
39
40
|
|
41
|
+
|
40
42
|
# Calls {NRSER.only} on `self`.
|
41
43
|
def only **options
|
42
44
|
NRSER.only self, **options
|
43
45
|
end
|
44
46
|
|
47
|
+
|
45
48
|
# See {NRSER.only!}
|
46
49
|
def only!
|
47
50
|
NRSER.only! self
|
48
51
|
end
|
49
52
|
|
53
|
+
|
54
|
+
# See {NRSER.count_by}
|
55
|
+
def count_by &block
|
56
|
+
NRSER.count_by self, &block
|
57
|
+
end
|
58
|
+
|
59
|
+
|
60
|
+
# See {NRSER.try_find}
|
61
|
+
def try_find &block
|
62
|
+
NRSER.try_find self, &block
|
63
|
+
end
|
64
|
+
|
50
65
|
end # module NRSER::Refinements::Enumerable
|
51
|
-
|
data/lib/nrser/rspex.rb
CHANGED
@@ -272,7 +272,58 @@ module NRSER::RSpex
|
|
272
272
|
module_exec &body
|
273
273
|
end # description,
|
274
274
|
|
275
|
-
end # #
|
275
|
+
end # #describe_x_type
|
276
|
+
|
277
|
+
|
278
|
+
# **EXPERIMENTAL**
|
279
|
+
#
|
280
|
+
# Example group helper for use at the top level of each spec file to
|
281
|
+
# set a bunch of stuff up and build a helpful description.
|
282
|
+
#
|
283
|
+
# @todo
|
284
|
+
# This is totally just a one-off right now... would need to be
|
285
|
+
# generalized quite a bit...
|
286
|
+
#
|
287
|
+
# 1. Extraction of module, class, etc from metadata should be flexible
|
288
|
+
#
|
289
|
+
# 2. Built description would need to be conditional on what metadata
|
290
|
+
# was found.
|
291
|
+
#
|
292
|
+
# @param [String] description:
|
293
|
+
# A description of the spec file to add to the RSpec description.
|
294
|
+
#
|
295
|
+
# @param [String] spec_path:
|
296
|
+
# The path to the spec file (just feed it `__FILE__`).
|
297
|
+
#
|
298
|
+
# Probably possible to extract this somehow without having to provide it?
|
299
|
+
#
|
300
|
+
# @return [nil]
|
301
|
+
#
|
302
|
+
def describe_spec_file description:,
|
303
|
+
spec_path:,
|
304
|
+
bind_subject: true,
|
305
|
+
**metadata,
|
306
|
+
&body
|
307
|
+
|
308
|
+
meth = metadata[:module].method metadata[:method]
|
309
|
+
file, line = meth.source_location
|
310
|
+
path = Pathname.new file
|
311
|
+
loc = "./#{ path.relative_path_from Pathname.getwd }:#{ line }"
|
312
|
+
|
313
|
+
spec_rel_path = "./#{ Pathname.new( spec_path ).relative_path_from Pathname.getwd }"
|
314
|
+
|
315
|
+
desc = "#{ metadata[:module].name }.#{ metadata[:method] } (#{ loc }) #{ description } Spec (#{ spec_rel_path})"
|
316
|
+
|
317
|
+
describe desc, **metadata do
|
318
|
+
if bind_subject
|
319
|
+
subject { meth }
|
320
|
+
end
|
321
|
+
|
322
|
+
module_exec &body
|
323
|
+
end
|
324
|
+
|
325
|
+
nil
|
326
|
+
end # #describe_spec_file
|
276
327
|
|
277
328
|
|
278
329
|
# @todo Document describe_instance method.
|
@@ -435,12 +486,17 @@ module NRSER::RSpex
|
|
435
486
|
end
|
436
487
|
|
437
488
|
|
438
|
-
def describe_module mod, **metadata, &block
|
489
|
+
def describe_module mod, bind_subject: true, **metadata, &block
|
439
490
|
describe(
|
440
491
|
"#{ NRSER::RSpex::PREFIXES[:module] } #{ mod.name }",
|
441
492
|
type: :module,
|
493
|
+
module: mod,
|
442
494
|
**metadata
|
443
495
|
) do
|
496
|
+
if bind_subject
|
497
|
+
subject { mod }
|
498
|
+
end
|
499
|
+
|
444
500
|
module_exec &block
|
445
501
|
end
|
446
502
|
end # #describe_module
|
@@ -567,6 +623,8 @@ RSpec.configure do |config|
|
|
567
623
|
config.add_setting :x_type_prefixes
|
568
624
|
config.x_type_prefixes = \
|
569
625
|
NRSER::RSpex::PREFIXES_BASE.merge( NRSER::RSpex::PREFIXES_MATH_ITALIC )
|
626
|
+
|
627
|
+
config.add_setting :x_type_prefixes
|
570
628
|
end
|
571
629
|
|
572
630
|
# Make available at the top-level
|
data/lib/nrser/version.rb
CHANGED
@@ -0,0 +1,61 @@
|
|
1
|
+
describe_spec_file(
|
2
|
+
description: "Gotchas",
|
3
|
+
spec_path: __FILE__,
|
4
|
+
module: NRSER,
|
5
|
+
method: :dedent,
|
6
|
+
) do
|
7
|
+
|
8
|
+
describe_section "Newline literals in HEREDOCs" do
|
9
|
+
# ========================================================================
|
10
|
+
|
11
|
+
subject do
|
12
|
+
super().call input
|
13
|
+
end
|
14
|
+
|
15
|
+
describe_group "when a HEREDOC has a with literal \\n" do
|
16
|
+
# ========================================================================
|
17
|
+
|
18
|
+
let :input do
|
19
|
+
<<-END
|
20
|
+
<%= headline %>
|
21
|
+
|
22
|
+
<% errors.each_with_index do |error, index| %>
|
23
|
+
<%= (index.succ.to_s + ".").ljust( 3 ) %> <%= error.message %> (<%= error.class %>):
|
24
|
+
<%= error.backtrace.join( "\n" ) %>
|
25
|
+
<% end %>
|
26
|
+
|
27
|
+
END
|
28
|
+
end
|
29
|
+
|
30
|
+
it "should NOT produce the desired dedent" do
|
31
|
+
expect( subject.lines.first ).not_to match /\A\S+/
|
32
|
+
end
|
33
|
+
|
34
|
+
end
|
35
|
+
# ************************************************************************
|
36
|
+
|
37
|
+
|
38
|
+
describe_group "when the HEREDOC uses $/ instead of \\n" do
|
39
|
+
let :input do
|
40
|
+
<<-END
|
41
|
+
<%= headline %>
|
42
|
+
|
43
|
+
<% errors.each_with_index do |error, index| %>
|
44
|
+
<%= (index.succ.to_s + ".").ljust( 3 ) %> <%= error.message %> (<%= error.class %>):
|
45
|
+
<%= error.backtrace.join( $/ ) %>
|
46
|
+
<% end %>
|
47
|
+
|
48
|
+
END
|
49
|
+
end
|
50
|
+
|
51
|
+
it "should produce the desired dedent" do
|
52
|
+
expect( subject.lines.first ).to match /\A\S+/
|
53
|
+
end
|
54
|
+
|
55
|
+
end # Group "when the HEREDOC uses $/ instead of \\n" Description
|
56
|
+
|
57
|
+
end # section Newline literals in HEREDOCs
|
58
|
+
# ************************************************************************
|
59
|
+
|
60
|
+
end # describe_spec_file
|
61
|
+
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: nrser
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.30
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- nrser
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-01-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -254,6 +254,7 @@ files:
|
|
254
254
|
- spec/nrser/string/common_prefix_spec.rb
|
255
255
|
- spec/nrser/string/looks_like_spec.rb
|
256
256
|
- spec/nrser/template_spec.rb
|
257
|
+
- spec/nrser/text/dedent/gotchas_spec.rb
|
257
258
|
- spec/nrser/text/dedent_spec.rb
|
258
259
|
- spec/nrser/tree/each_branch_spec.rb
|
259
260
|
- spec/nrser/tree/leaves_spec.rb
|
@@ -335,6 +336,7 @@ test_files:
|
|
335
336
|
- spec/nrser/string/common_prefix_spec.rb
|
336
337
|
- spec/nrser/string/looks_like_spec.rb
|
337
338
|
- spec/nrser/template_spec.rb
|
339
|
+
- spec/nrser/text/dedent/gotchas_spec.rb
|
338
340
|
- spec/nrser/text/dedent_spec.rb
|
339
341
|
- spec/nrser/tree/each_branch_spec.rb
|
340
342
|
- spec/nrser/tree/leaves_spec.rb
|