nrser 0.2.0.pre.3 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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