nrser 0.2.0.pre.3 → 0.2.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/ext/enumerable.rb +12 -3
- data/lib/nrser/ext/module.rb +62 -0
- data/lib/nrser/ext.rb +1 -0
- data/lib/nrser/functions/binding.rb +33 -0
- data/lib/nrser/functions/enumerable/associate.rb +103 -0
- data/lib/nrser/functions/enumerable/map_keys.rb +0 -0
- data/lib/nrser/functions/enumerable/map_values.rb +94 -0
- data/lib/nrser/functions/enumerable.rb +2 -87
- data/lib/nrser/functions/module/methods.rb +206 -0
- data/lib/nrser/functions/module/source_locations.rb +213 -0
- data/lib/nrser/functions/module.rb +2 -0
- data/lib/nrser/functions.rb +1 -0
- data/lib/nrser/logging/appender/sync.rb +148 -0
- data/lib/nrser/logging/appender.rb +3 -0
- data/lib/nrser/logging/formatters/color.rb +165 -0
- data/lib/nrser/logging/formatters.rb +1 -0
- data/lib/nrser/logging.rb +353 -0
- data/lib/nrser/refinements/module.rb +5 -0
- data/lib/nrser/refinements.rb +1 -0
- data/lib/nrser/rspex/described.rb +99 -0
- data/lib/nrser/rspex/example_group/describe_called_with.rb +2 -2
- data/lib/nrser/rspex/example_group/describe_class.rb +31 -0
- data/lib/nrser/rspex/example_group/describe_instance.rb +1 -1
- data/lib/nrser/rspex/example_group/describe_method.rb +40 -0
- data/lib/nrser/rspex/example_group.rb +2 -34
- data/lib/nrser/rspex/format.rb +19 -6
- data/lib/nrser/rspex.rb +1 -1
- data/lib/nrser/types/numbers.rb +16 -16
- data/lib/nrser/version.rb +1 -1
- data/lib/nrser.rb +2 -5
- data/spec/design/mapping_spec.rb +42 -0
- data/spec/lib/nrser/mean_streak/identity_instance_spec.rb +7 -5
- data/spec/spec_helper.rb +23 -105
- data/spec/support/shared/types.rb +92 -0
- data/spec/support/shared.rb +1 -0
- metadata +27 -24
- data/lib/nrser/labs/unicode_math.rb +0 -48
- data/lib/nrser/labs/where.rb +0 -50
- data/lib/nrser/logger.rb +0 -457
- data/spec/lib/nrser/logger/dest_spec.rb +0 -15
- data/spec/lib/nrser/logger/die_spec.rb +0 -41
- data/spec/lib/nrser/logger/install_spec.rb +0 -98
- data/spec/lib/nrser/logger/level_int_spec.rb +0 -22
- data/spec/lib/nrser/logger/level_name_spec.rb +0 -23
- data/spec/lib/nrser/logger/level_sym_spec.rb +0 -22
- data/spec/lib/nrser/logger/send_log_spec.rb +0 -63
- data/spec/lib/nrser/logger/use_spec.rb +0 -16
@@ -0,0 +1,353 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
# Requirements
|
5
|
+
# =======================================================================
|
6
|
+
|
7
|
+
# Stdlib
|
8
|
+
# -----------------------------------------------------------------------
|
9
|
+
|
10
|
+
# Deps
|
11
|
+
# -----------------------------------------------------------------------
|
12
|
+
require 'semantic_logger'
|
13
|
+
|
14
|
+
# Project / Package
|
15
|
+
# -----------------------------------------------------------------------
|
16
|
+
require_relative './logging/formatters'
|
17
|
+
require_relative './logging/appender'
|
18
|
+
|
19
|
+
|
20
|
+
# Definitions
|
21
|
+
# =======================================================================
|
22
|
+
|
23
|
+
module NRSER
|
24
|
+
|
25
|
+
# Mix in {.logger} and {#logger} to NRSER for functions to use
|
26
|
+
include SemanticLogger::Loggable
|
27
|
+
|
28
|
+
# Unified logging support via {SemanticLogger}.
|
29
|
+
#
|
30
|
+
# @see https://rocketjob.github.io/semantic_logger/index.html
|
31
|
+
#
|
32
|
+
module Logging
|
33
|
+
|
34
|
+
# Constants
|
35
|
+
# ============================================================================
|
36
|
+
|
37
|
+
# Include this guy in modules and classes to add `.logger` and `#logger` methods
|
38
|
+
# that point to their own named logger.
|
39
|
+
#
|
40
|
+
# Right now, just points to {SemanticLogger::Loggable}, but may expand on that
|
41
|
+
# some time in the future, such as to add `.on`/`#on` methods like the old
|
42
|
+
# `NRSER::Logger` had, etc.
|
43
|
+
#
|
44
|
+
# @see http://www.rubydoc.info/gems/semantic_logger/SemanticLogger/Loggable
|
45
|
+
#
|
46
|
+
# @return [Module]
|
47
|
+
#
|
48
|
+
Mixin = SemanticLogger::Loggable
|
49
|
+
|
50
|
+
|
51
|
+
# Mixins
|
52
|
+
# ============================================================================
|
53
|
+
|
54
|
+
# Mix in {.logger} and {#logger}
|
55
|
+
include Mixin
|
56
|
+
|
57
|
+
extend SingleForwardable
|
58
|
+
|
59
|
+
|
60
|
+
# Delegation
|
61
|
+
# ============================================================================
|
62
|
+
|
63
|
+
def_single_delegators(
|
64
|
+
SemanticLogger,
|
65
|
+
:application,
|
66
|
+
:application=,
|
67
|
+
:[],
|
68
|
+
# NOTE These are funky due to different in SemLog's int level and Ruby
|
69
|
+
# stdlib / Rails logger int levels, so omit for now.
|
70
|
+
#
|
71
|
+
# :index_to_level,
|
72
|
+
# :level_to_index
|
73
|
+
)
|
74
|
+
|
75
|
+
|
76
|
+
# Module Attributes
|
77
|
+
# ============================================================================
|
78
|
+
|
79
|
+
@__mutex = Mutex.new
|
80
|
+
|
81
|
+
|
82
|
+
# Module (Class) Methods
|
83
|
+
# =====================================================================
|
84
|
+
|
85
|
+
# Normalize a level name or number to a symbol, raising if it's not valid.
|
86
|
+
#
|
87
|
+
# Relies on Semantic Logger's "internal" {SemanticLogger.level_to_index}
|
88
|
+
# method.
|
89
|
+
#
|
90
|
+
# @see https://github.com/rocketjob/semantic_logger/blob/97247126de32e6ecbf74cbccaa3b3732768d52c5/lib/semantic_logger/semantic_logger.rb#L454
|
91
|
+
#
|
92
|
+
# @param [Symbol | String | Integer]
|
93
|
+
# Representation of a level in one of the following formats:
|
94
|
+
#
|
95
|
+
# 1. {Symbol} - verified as member of {SemanticLogger::LEVELS} and
|
96
|
+
# returned.
|
97
|
+
#
|
98
|
+
# 2. {String} - accepts string representations of the level symbols,
|
99
|
+
# case insensitive.
|
100
|
+
#
|
101
|
+
# 3. {Integer} - interpreted as a Ruby StdLib Logger / Rails Logger
|
102
|
+
# level, which are **different** than Semantic Logger's!
|
103
|
+
#
|
104
|
+
# @return [:trace | :debug | :info | :warn | :error | :fatal]
|
105
|
+
# Log level symbol.
|
106
|
+
#
|
107
|
+
# @raise
|
108
|
+
# When `level` is invalid.
|
109
|
+
#
|
110
|
+
def self.level_sym_for level
|
111
|
+
if SemanticLogger::LEVELS.include? level
|
112
|
+
level
|
113
|
+
else
|
114
|
+
SemanticLogger.index_to_level SemanticLogger.level_to_index( level )
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
# Global / default log level, which we always normalize to a symbol.
|
120
|
+
#
|
121
|
+
# @return [:trace | :debug | :info | :warn | :error | :fatal]
|
122
|
+
#
|
123
|
+
def self.level
|
124
|
+
level_sym_for SemanticLogger.default_level
|
125
|
+
end
|
126
|
+
|
127
|
+
|
128
|
+
def self.level_index
|
129
|
+
SemanticLogger.default_level_index
|
130
|
+
end
|
131
|
+
|
132
|
+
|
133
|
+
# Set the global default log level.
|
134
|
+
#
|
135
|
+
# @param level (see .level_sym_for)
|
136
|
+
# @return (see .level_sym_for)
|
137
|
+
# @raise (see .level_sym_for)
|
138
|
+
#
|
139
|
+
def self.level= level
|
140
|
+
SemanticLogger.default_level = level_sym_for level
|
141
|
+
end
|
142
|
+
|
143
|
+
|
144
|
+
# Try to set the level, logging a warning and returning `nil` if it fails.
|
145
|
+
#
|
146
|
+
# @param level (see .level=)
|
147
|
+
#
|
148
|
+
# @return [Symbol]
|
149
|
+
# The level symbol if it was set successfully.
|
150
|
+
#
|
151
|
+
# @return [nil]
|
152
|
+
# If the set failed (also logs a warning).
|
153
|
+
#
|
154
|
+
def self.try_set_level level
|
155
|
+
begin
|
156
|
+
self.level = level
|
157
|
+
rescue Exception => error
|
158
|
+
logger.warn "Unable to set level, probably bad value",
|
159
|
+
level: level,
|
160
|
+
error: error
|
161
|
+
nil
|
162
|
+
end
|
163
|
+
end # .try_set_level
|
164
|
+
|
165
|
+
|
166
|
+
def self.level_from_ENV prefix:
|
167
|
+
if NRSER.truthy? ENV["#{ prefix }_TRACE"]
|
168
|
+
return :trace
|
169
|
+
elsif NRSER.truthy? ENV["#{ prefix }_DEBUG"]
|
170
|
+
return :debug
|
171
|
+
end
|
172
|
+
|
173
|
+
level = ENV["#{ prefix }_LOG_LEVEL"]
|
174
|
+
|
175
|
+
unless level.nil? || level == ''
|
176
|
+
return level
|
177
|
+
end
|
178
|
+
|
179
|
+
nil
|
180
|
+
end
|
181
|
+
|
182
|
+
|
183
|
+
# Setup logging.
|
184
|
+
#
|
185
|
+
# @param [type] arg_name
|
186
|
+
# @todo Add name param description.
|
187
|
+
#
|
188
|
+
# @return [nil]
|
189
|
+
#
|
190
|
+
def self.setup! level: nil,
|
191
|
+
dest: nil,
|
192
|
+
sync: false,
|
193
|
+
say_hi: :debug,
|
194
|
+
application: 'NRSER',
|
195
|
+
env_var_prefix: nil
|
196
|
+
|
197
|
+
unless @__mutex.try_lock
|
198
|
+
raise ThreadError, <<~END
|
199
|
+
Mutex is already held.
|
200
|
+
|
201
|
+
You should pretty generally NOT have multiple threads trying to
|
202
|
+
setup logging at once or re-enter {NRSER::Logging.setup}!
|
203
|
+
END
|
204
|
+
end
|
205
|
+
|
206
|
+
# Wrap around everything to make sure we release the mutex
|
207
|
+
begin
|
208
|
+
self.appender = dest unless dest.nil?
|
209
|
+
|
210
|
+
# Force synchronous logging
|
211
|
+
sync! if sync
|
212
|
+
|
213
|
+
# If we didn't receive a level, check the ENV
|
214
|
+
if level.nil?
|
215
|
+
if env_var_prefix.nil?
|
216
|
+
env_var_prefix = application.gsub( /[^a-zA-Z0-0_]+/, '_' ).upcase
|
217
|
+
end
|
218
|
+
|
219
|
+
level = level_from_ENV prefix: env_var_prefix
|
220
|
+
end
|
221
|
+
|
222
|
+
# If we ended up with a level, try to set it (will only log a warning
|
223
|
+
# if it fails, not raise, which could crash things on boot)
|
224
|
+
try_set_level level unless level.nil?
|
225
|
+
|
226
|
+
self.application = application unless application.nil?
|
227
|
+
|
228
|
+
ensure
|
229
|
+
# Make sure we release the mutex; don't need to hold it for the rest
|
230
|
+
@__mutex.unlock
|
231
|
+
end
|
232
|
+
|
233
|
+
will_say_hi = case say_hi
|
234
|
+
when true, false
|
235
|
+
say_hi
|
236
|
+
when Symbol, String, Fixnum
|
237
|
+
begin
|
238
|
+
level_index < SemanticLogger.level_to_index( say_hi )
|
239
|
+
rescue Exception => error
|
240
|
+
logger.warn "Bad `say_hi` kwd in {NRSER::Logging.setup}",
|
241
|
+
say_hi: say_hi,
|
242
|
+
expected: "Symbol, String, or Fixnum representing log level",
|
243
|
+
error: error
|
244
|
+
|
245
|
+
false
|
246
|
+
end
|
247
|
+
else
|
248
|
+
logger.warn "Bad `say_hi` kwd in {NRSER::Logging.setup}",
|
249
|
+
say_hi: say_hi,
|
250
|
+
expected: [true, false, Symbol, String, Fixnum]
|
251
|
+
|
252
|
+
false
|
253
|
+
end
|
254
|
+
|
255
|
+
if will_say_hi
|
256
|
+
logger.info "Hi! Logging is setup",
|
257
|
+
level: self.level,
|
258
|
+
dest: dest,
|
259
|
+
sync: sync
|
260
|
+
end
|
261
|
+
|
262
|
+
nil
|
263
|
+
rescue Exception => error
|
264
|
+
# Suppress errors in favor of a warning
|
265
|
+
|
266
|
+
logger.warn \
|
267
|
+
message: "Error setting up logging",
|
268
|
+
payload: {
|
269
|
+
args: {
|
270
|
+
level: level,
|
271
|
+
dest: dest,
|
272
|
+
env_var_prefix: env_var_prefix,
|
273
|
+
say_hi: say_hi,
|
274
|
+
},
|
275
|
+
},
|
276
|
+
exception: error
|
277
|
+
|
278
|
+
nil
|
279
|
+
end # .setup!
|
280
|
+
|
281
|
+
|
282
|
+
# Call {.setup!} with some default keywords that are nice for CLI apps.
|
283
|
+
#
|
284
|
+
# @param (see .setup!)
|
285
|
+
# @return (see .setup!)
|
286
|
+
#
|
287
|
+
def self.setup_for_cli! dest: $stderr,
|
288
|
+
sync: true,
|
289
|
+
**kwds
|
290
|
+
setup! dest: dest, sync: sync, **kwds
|
291
|
+
end # .setup_for_cli!
|
292
|
+
|
293
|
+
|
294
|
+
# Hack up SemanticLogger to do sync logging in the main thread
|
295
|
+
#
|
296
|
+
# @return [nil]
|
297
|
+
#
|
298
|
+
def self.sync!
|
299
|
+
# Create a {Locd::Logging::Appender::Sync}, which implements the
|
300
|
+
# {SemanticLogger::Appender::Async} interface but just forwards directly
|
301
|
+
# to it's appender in the same thread, and point it where
|
302
|
+
# {SemanticLogger::Processor.instance} (which is an Async) points.
|
303
|
+
#
|
304
|
+
sync_appender = NRSER::Logging::Appender::Sync.new \
|
305
|
+
appender: SemanticLogger::Processor.instance.appender
|
306
|
+
|
307
|
+
# Swap our sync in for the async
|
308
|
+
SemanticLogger::Processor.instance_variable_set \
|
309
|
+
:@processor,
|
310
|
+
sync_appender
|
311
|
+
|
312
|
+
nil
|
313
|
+
end
|
314
|
+
|
315
|
+
|
316
|
+
# The current "main" appender (destination), if any.
|
317
|
+
#
|
318
|
+
# This is just to simplify things in simple cases, you can always still
|
319
|
+
# add multiple appenders.
|
320
|
+
#
|
321
|
+
# @return [SemanticLogger::Subscriber | nil]
|
322
|
+
#
|
323
|
+
def self.appender
|
324
|
+
@appender
|
325
|
+
end
|
326
|
+
|
327
|
+
|
328
|
+
def self.appender= value
|
329
|
+
# Save ref to current appender (if any) so we can remove it after adding
|
330
|
+
# the new one.
|
331
|
+
old_appender = @appender
|
332
|
+
|
333
|
+
@appender = case value
|
334
|
+
when Hash
|
335
|
+
SemanticLogger.add_appender value
|
336
|
+
when String, Pathname
|
337
|
+
SemanticLogger.add_appender file_name: value.to_s
|
338
|
+
else
|
339
|
+
SemanticLogger.add_appender \
|
340
|
+
io: value,
|
341
|
+
formatter: NRSER::Logging::Formatters::Color.new
|
342
|
+
end
|
343
|
+
|
344
|
+
# Remove the old appender (if there was one). This is done after adding
|
345
|
+
# the new one so that failing won't result with no appenders.
|
346
|
+
SemanticLogger.remove_appender( old_appender ) if old_appender
|
347
|
+
|
348
|
+
@appender
|
349
|
+
end
|
350
|
+
|
351
|
+
|
352
|
+
end # module Logging
|
353
|
+
end # module NRSER
|
data/lib/nrser/refinements.rb
CHANGED
@@ -0,0 +1,99 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Requirements
|
4
|
+
# =======================================================================
|
5
|
+
|
6
|
+
# Stdlib
|
7
|
+
# -----------------------------------------------------------------------
|
8
|
+
|
9
|
+
# Deps
|
10
|
+
# -----------------------------------------------------------------------
|
11
|
+
|
12
|
+
# Project / Package
|
13
|
+
# -----------------------------------------------------------------------
|
14
|
+
|
15
|
+
|
16
|
+
# Refinements
|
17
|
+
# =======================================================================
|
18
|
+
|
19
|
+
|
20
|
+
# Declarations
|
21
|
+
# =======================================================================
|
22
|
+
|
23
|
+
|
24
|
+
# Definitions
|
25
|
+
# =======================================================================
|
26
|
+
|
27
|
+
#
|
28
|
+
class NRSER::RSpex::Described
|
29
|
+
|
30
|
+
# Constants
|
31
|
+
# ======================================================================
|
32
|
+
|
33
|
+
|
34
|
+
# Class Methods
|
35
|
+
# ======================================================================
|
36
|
+
|
37
|
+
|
38
|
+
# Attributes
|
39
|
+
# ======================================================================
|
40
|
+
|
41
|
+
|
42
|
+
# Constructor
|
43
|
+
# ======================================================================
|
44
|
+
|
45
|
+
# Instantiate a new `NRSER::RSpex::Described`.
|
46
|
+
def initialize **metadata
|
47
|
+
|
48
|
+
end # #initialize
|
49
|
+
|
50
|
+
|
51
|
+
# Instance Methods
|
52
|
+
# ======================================================================
|
53
|
+
|
54
|
+
|
55
|
+
end # class NRSER::RSpex::Described
|
56
|
+
|
57
|
+
|
58
|
+
|
59
|
+
|
60
|
+
# @todo document NRSER::RSpex::Described::Class class.
|
61
|
+
class NRSER::RSpex::Described::Class < NRSER::RSpex::Described
|
62
|
+
def initialize class:
|
63
|
+
end
|
64
|
+
|
65
|
+
|
66
|
+
def location
|
67
|
+
# Get a reasonable file and line for the class
|
68
|
+
file, line = klass.
|
69
|
+
# Get an array of all instance methods, excluding inherited ones
|
70
|
+
# (the `false` arg)
|
71
|
+
instance_methods( false ).
|
72
|
+
# Add `#initialize` since it isn't in `#instance_methods` for some
|
73
|
+
# reason
|
74
|
+
<<( :initialize ).
|
75
|
+
# Map those to their {UnboundMethod} objects
|
76
|
+
map { |sym| klass.instance_method sym }.
|
77
|
+
# Toss any `nil` values
|
78
|
+
compact.
|
79
|
+
# Get the source locations
|
80
|
+
map( &:source_location ).
|
81
|
+
# Get the first line in the shortest path
|
82
|
+
min_by { |(path, line)| [path.length, line] }
|
83
|
+
|
84
|
+
# Another approach I thought of... (untested)
|
85
|
+
#
|
86
|
+
# Get the path
|
87
|
+
# # Get frequency of the paths
|
88
|
+
# count_by { |(path, line)| path }.
|
89
|
+
# # Get the one with the most occurrences
|
90
|
+
# max_by { |path, count| count }.
|
91
|
+
# # Get just the path (not the count)
|
92
|
+
# first
|
93
|
+
end
|
94
|
+
|
95
|
+
|
96
|
+
def to_desc
|
97
|
+
|
98
|
+
end
|
99
|
+
end # class NRSER::RSpex::Described::Class
|
@@ -25,8 +25,8 @@ module NRSER::RSpex::ExampleGroup
|
|
25
25
|
# @return [void]
|
26
26
|
#
|
27
27
|
def describe_called_with *args, &body
|
28
|
-
describe_x_type
|
29
|
-
type: :
|
28
|
+
describe_x_type List(*args),
|
29
|
+
type: :called_with,
|
30
30
|
subject_block: -> { super().call *args },
|
31
31
|
&body
|
32
32
|
end # #describe_called_with
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module NRSER::RSpex::ExampleGroup
|
5
|
+
|
6
|
+
# @todo Document describe_class method.
|
7
|
+
#
|
8
|
+
# @return [void]
|
9
|
+
#
|
10
|
+
def describe_class klass,
|
11
|
+
*description,
|
12
|
+
bind_subject: true,
|
13
|
+
**metadata,
|
14
|
+
&body
|
15
|
+
subject_block = if bind_subject
|
16
|
+
-> { klass }
|
17
|
+
end
|
18
|
+
|
19
|
+
describe_x \
|
20
|
+
NRSER::RSpex::Format.md_code_quote( klass.name ),
|
21
|
+
*description,
|
22
|
+
type: :class,
|
23
|
+
metadata: {
|
24
|
+
**metadata,
|
25
|
+
class: klass,
|
26
|
+
},
|
27
|
+
subject_block: subject_block,
|
28
|
+
&body
|
29
|
+
end # #describe_class
|
30
|
+
|
31
|
+
end # module NRSER::RSpex::ExampleGroup
|
@@ -11,7 +11,7 @@ module NRSER::RSpex::ExampleGroup
|
|
11
11
|
# @todo Document return value.
|
12
12
|
#
|
13
13
|
def describe_instance *constructor_args, &body
|
14
|
-
|
14
|
+
describe_x ".new", Args(*constructor_args),
|
15
15
|
type: :instance,
|
16
16
|
metadata: {
|
17
17
|
constructor_args: constructor_args,
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module NRSER::RSpex::ExampleGroup
|
5
|
+
|
6
|
+
# @todo Document describe_method method.
|
7
|
+
#
|
8
|
+
# @return [void]
|
9
|
+
#
|
10
|
+
def describe_method method_name, *description, **metadata, &body
|
11
|
+
# Due to legacy, we only auto-bind if the name is a symbol
|
12
|
+
#
|
13
|
+
# TODO Get rid of this
|
14
|
+
#
|
15
|
+
subject_block = if method_name.is_a? Symbol
|
16
|
+
-> { super().method method_name }
|
17
|
+
end
|
18
|
+
|
19
|
+
name_prefix = if self.respond_to?( :metadata ) &&
|
20
|
+
self.metadata.key?( :constructor_args )
|
21
|
+
'#'
|
22
|
+
else
|
23
|
+
'.'
|
24
|
+
end
|
25
|
+
|
26
|
+
name_string = NRSER::RSpex::Format.md_code_quote \
|
27
|
+
"#{ name_prefix }#{ method_name }"
|
28
|
+
|
29
|
+
# Create the RSpec example group context
|
30
|
+
describe_x name_string, *description,
|
31
|
+
type: :method,
|
32
|
+
metadata: {
|
33
|
+
**metadata,
|
34
|
+
method_name: method_name,
|
35
|
+
},
|
36
|
+
subject_block: subject_block,
|
37
|
+
&body
|
38
|
+
end # #describe_method
|
39
|
+
|
40
|
+
end # module NRSER::RSpex::ExampleGroup
|
@@ -194,24 +194,6 @@ module NRSER::RSpex::ExampleGroup
|
|
194
194
|
end # #describe_module
|
195
195
|
|
196
196
|
|
197
|
-
def describe_class klass, bind_subject: true, **metadata, &block
|
198
|
-
description = "#{ NRSER::RSpex::PREFIXES[:class] } #{ klass.name }"
|
199
|
-
|
200
|
-
describe(
|
201
|
-
description,
|
202
|
-
type: :class,
|
203
|
-
class: klass,
|
204
|
-
**metadata
|
205
|
-
) do
|
206
|
-
if bind_subject
|
207
|
-
subject { klass }
|
208
|
-
end
|
209
|
-
|
210
|
-
module_exec &block
|
211
|
-
end
|
212
|
-
end # #describe_class
|
213
|
-
|
214
|
-
|
215
197
|
def describe_group title, **metadata, &block
|
216
198
|
describe(
|
217
199
|
"#{ NRSER::RSpex::PREFIXES[:group] } #{ title }",
|
@@ -223,22 +205,6 @@ module NRSER::RSpex::ExampleGroup
|
|
223
205
|
end # #describe_class
|
224
206
|
|
225
207
|
|
226
|
-
def describe_method name, **metadata, &block
|
227
|
-
describe(
|
228
|
-
"#{ NRSER::RSpex::PREFIXES[:method] } #{ name }",
|
229
|
-
type: :method,
|
230
|
-
method_name: name,
|
231
|
-
**metadata
|
232
|
-
) do
|
233
|
-
if name.is_a? Symbol
|
234
|
-
subject { super().method name }
|
235
|
-
end
|
236
|
-
|
237
|
-
module_exec &block
|
238
|
-
end
|
239
|
-
end # #describe_method
|
240
|
-
|
241
|
-
|
242
208
|
def describe_attribute symbol, **metadata, &block
|
243
209
|
describe(
|
244
210
|
"#{ NRSER::RSpex::PREFIXES[:attribute] } ##{ symbol }",
|
@@ -296,3 +262,5 @@ require_relative './example_group/describe_setup'
|
|
296
262
|
require_relative './example_group/describe_use_case'
|
297
263
|
require_relative './example_group/describe_instance'
|
298
264
|
require_relative './example_group/describe_called_with'
|
265
|
+
require_relative './example_group/describe_method'
|
266
|
+
require_relative './example_group/describe_class'
|
data/lib/nrser/rspex/format.rb
CHANGED
@@ -76,8 +76,18 @@ module NRSER::RSpex::Format
|
|
76
76
|
singleton_class.send :alias_method, :b, :bold
|
77
77
|
|
78
78
|
|
79
|
+
def self.rspec_syntax_highlighter
|
80
|
+
@rspec_syntax_highlighter ||= \
|
81
|
+
RSpec::Core::Formatters::SyntaxHighlighter.new RSpec.configuration
|
82
|
+
end
|
83
|
+
|
84
|
+
|
79
85
|
def self.code string
|
80
|
-
|
86
|
+
if string =~ /\A\#[a-zA-Z][a-zA-Z0-9_]*(?:\?|\!)?/
|
87
|
+
pastel.bold.blue string
|
88
|
+
else
|
89
|
+
rspec_syntax_highlighter.highlight string.lines
|
90
|
+
end
|
81
91
|
end
|
82
92
|
|
83
93
|
|
@@ -98,10 +108,13 @@ module NRSER::RSpex::Format
|
|
98
108
|
def self.prepend_type type, description
|
99
109
|
return description if type.nil?
|
100
110
|
|
101
|
-
prefixes = RSpec.configuration.x_type_prefixes
|
111
|
+
# prefixes = RSpec.configuration.x_type_prefixes
|
112
|
+
#
|
113
|
+
# prefix = prefixes[type] ||
|
114
|
+
# pastel.magenta( i( type.to_s.upcase.gsub('_', ' ') ) )
|
102
115
|
|
103
|
-
prefix =
|
104
|
-
|
116
|
+
# prefix = "*" + type.to_s.upcase.gsub('_', ' ') + "*"
|
117
|
+
prefix = pastel.magenta( i( type.to_s.upcase.gsub('_', ' ') ) )
|
105
118
|
|
106
119
|
"#{ prefix } #{ description }"
|
107
120
|
end # .format_type
|
@@ -127,13 +140,13 @@ module NRSER::RSpex::Format
|
|
127
140
|
elsif part.is_a? String
|
128
141
|
part
|
129
142
|
else
|
130
|
-
short_s part
|
143
|
+
NRSER::RSpex.short_s part
|
131
144
|
end
|
132
145
|
}.
|
133
146
|
join( ' ' ).
|
134
147
|
squish.
|
135
148
|
thru { |description|
|
136
|
-
mean_streak.render
|
149
|
+
prepend_type type, mean_streak.render( description )
|
137
150
|
}
|
138
151
|
end # .description
|
139
152
|
|
data/lib/nrser/rspex.rb
CHANGED