nrser 0.2.2 → 0.3.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.
- checksums.yaml +4 -4
- data/lib/nrser/char/alpha_numeric_sub.rb +1 -2
- data/lib/nrser/char.rb +0 -6
- data/lib/nrser/core_ext/array.rb +120 -0
- data/lib/nrser/core_ext/binding.rb +44 -0
- data/lib/nrser/{functions → core_ext}/enumerable/find_map.rb +18 -15
- data/lib/nrser/{ext → core_ext}/enumerable.rb +10 -24
- data/lib/nrser/core_ext/exception.rb +30 -0
- data/lib/nrser/core_ext/hash/extract_values_at.rb +49 -0
- data/lib/nrser/core_ext/hash/transform_values_with_keys.rb +24 -0
- data/lib/nrser/core_ext/hash.rb +50 -0
- data/lib/nrser/core_ext/module/method_objects.rb +96 -0
- data/lib/nrser/core_ext/module/names.rb +69 -0
- data/lib/nrser/core_ext/module/source_locations.rb +214 -0
- data/lib/nrser/core_ext/module.rb +2 -0
- data/lib/nrser/core_ext/object/lazy_var.rb +31 -0
- data/lib/nrser/core_ext/object.rb +46 -0
- data/lib/nrser/core_ext/open_struct.rb +6 -0
- data/lib/nrser/{ext → core_ext}/pathname.rb +8 -5
- data/lib/nrser/{ext → core_ext}/string.rb +6 -12
- data/lib/nrser/core_ext/symbol.rb +13 -0
- data/lib/nrser/core_ext/time.rb +46 -0
- data/lib/nrser/core_ext.rb +13 -0
- data/lib/nrser/errors/abstract_method_error.rb +150 -0
- data/lib/nrser/errors/argument_error.rb +42 -0
- data/lib/nrser/errors/nicer_error.rb +298 -72
- data/lib/nrser/errors/type_error.rb +46 -0
- data/lib/nrser/errors.rb +4 -53
- data/lib/nrser/ext/tree.rb +3 -0
- data/lib/nrser/functions/enumerable/associate.rb +6 -9
- data/lib/nrser/functions/enumerable/include_slice.rb +2 -3
- data/lib/nrser/functions/enumerable.rb +1 -3
- data/lib/nrser/functions/exception.rb +1 -1
- data/lib/nrser/functions/hash.rb +0 -6
- data/lib/nrser/functions/merge_by.rb +2 -2
- data/lib/nrser/functions/module/method_objects.rb +77 -0
- data/lib/nrser/functions/module.rb +1 -2
- data/lib/nrser/functions/open_struct.rb +25 -35
- data/lib/nrser/functions/proc.rb +1 -6
- data/lib/nrser/functions/string/looks_like.rb +32 -1
- data/lib/nrser/functions/string.rb +1 -40
- data/lib/nrser/functions/text/lines.rb +2 -1
- data/lib/nrser/functions.rb +0 -1
- data/lib/nrser/graph/tsorter.rb +41 -0
- data/lib/nrser/labs/core_ext/binding.rb +37 -0
- data/lib/nrser/labs/stash.rb +372 -0
- data/lib/nrser/{logging → log}/appender/sync.rb +3 -3
- data/lib/nrser/log/appender.rb +3 -0
- data/lib/nrser/{logging → log}/formatters/color.rb +47 -20
- data/lib/nrser/log/formatters/mixin.rb +270 -0
- data/lib/nrser/{logging → log}/formatters.rb +0 -0
- data/lib/nrser/log/logger.rb +229 -0
- data/lib/nrser/log/mixin.rb +56 -0
- data/lib/nrser/log.rb +723 -0
- data/lib/nrser/message.rb +24 -3
- data/lib/nrser/meta/source/location.rb +158 -0
- data/lib/nrser/meta.rb +1 -1
- data/lib/nrser/props/class_methods.rb +118 -0
- data/lib/nrser/props/immutable/hash.rb +111 -0
- data/lib/nrser/props/immutable/hash_variable.rb +82 -0
- data/lib/nrser/props/immutable/instance_variables.rb +48 -0
- data/lib/nrser/props/immutable/vector.rb +107 -0
- data/lib/nrser/props/instance_methods.rb +184 -0
- data/lib/nrser/props/metadata.rb +359 -0
- data/lib/nrser/props/mutable/instance_variables.rb +60 -0
- data/lib/nrser/props/mutable/stash.rb +199 -0
- data/lib/nrser/{meta/props → props}/prop.rb +217 -112
- data/lib/nrser/props/storage/instance_variable.rb +85 -0
- data/lib/nrser/props/storage/instance_variables.rb +67 -0
- data/lib/nrser/props/storage/key.rb +88 -0
- data/lib/nrser/props.rb +9 -0
- data/lib/nrser/refinements/sugar.rb +41 -0
- data/lib/nrser/refinements/types.rb +2 -2
- data/lib/nrser/refinements.rb +14 -16
- data/lib/nrser/rspex/example_group/describe_attribute.rb +24 -0
- data/lib/nrser/rspex/example_group/describe_called_with.rb +1 -6
- data/lib/nrser/rspex/example_group/{describe_use_case.rb → describe_case.rb} +6 -3
- data/lib/nrser/rspex/example_group/describe_class.rb +1 -0
- data/lib/nrser/rspex/example_group/describe_group.rb +29 -0
- data/lib/nrser/rspex/example_group/describe_instance_method.rb +2 -2
- data/lib/nrser/rspex/example_group/describe_message.rb +35 -0
- data/lib/nrser/rspex/example_group/describe_method.rb +23 -2
- data/lib/nrser/rspex/example_group/describe_module.rb +19 -0
- data/lib/nrser/rspex/example_group/describe_response_to.rb +32 -0
- data/lib/nrser/rspex/example_group/describe_section.rb +38 -0
- data/lib/nrser/rspex/example_group/describe_sent_to.rb +52 -0
- data/lib/nrser/rspex/example_group/describe_source_file.rb +49 -0
- data/lib/nrser/rspex/example_group/describe_spec_file.rb +41 -108
- data/lib/nrser/rspex/example_group/describe_when.rb +14 -7
- data/lib/nrser/rspex/example_group/describe_x.rb +39 -12
- data/lib/nrser/rspex/example_group/overrides.rb +66 -0
- data/lib/nrser/rspex/example_group.rb +20 -252
- data/lib/nrser/rspex/format.rb +83 -17
- data/lib/nrser/rspex.rb +4 -34
- data/lib/nrser/sugar/method_missing_forwarder.rb +50 -0
- data/lib/nrser/{env → sys/env}/path.rb +1 -2
- data/lib/nrser/{env.rb → sys/env.rb} +2 -1
- data/lib/nrser/sys.rb +5 -0
- data/lib/nrser/types/any.rb +36 -7
- data/lib/nrser/types/{array.rb → arrays.rb} +32 -81
- data/lib/nrser/types/attrs.rb +68 -15
- data/lib/nrser/types/booleans.rb +95 -34
- data/lib/nrser/types/bounded.rb +12 -10
- data/lib/nrser/types/combinators.rb +74 -37
- data/lib/nrser/types/errors/check_error.rb +86 -0
- data/lib/nrser/types/errors/from_string_error.rb +82 -0
- data/lib/nrser/types/factory.rb +91 -0
- data/lib/nrser/types/hashes.rb +171 -26
- data/lib/nrser/types/in.rb +25 -12
- data/lib/nrser/types/is.rb +50 -18
- data/lib/nrser/types/is_a.rb +52 -33
- data/lib/nrser/types/labels.rb +6 -33
- data/lib/nrser/types/maybe.rb +12 -4
- data/lib/nrser/types/nil.rb +24 -4
- data/lib/nrser/types/not.rb +6 -16
- data/lib/nrser/types/numbers.rb +94 -57
- data/lib/nrser/types/pairs.rb +57 -57
- data/lib/nrser/types/paths.rb +112 -133
- data/lib/nrser/types/responds.rb +64 -74
- data/lib/nrser/types/shape.rb +29 -24
- data/lib/nrser/types/strings.rb +25 -17
- data/lib/nrser/types/symbols.rb +19 -17
- data/lib/nrser/types/trees.rb +18 -70
- data/lib/nrser/types/tuples.rb +36 -40
- data/lib/nrser/types/type.rb +342 -91
- data/lib/nrser/types/when.rb +40 -18
- data/lib/nrser/types/where.rb +94 -9
- data/lib/nrser/types.rb +72 -63
- data/lib/nrser/version.rb +1 -1
- data/lib/nrser.rb +18 -18
- data/spec/lib/nrser/{functions/binding/template_spec.rb → core_ext/binding/erb_spec.rb} +5 -5
- data/spec/lib/nrser/{functions → core_ext}/enumerable/find_map_spec.rb +8 -6
- data/spec/lib/nrser/{refinements → core_ext}/hash_spec.rb +9 -22
- data/spec/lib/nrser/errors/abstract_method_error_spec.rb +12 -5
- data/spec/lib/nrser/functions/enumerable/{to_h_by_spec.rb → associate_spec.rb} +1 -1
- data/spec/lib/nrser/functions/merge_by_spec.rb +1 -1
- data/spec/lib/nrser/functions/tree/each_branch_spec.rb +3 -3
- data/spec/lib/nrser/functions/tree/transform_spec.rb +14 -15
- data/spec/lib/nrser/gem_ext/hamster/json_spec.rb +4 -0
- data/spec/lib/nrser/meta/source/location_spec.rb +86 -0
- data/spec/lib/nrser/props/immutable/hash_spec.rb +297 -0
- data/spec/lib/nrser/props/immutable/vector_spec.rb +296 -0
- data/spec/lib/nrser/{meta/props_spec.rb → props/original_props_spec.rb} +11 -16
- data/spec/lib/nrser/{meta/props → props}/to_and_from_data_spec.rb +10 -8
- data/spec/lib/nrser/refinements/array_spec.rb +2 -15
- data/spec/lib/nrser/refinements/erb_spec.rb +5 -7
- data/spec/lib/nrser/refinements/set_spec.rb +2 -15
- data/spec/lib/nrser/{env → sys/env}/path/insert_spec.rb +4 -2
- data/spec/lib/nrser/{env → sys/env}/path_spec.rb +4 -2
- data/spec/lib/nrser/types/array_spec.rb +8 -8
- data/spec/lib/nrser/types/paths_spec.rb +15 -18
- data/spec/spec_helper.rb +4 -0
- metadata +109 -69
- data/lib/nrser/ext/binding.rb +0 -36
- data/lib/nrser/ext/module.rb +0 -62
- data/lib/nrser/ext.rb +0 -8
- data/lib/nrser/functions/binding.rb +0 -76
- data/lib/nrser/functions/enumerable/map_keys.rb +0 -0
- data/lib/nrser/functions/enumerable/map_values.rb +0 -94
- data/lib/nrser/functions/hash/deep_merge.rb +0 -57
- data/lib/nrser/functions/hash/except_keys.rb +0 -44
- data/lib/nrser/functions/hash/slice_keys.rb +0 -43
- data/lib/nrser/functions/hash/stringify_keys.rb +0 -55
- data/lib/nrser/functions/hash/symbolize_keys.rb +0 -57
- data/lib/nrser/functions/hash/transform_keys.rb +0 -140
- data/lib/nrser/functions/module/methods.rb +0 -206
- data/lib/nrser/functions/module/source_locations.rb +0 -213
- data/lib/nrser/logging/appender.rb +0 -3
- data/lib/nrser/logging.rb +0 -353
- data/lib/nrser/meta/props/base.rb +0 -31
- data/lib/nrser/meta/props.rb +0 -357
- data/lib/nrser/refinements/array.rb +0 -133
- data/lib/nrser/refinements/binding.rb +0 -6
- data/lib/nrser/refinements/enumerator.rb +0 -5
- data/lib/nrser/refinements/exception.rb +0 -35
- data/lib/nrser/refinements/hash.rb +0 -150
- data/lib/nrser/refinements/module.rb +0 -5
- data/lib/nrser/refinements/object.rb +0 -42
- data/lib/nrser/refinements/open_struct.rb +0 -28
- data/lib/nrser/refinements/pathname.rb +0 -5
- data/lib/nrser/refinements/set.rb +0 -5
- data/lib/nrser/refinements/string.rb +0 -5
- data/lib/nrser/refinements/symbol.rb +0 -20
- data/lib/nrser/rspex/described.rb +0 -99
- data/spec/design/mapping_spec.rb +0 -42
- data/spec/lib/nrser/functions/hash_spec.rb +0 -41
- data/spec/lib/nrser/functions/string/truncate_spec.rb +0 -11
- data/spec/lib/nrser/refinements/truncate_spec.rb +0 -10
@@ -1,110 +1,336 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
4
|
+
|
3
5
|
# Requirements
|
4
|
-
#
|
6
|
+
# ========================================================================
|
5
7
|
|
6
8
|
# Stdlib
|
7
|
-
#
|
9
|
+
# ------------------------------------------------------------------------
|
8
10
|
|
9
|
-
#
|
10
|
-
|
11
|
+
# Using {PP.pp} as default dumper.
|
12
|
+
require 'pp'
|
11
13
|
|
12
|
-
|
13
|
-
# -----------------------------------------------------------------------
|
14
|
+
require 'nrser/core_ext/object/lazy_var'
|
14
15
|
|
15
16
|
|
16
17
|
# Definitions
|
17
18
|
# =======================================================================
|
18
19
|
|
19
|
-
# A mixin for {Exception} and utilities to make
|
20
|
+
# A mixin for {Exception} and utilities to make life better... even when things
|
21
|
+
# go wrong.
|
22
|
+
#
|
23
|
+
# "Nicer" errors do a few things:
|
24
|
+
#
|
25
|
+
# 1. **`message` is a splat/`Array`**
|
26
|
+
#
|
27
|
+
# Accept an {Array} `message` instead of just a string, dumping non-string
|
28
|
+
# values and joining everything together.
|
29
|
+
#
|
30
|
+
# This lets you deal with printing/dumping all in one place instead of
|
31
|
+
# ad-hoc'ing `#to_s`, `#inspect`, `#pretty_inspect`, etc. all over the
|
32
|
+
# place (though you can still dump values yourself of course since string
|
33
|
+
# pass right through).
|
34
|
+
#
|
35
|
+
# Write things like:
|
36
|
+
#
|
37
|
+
# MyError.new "The value", value, "sucks, it should be", expected
|
38
|
+
#
|
39
|
+
# This should cut down the amount of typing when raising as well, which
|
40
|
+
# is always welcome.
|
41
|
+
#
|
42
|
+
# It also allows for a future where we get smarter about dumping things,
|
43
|
+
# offer configuration options, switch on environments (slow, rich dev
|
44
|
+
# versus fast, concise prod), etc.
|
45
|
+
#
|
46
|
+
# 2. **"Extended" Messages**
|
47
|
+
#
|
48
|
+
# The normal message that we talked about in (1) - that we call the
|
49
|
+
# *summary message* or *super-message* (since it gets passed up to the
|
50
|
+
# built-in Exception's `#initialize`) - is intended to be:
|
51
|
+
#
|
52
|
+
# 1. Very concise
|
53
|
+
# - A single line well under 80 characters if possible.
|
54
|
+
#
|
55
|
+
# - This just seems like how Ruby exception messages were meant to
|
56
|
+
# be, I guess, and in many situations it's all you would want or
|
57
|
+
# need (production, when it just gets rescued anyways,
|
58
|
+
# there's no one there to read it, etc.).
|
59
|
+
#
|
60
|
+
# 2. Cheap to render.
|
61
|
+
# - We may be trying to do lot very quickly on a production system.
|
62
|
+
#
|
63
|
+
# However - especially when developing - it can be really nice to add
|
64
|
+
# considerably more detail and feedback to errors.
|
65
|
+
#
|
66
|
+
# To support this important use case as well, `NicerError` introduces the
|
67
|
+
# idea of an *extended message* that does not need to be rendered and
|
68
|
+
# output along with the *summary/super-message*.
|
69
|
+
#
|
70
|
+
# It's rendering is done on-demand, so systems that are not configured to
|
71
|
+
# use it will pay a minimal cost for it's existence.
|
72
|
+
#
|
73
|
+
# > See {#extended_message}.
|
74
|
+
#
|
75
|
+
# The extended message is composed of:
|
76
|
+
#
|
77
|
+
# 1. Text *details*, optionally rendered via {Binding.erb} when a
|
78
|
+
# binding is provided.
|
79
|
+
#
|
80
|
+
# 2. A *context* of name and value pairs to dump.
|
81
|
+
#
|
82
|
+
# Both are provided as optional keyword parameters to {#initialize}.
|
20
83
|
#
|
21
84
|
module NRSER::NicerError
|
22
85
|
|
86
|
+
# Constants
|
87
|
+
# ========================================================================
|
88
|
+
|
89
|
+
# Default column width
|
90
|
+
DEFAULT_COLUMN_WIDTH = 78
|
91
|
+
|
23
92
|
|
24
|
-
#
|
93
|
+
# Module Methods
|
94
|
+
# ==========================================================================
|
95
|
+
|
96
|
+
# Column width to format for (just summary/super-message at the moment).
|
97
|
+
#
|
98
|
+
# @todo
|
99
|
+
# Implement terminal width detection like Thor?
|
100
|
+
#
|
101
|
+
# @return [Fixnum]
|
102
|
+
# Positive integer.
|
25
103
|
#
|
26
|
-
|
27
|
-
|
28
|
-
|
104
|
+
def self.column_width
|
105
|
+
DEFAULT_COLUMN_WIDTH
|
106
|
+
end
|
29
107
|
|
30
108
|
|
31
|
-
#
|
109
|
+
# Construct a nicer error.
|
32
110
|
#
|
33
|
-
# @param [
|
34
|
-
#
|
111
|
+
# @param [Array] *message
|
112
|
+
# Main message segments.
|
35
113
|
#
|
36
|
-
# @
|
37
|
-
#
|
114
|
+
# @param [Binding?] binding:
|
115
|
+
# When provided any details string will be rendered using it's
|
116
|
+
# {Binding#erb} method.
|
38
117
|
#
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
118
|
+
# @param [nil | String | Proc<()=>String> | #to_s] details:
|
119
|
+
# Additional text details to add to the extended message. When:
|
120
|
+
#
|
121
|
+
# 1. `nil` - no details will be added.
|
122
|
+
#
|
123
|
+
# 2. `String` - the value will be used. If `binding:` is provided, it
|
124
|
+
# will be rendered against it as ERB.
|
125
|
+
#
|
126
|
+
# 3. `Proc<()=>String>` - if and when an extended message is needed
|
127
|
+
# the proc will be called, and the resulting string will be used
|
128
|
+
# as in (2).
|
129
|
+
#
|
130
|
+
# 4. `#to_s` - catch all; if and when an extended message is needed
|
131
|
+
# `#to_s` will be called on the value and the result will be used
|
132
|
+
# as in (2).
|
133
|
+
#
|
134
|
+
# @param [Hash<Symbol, VALUE>] **context
|
135
|
+
# Any additional names and values to dump with an extended message.
|
136
|
+
#
|
137
|
+
def initialize *message,
|
138
|
+
binding: nil,
|
139
|
+
details: nil,
|
140
|
+
**context
|
141
|
+
@binding = binding
|
142
|
+
@context = context
|
143
|
+
@details = details
|
48
144
|
|
49
|
-
if
|
50
|
-
|
51
|
-
short_message = message_lines.first.chomp
|
52
|
-
extended_message_lines = message_lines.rest
|
53
|
-
else
|
54
|
-
short_message = message
|
55
|
-
extended_message_lines = nil
|
56
|
-
end
|
145
|
+
message = default_message if message.empty?
|
146
|
+
super_message = format_message *message
|
57
147
|
|
58
|
-
|
59
|
-
|
148
|
+
super super_message
|
149
|
+
end # #initialize
|
150
|
+
|
151
|
+
|
152
|
+
# Format a segment of the error message.
|
153
|
+
#
|
154
|
+
# Strings are simply returned. Other things are inspected (for now).
|
155
|
+
#
|
156
|
+
# @param [Object] segment
|
157
|
+
# The segment.
|
158
|
+
#
|
159
|
+
# @return [String]
|
160
|
+
# The formatted string for the segment.
|
161
|
+
#
|
162
|
+
def format_message_segment segment
|
163
|
+
return segment if String === segment
|
60
164
|
|
61
|
-
#
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
165
|
+
# TODO Do better!
|
166
|
+
segment.inspect
|
167
|
+
end # #format_message_segment
|
168
|
+
|
169
|
+
|
170
|
+
# Format the main message by converting args to strings and joining them.
|
171
|
+
#
|
172
|
+
# @param [Array] *message
|
173
|
+
# Message segments.
|
174
|
+
#
|
175
|
+
# @return [String]
|
176
|
+
# Formatted and joined message ready to pass up to the built-in
|
177
|
+
# exception's `#initialize`.
|
178
|
+
#
|
179
|
+
def format_message *message
|
180
|
+
message.map( &method( :format_message_segment ) ).join( ' ' )
|
181
|
+
end
|
182
|
+
|
183
|
+
|
184
|
+
# Main message to use when none provided to {#initialize}.
|
185
|
+
#
|
186
|
+
# @return [String]
|
187
|
+
#
|
188
|
+
def default_message
|
189
|
+
"(no message)"
|
190
|
+
end
|
191
|
+
|
192
|
+
|
193
|
+
# Any additional context values to add to extended messages provided to
|
194
|
+
# {#initialize}.
|
195
|
+
#
|
196
|
+
# @return [Hash<Symbol, *>]
|
197
|
+
#
|
198
|
+
def context
|
199
|
+
@context
|
200
|
+
end
|
201
|
+
|
202
|
+
|
203
|
+
def details
|
204
|
+
@details
|
205
|
+
end
|
206
|
+
|
207
|
+
|
208
|
+
# Render details (first time only, then cached) and return the string.
|
209
|
+
#
|
210
|
+
# @return [String?]
|
211
|
+
#
|
212
|
+
def details_section
|
213
|
+
lazy_var :@details_section do
|
214
|
+
# No details if we have nothing to work with
|
215
|
+
if details.nil?
|
216
|
+
nil
|
66
217
|
else
|
67
|
-
|
218
|
+
contents = case details
|
219
|
+
when Proc
|
220
|
+
details.call
|
221
|
+
when String
|
222
|
+
details
|
223
|
+
else
|
224
|
+
details.to_s
|
225
|
+
end
|
226
|
+
|
227
|
+
if contents.empty?
|
228
|
+
nil
|
229
|
+
else
|
230
|
+
if @binding
|
231
|
+
contents = binding.erb contents
|
232
|
+
end
|
233
|
+
|
234
|
+
"# Details\n\n" + contents
|
235
|
+
end
|
68
236
|
end
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
237
|
+
end
|
238
|
+
end
|
239
|
+
|
240
|
+
|
241
|
+
# @return [String?]
|
242
|
+
#
|
243
|
+
def context_section
|
244
|
+
lazy_var :@context_section do
|
245
|
+
if context.empty?
|
246
|
+
nil
|
79
247
|
else
|
80
|
-
|
248
|
+
"# Context:\n\n" + context.map { |name, value|
|
249
|
+
name_str = name.to_s
|
250
|
+
value_str = PP.pp \
|
251
|
+
value,
|
252
|
+
''.dup,
|
253
|
+
(NRSER::NicerError.column_width - name_str.length - 2)
|
254
|
+
|
255
|
+
if value_str.lines.count > 1
|
256
|
+
"#{ name_str }:\n\n#{ value_str.indent 4 }\n"
|
257
|
+
else
|
258
|
+
"#{ name_str }: #{ value_str }\n"
|
259
|
+
end
|
260
|
+
}.join
|
81
261
|
end
|
82
262
|
end
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
263
|
+
end
|
264
|
+
|
265
|
+
|
266
|
+
# Return the extended message, rendering if necessary (cached after first
|
267
|
+
# call).
|
268
|
+
#
|
269
|
+
# @return [String]
|
270
|
+
# Will be empty if there is no extended message.
|
271
|
+
#
|
272
|
+
def extended_message
|
273
|
+
@extended_message ||= begin
|
274
|
+
sections = []
|
275
|
+
|
276
|
+
sections << details_section unless details_section.nil?
|
277
|
+
sections << context_section unless context_section.nil?
|
91
278
|
|
92
|
-
|
279
|
+
joined = sections.join "\n\n"
|
280
|
+
end
|
281
|
+
end
|
93
282
|
|
94
283
|
|
95
|
-
#
|
284
|
+
# Should we add the extended message to {#to_s} output?
|
96
285
|
#
|
97
|
-
# @
|
98
|
-
#
|
286
|
+
# @todo
|
287
|
+
# Just returns `true` for now... should be configurable in the future.
|
99
288
|
#
|
100
|
-
# @return [
|
101
|
-
# @todo Document return value.
|
289
|
+
# @return [Boolean]
|
102
290
|
#
|
103
|
-
def
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
291
|
+
def add_extended_message?
|
292
|
+
true
|
293
|
+
end
|
294
|
+
|
295
|
+
|
296
|
+
# Get the message or the extended message.
|
297
|
+
#
|
298
|
+
# @note
|
299
|
+
# This is a bit weird, having to do with what I can tell about the
|
300
|
+
# built-in errors and how they handle their message - they have *no*
|
301
|
+
# instance variables, and seem to rely on `#to_s` to get the message
|
302
|
+
# out of C-land, however that works.
|
303
|
+
#
|
304
|
+
# {Exception#message} just forwards here, so I overrode that with
|
305
|
+
# {#message} to just get the *summary/super-message* from this method.
|
306
|
+
#
|
307
|
+
# @param [Boolean?] extended:
|
308
|
+
# Flag to explicitly control summary/super or extended message:
|
309
|
+
#
|
310
|
+
# 1. `nil` - call {#add_extended_message?} to decide (default).
|
311
|
+
# 2. `false` - return just the *summary/super-message*.
|
312
|
+
# 3. `true` - always add the *extended message* (unless it's empty).
|
313
|
+
#
|
314
|
+
# @return [String]
|
315
|
+
#
|
316
|
+
def to_s extended: nil
|
317
|
+
# The way to get the superclass' message
|
318
|
+
message = super()
|
319
|
+
|
320
|
+
# If `extended` is explicitly `false` then just return that
|
321
|
+
return message if extended == false
|
322
|
+
|
323
|
+
# Otherwise, see if the extended message was explicitly requested,
|
324
|
+
# of if we're configured to provide it as well.
|
325
|
+
#
|
326
|
+
# Either way, don't add it it's empty.
|
327
|
+
#
|
328
|
+
if (extended || add_extended_message?) &&
|
329
|
+
!extended_message.empty?
|
330
|
+
message + "\n\n" + extended_message
|
331
|
+
else
|
332
|
+
message
|
333
|
+
end
|
334
|
+
end
|
109
335
|
|
110
336
|
end # module NRSER::NicerError
|
@@ -0,0 +1,46 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Requirements
|
5
|
+
# =======================================================================
|
6
|
+
|
7
|
+
# Stdlib
|
8
|
+
# -----------------------------------------------------------------------
|
9
|
+
|
10
|
+
# Deps
|
11
|
+
# -----------------------------------------------------------------------
|
12
|
+
|
13
|
+
# Project / Package
|
14
|
+
# -----------------------------------------------------------------------
|
15
|
+
|
16
|
+
require_relative './nicer_error'
|
17
|
+
|
18
|
+
|
19
|
+
# Declarations
|
20
|
+
# =======================================================================
|
21
|
+
|
22
|
+
|
23
|
+
# Definitions
|
24
|
+
# =======================================================================
|
25
|
+
|
26
|
+
|
27
|
+
# Extension of {::ArgumentError} that includes {NRSER::NicerError} and
|
28
|
+
# supports optional
|
29
|
+
#
|
30
|
+
class NRSER::TypeError < ::TypeError
|
31
|
+
|
32
|
+
include NRSER::NicerError
|
33
|
+
|
34
|
+
|
35
|
+
# Instance Methods
|
36
|
+
# ========================================================================
|
37
|
+
|
38
|
+
# def expected
|
39
|
+
# context[:expected]
|
40
|
+
# end
|
41
|
+
|
42
|
+
# def default_message
|
43
|
+
# ["Expected", name, ""]
|
44
|
+
# end
|
45
|
+
|
46
|
+
end # class NRSER::ArgumentError
|
data/lib/nrser/errors.rb
CHANGED
@@ -13,6 +13,9 @@
|
|
13
13
|
require_relative './errors/value_error'
|
14
14
|
require_relative './errors/attr_error'
|
15
15
|
require_relative './errors/count_error'
|
16
|
+
require_relative './errors/argument_error'
|
17
|
+
require_relative './errors/type_error'
|
18
|
+
require_relative './errors/abstract_method_error'
|
16
19
|
|
17
20
|
|
18
21
|
module NRSER
|
@@ -22,58 +25,6 @@ module NRSER
|
|
22
25
|
class ConflictError < StandardError; end
|
23
26
|
|
24
27
|
|
25
|
-
# Extension of Ruby's {NotImplementedError} to provide a useful message
|
26
|
-
# and convenient constructor for abstract methods.
|
27
|
-
#
|
28
|
-
# @example
|
29
|
-
#
|
30
|
-
# def f
|
31
|
-
# raise NRSER::AbstractMethodError.new( self, __method__ )
|
32
|
-
#
|
33
|
-
#
|
34
|
-
class AbstractMethodError < NotImplementedError
|
35
|
-
|
36
|
-
# Construct a new `AbstractMethodError`.
|
37
|
-
#
|
38
|
-
# @param [Object] instance
|
39
|
-
# Instance that invoked the abstract method.
|
40
|
-
#
|
41
|
-
# @param [Symbol | String] method_name
|
42
|
-
# Name of abstract method.
|
43
|
-
#
|
44
|
-
def initialize instance, method_name
|
45
|
-
@instance = instance
|
46
|
-
@method_name = method_name
|
47
|
-
@method = instance.method @method_name
|
48
|
-
|
49
|
-
message = if @method.owner == instance.class
|
50
|
-
NRSER.dedent <<-END
|
51
|
-
Method #{ @method.owner.name }##{ @method_name } is abstract, meaning
|
52
|
-
#{ @method.owner.name } is an abstract class and the invoking
|
53
|
-
instance #{ @instance } should NOT have been constructed.
|
54
|
-
END
|
55
|
-
else
|
56
|
-
NRSER.squish <<-END
|
57
|
-
Method #{ @method.owner.name }##{ @method_name } is abstract and
|
58
|
-
has not been implemented in invoking class #{ @instance.class }.
|
59
|
-
|
60
|
-
If you *are* developing the invoking class #{ @instance.class } it
|
61
|
-
(or a parent class between it and #{ @method.owner.name }) must
|
62
|
-
implement ##{ @method_name }.
|
63
|
-
|
64
|
-
If you *are not* developing #{ @instance.class } it should be treated
|
65
|
-
as an abstract base class and should NOT be constructed. You need to
|
66
|
-
find a subclass of #{ @instance.class } to instantiate or write
|
67
|
-
your own.
|
68
|
-
END
|
69
|
-
end
|
70
|
-
|
71
|
-
super message
|
72
|
-
end # #initialize
|
73
|
-
|
74
|
-
end # class AbstractMethodError
|
75
|
-
|
76
|
-
|
77
28
|
# A wrapper error around a list of other errors.
|
78
29
|
#
|
79
30
|
class MultipleErrors < StandardError
|
@@ -103,7 +54,7 @@ module NRSER
|
|
103
54
|
headline = "#{ errors.count } error(s) occurred - #{ class_counts }"
|
104
55
|
end
|
105
56
|
|
106
|
-
message =
|
57
|
+
message = binding.erb <<-END
|
107
58
|
<%= headline %>
|
108
59
|
|
109
60
|
<% errors.each_with_index do |error, index| %>
|
data/lib/nrser/ext/tree.rb
CHANGED
@@ -11,11 +11,11 @@ module NRSER
|
|
11
11
|
# get it's key, raising an error if multiple entries map to the same key.
|
12
12
|
#
|
13
13
|
# @example Basic usage
|
14
|
-
# ['a', :b].
|
14
|
+
# ['a', :b].assoc_by &:class
|
15
15
|
# # => {String=>"a", Symbol=>:b}
|
16
16
|
#
|
17
17
|
# @example Conflict error
|
18
|
-
# [:a, :b].
|
18
|
+
# [:a, :b].assoc_by &:class
|
19
19
|
# # NRSER::ConflictError: Key Symbol is already in results with value:
|
20
20
|
# #
|
21
21
|
# # :a
|
@@ -37,7 +37,7 @@ module NRSER
|
|
37
37
|
key = block.call element
|
38
38
|
|
39
39
|
if result.key? key
|
40
|
-
raise NRSER::ConflictError.new erb
|
40
|
+
raise NRSER::ConflictError.new binding.erb <<-END
|
41
41
|
Key <%= key.inspect %> is already in results with value:
|
42
42
|
|
43
43
|
<%= result[key].pretty_inspect %>
|
@@ -47,10 +47,7 @@ module NRSER
|
|
47
47
|
|
48
48
|
result[key] = element
|
49
49
|
}
|
50
|
-
end # .
|
51
|
-
|
52
|
-
singleton_class.send :alias_method, :to_h_by, :assoc_by
|
53
|
-
|
50
|
+
end # .assoc_by
|
54
51
|
|
55
52
|
|
56
53
|
# Create a {Hash} mapping the entries in `enum` to the value returned by
|
@@ -68,7 +65,7 @@ module NRSER
|
|
68
65
|
value = if hash.key? entry
|
69
66
|
case on_conflict
|
70
67
|
when :raise
|
71
|
-
raise NRSER::ConflictError.new erb
|
68
|
+
raise NRSER::ConflictError.new binding.erb <<-END
|
72
69
|
Entry <%= entry %> appears more than once in `enum`
|
73
70
|
|
74
71
|
This would cause conflict in the resulting {Hash}.
|
@@ -97,7 +94,7 @@ module NRSER
|
|
97
94
|
|
98
95
|
hash[entry] = value
|
99
96
|
}
|
100
|
-
end # .
|
97
|
+
end # .assoc_to
|
101
98
|
|
102
99
|
|
103
100
|
end # module NRSER
|
@@ -1,6 +1,5 @@
|
|
1
1
|
require_relative './include_slice/array_include_slice'
|
2
2
|
|
3
|
-
using NRSER
|
4
3
|
|
5
4
|
module NRSER
|
6
5
|
|
@@ -54,11 +53,11 @@ module NRSER
|
|
54
53
|
raise TypeError.new binding.erb <<-END
|
55
54
|
Both `enum` and `slice` must be {Enumerable}
|
56
55
|
|
57
|
-
enum (<%= enum.class.
|
56
|
+
enum (<%= enum.class.safe_name %>):
|
58
57
|
|
59
58
|
<%= enum.pretty_inspect %>
|
60
59
|
|
61
|
-
slice (<%= slice.class.
|
60
|
+
slice (<%= slice.class.safe_name %>):
|
62
61
|
|
63
62
|
<%= slice.pretty_inspect %>
|
64
63
|
|
@@ -1,8 +1,6 @@
|
|
1
|
-
require_relative './enumerable/find_map'
|
2
1
|
require_relative './enumerable/find_all_map'
|
3
2
|
require_relative './enumerable/include_slice'
|
4
3
|
require_relative './enumerable/associate'
|
5
|
-
require_relative './enumerable/map_values'
|
6
4
|
|
7
5
|
module NRSER
|
8
6
|
|
@@ -64,7 +62,7 @@ module NRSER
|
|
64
62
|
NRSER::Types.
|
65
63
|
length(bounds).
|
66
64
|
check(enum.find_all &block) { |type:, value:|
|
67
|
-
erb
|
65
|
+
binding.erb <<-END
|
68
66
|
|
69
67
|
Length of found elements (<%= value.length %>) FAILED to
|
70
68
|
satisfy <%= type.to_s %>.
|
data/lib/nrser/functions/hash.rb
CHANGED
@@ -3,11 +3,5 @@
|
|
3
3
|
|
4
4
|
# Project / Package
|
5
5
|
# -----------------------------------------------------------------------
|
6
|
-
require_relative './hash/except_keys'
|
7
|
-
require_relative './hash/transform_keys'
|
8
|
-
require_relative './hash/symbolize_keys'
|
9
|
-
require_relative './hash/stringify_keys'
|
10
|
-
require_relative './hash/slice_keys'
|
11
6
|
require_relative './hash/guess_label_key_type'
|
12
7
|
require_relative './hash/bury'
|
13
|
-
require_relative './hash/deep_merge'
|
@@ -21,8 +21,8 @@ module NRSER
|
|
21
21
|
# Final array of merged hashes. Don't depend on order.
|
22
22
|
#
|
23
23
|
def self.merge_by current, *updates, &merge_key
|
24
|
-
updates.reduce(
|
25
|
-
deep_merge!
|
24
|
+
updates.reduce( assoc_by current, &merge_key ) { |result, update|
|
25
|
+
result.deep_merge! assoc_by( update, &merge_key )
|
26
26
|
}.values
|
27
27
|
end # .merge_by
|
28
28
|
|