nrser 0.2.2 → 0.3.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/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
@@ -0,0 +1,49 @@
|
|
1
|
+
# encoding: UTF-8
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module NRSER::RSpex::ExampleGroup
|
5
|
+
|
6
|
+
# Create an example group covering a source file.
|
7
|
+
#
|
8
|
+
# Useful for when method implementations are spread out across multiple
|
9
|
+
# files but you want to group examples by the source file they're in.
|
10
|
+
#
|
11
|
+
# @note
|
12
|
+
# Honestly, now that modules, classes and methods described through RSpex
|
13
|
+
# add their source locations, this is not all that useful. But it was
|
14
|
+
# there from before that, which is why for the moment it's still here.
|
15
|
+
#
|
16
|
+
# @see #describe_x
|
17
|
+
#
|
18
|
+
# @param [String | Pathname] path
|
19
|
+
# File path.
|
20
|
+
#
|
21
|
+
# @param *description (see #describe_x)
|
22
|
+
#
|
23
|
+
# @param [Hash<Symbol, Object>] **metadata
|
24
|
+
# RSpec metadata to set for the example group.
|
25
|
+
#
|
26
|
+
# See the `metadata` keyword argument to {#describe_x}.
|
27
|
+
#
|
28
|
+
# A `file` key is added pointed to the {Pathname} for `path` before
|
29
|
+
# passing up to {#describe_x}.
|
30
|
+
#
|
31
|
+
# @param &body (see #describe_x)
|
32
|
+
#
|
33
|
+
# @return (see #describe_x)
|
34
|
+
#
|
35
|
+
def describe_source_file path, *description, **metadata, &body
|
36
|
+
path = path.to_pn
|
37
|
+
|
38
|
+
describe_x \
|
39
|
+
path,
|
40
|
+
*description,
|
41
|
+
type: :source_file,
|
42
|
+
metadata: {
|
43
|
+
source_file: path,
|
44
|
+
**metadata,
|
45
|
+
},
|
46
|
+
&body
|
47
|
+
end
|
48
|
+
|
49
|
+
end # module NRSER::RSpex::ExampleGroup
|
@@ -4,6 +4,26 @@ using NRSER
|
|
4
4
|
|
5
5
|
module NRSER::RSpex::ExampleGroup
|
6
6
|
|
7
|
+
def dive_x current, *rest, **kwds, &body
|
8
|
+
type, data = current
|
9
|
+
|
10
|
+
method_name = "describe_#{ type }"
|
11
|
+
|
12
|
+
block = if rest.empty?
|
13
|
+
body
|
14
|
+
else
|
15
|
+
-> { dive_x *rest, &body }
|
16
|
+
end
|
17
|
+
|
18
|
+
begin
|
19
|
+
public_send method_name, data, **kwds, &block
|
20
|
+
rescue NoMethodError => error
|
21
|
+
pp self.methods
|
22
|
+
raise error
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
|
7
27
|
# **EXPERIMENTAL**
|
8
28
|
#
|
9
29
|
# Example group helper for use at the top level of each spec file to
|
@@ -26,7 +46,7 @@ module NRSER::RSpex::ExampleGroup
|
|
26
46
|
#
|
27
47
|
# Probably possible to extract this somehow without having to provide it?
|
28
48
|
#
|
29
|
-
# @return
|
49
|
+
# @return (see #describe_x)
|
30
50
|
#
|
31
51
|
def describe_spec_file description: nil,
|
32
52
|
spec_path:,
|
@@ -34,118 +54,31 @@ module NRSER::RSpex::ExampleGroup
|
|
34
54
|
**metadata,
|
35
55
|
&body
|
36
56
|
|
37
|
-
|
38
|
-
meth = metadata[:module].method metadata[:method]
|
39
|
-
file, line = meth.source_location
|
40
|
-
path = Pathname.new file
|
41
|
-
loc = "./#{ path.relative_path_from Pathname.getwd }:#{ line }"
|
42
|
-
|
43
|
-
spec_rel_path = \
|
44
|
-
"./#{ Pathname.new( spec_path ).relative_path_from Pathname.getwd }"
|
45
|
-
|
46
|
-
desc = [
|
47
|
-
"#{ metadata[:module].name }.#{ metadata[:method] }",
|
48
|
-
"(#{ loc })",
|
49
|
-
description,
|
50
|
-
"Spec (#{ spec_rel_path})"
|
51
|
-
].compact.join " "
|
52
|
-
|
53
|
-
subj = meth
|
57
|
+
chain = []
|
54
58
|
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
meth = metadata[:class].method metadata[:method]
|
68
|
-
file, line = meth.source_location
|
69
|
-
path = Pathname.new file
|
70
|
-
loc = "./#{ path.relative_path_from Pathname.getwd }:#{ line }"
|
71
|
-
|
72
|
-
spec_rel_path = \
|
73
|
-
"./#{ Pathname.new( spec_path ).relative_path_from Pathname.getwd }"
|
74
|
-
|
75
|
-
desc = [
|
76
|
-
"#{ metadata[:class].name }.#{ metadata[:method] }",
|
77
|
-
"(#{ loc })",
|
78
|
-
description,
|
79
|
-
"Spec (#{ spec_rel_path})"
|
80
|
-
].compact.join " "
|
81
|
-
|
82
|
-
subj = meth
|
83
|
-
|
84
|
-
else
|
85
|
-
name = klass.name
|
86
|
-
|
87
|
-
# Get a reasonable file and line for the class
|
88
|
-
file, line = klass.
|
89
|
-
# Get an array of all instance methods, excluding inherited ones
|
90
|
-
# (the `false` arg)
|
91
|
-
instance_methods( false ).
|
92
|
-
# Add `#initialize` since it isn't in `#instance_methods` for some
|
93
|
-
# reason
|
94
|
-
<<( :initialize ).
|
95
|
-
# Map those to their {UnboundMethod} objects
|
96
|
-
map { |sym| klass.instance_method sym }.
|
97
|
-
# Toss any `nil` values
|
98
|
-
compact.
|
99
|
-
# Get the source locations
|
100
|
-
map( &:source_location ).
|
101
|
-
# Get rid of `[nil, nil]` results, which seems to come from C exts
|
102
|
-
reject { |(path, line)| path.nil? || line.nil? }.
|
103
|
-
# Get the first line in the shortest path
|
104
|
-
min_by { |(path, line)| [path.length, line] }
|
105
|
-
|
106
|
-
# Another approach I thought of... (untested)
|
107
|
-
#
|
108
|
-
# Get the path
|
109
|
-
# # Get frequency of the paths
|
110
|
-
# count_by { |(path, line)| path }.
|
111
|
-
# # Get the one with the most occurrences
|
112
|
-
# max_by { |path, count| count }.
|
113
|
-
# # Get just the path (not the count)
|
114
|
-
# first
|
115
|
-
end
|
116
|
-
|
117
|
-
location = if file
|
118
|
-
"(#{ NRSER::RSpex.dot_rel_path file }:#{ line })"
|
59
|
+
[
|
60
|
+
:source_file,
|
61
|
+
:module,
|
62
|
+
:class,
|
63
|
+
:instance,
|
64
|
+
:method,
|
65
|
+
:instance_method,
|
66
|
+
:called_with,
|
67
|
+
:attribute,
|
68
|
+
].each do |type|
|
69
|
+
if data = metadata.delete( type )
|
70
|
+
chain << [type, data]
|
119
71
|
end
|
120
|
-
|
121
|
-
desc = [
|
122
|
-
"𝑆𝑃𝐸𝐶 𝐹𝐼𝐿𝐸 `#{ NRSER::RSpex.dot_rel_path spec_path }` 𝐹𝑂𝑅",
|
123
|
-
name,
|
124
|
-
location,
|
125
|
-
description,
|
126
|
-
].compact.join " "
|
127
|
-
|
128
|
-
subj = klass
|
129
|
-
|
130
|
-
else
|
131
|
-
# TODO Make this work!
|
132
|
-
raise ArgumentError.new binding.erb <<-END
|
133
|
-
Not yet able to handle metadata:
|
134
|
-
|
135
|
-
<%= metadata.pretty_inspect %>
|
136
|
-
|
137
|
-
END
|
138
72
|
end
|
139
73
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
74
|
+
describe_x(
|
75
|
+
NRSER::RSpex.dot_rel_path( spec_path ),
|
76
|
+
*description,
|
77
|
+
type: :spec_file,
|
78
|
+
metadata: metadata,
|
79
|
+
) do
|
80
|
+
dive_x *chain, bind_subject: bind_subject, &body
|
146
81
|
end
|
147
|
-
|
148
|
-
nil
|
149
82
|
end # #describe_spec_file
|
150
83
|
|
151
84
|
end # module NRSER::RSpex::ExampleGroup
|
@@ -1,18 +1,20 @@
|
|
1
|
+
# encoding: UTF-8
|
1
2
|
# frozen_string_literal: true
|
2
3
|
|
3
4
|
module NRSER::RSpex::ExampleGroup
|
4
5
|
|
5
|
-
# Define a example group
|
6
|
-
#
|
6
|
+
# Define a example group with the keyword args as bindings.
|
7
|
+
#
|
8
|
+
# @see #describe_x
|
9
|
+
#
|
10
|
+
# @param *description (see #describe_x)
|
7
11
|
#
|
8
12
|
# @param [Hash<Symbol, Object>] **bindings
|
9
|
-
#
|
13
|
+
# See the `bindings` keyword arg in {#describe_x}.
|
10
14
|
#
|
11
|
-
# @param
|
12
|
-
# Body block to evaluate in the context.
|
15
|
+
# @param &body (see #describe_x)
|
13
16
|
#
|
14
|
-
# @return
|
15
|
-
# Whatever `context` returns.
|
17
|
+
# @return (see #describe_x)
|
16
18
|
#
|
17
19
|
def describe_when *description, **bindings, &body
|
18
20
|
describe_x \
|
@@ -22,4 +24,9 @@ module NRSER::RSpex::ExampleGroup
|
|
22
24
|
&body
|
23
25
|
end
|
24
26
|
|
27
|
+
# Old name (used to be different method)
|
28
|
+
|
29
|
+
alias_method :context_where, :describe_when
|
30
|
+
|
31
|
+
|
25
32
|
end # module NRSER::RSpex::ExampleGroup
|
@@ -23,25 +23,38 @@ module NRSER::RSpex::ExampleGroup
|
|
23
23
|
# key.
|
24
24
|
#
|
25
25
|
# @param [Hash<Symbol, Object>] metadata:
|
26
|
-
#
|
26
|
+
# [RSpec metadata][] to add to the new example group.
|
27
27
|
#
|
28
28
|
# In addition to the keys RSpec will reject, we prohibit `:type` *unless*
|
29
29
|
# it is the same as the `type` keyword argument or `nil`.
|
30
30
|
#
|
31
31
|
# In either of these cases, the `type` keyword arg will be used for the new
|
32
32
|
# example group's `:type` metadata value.
|
33
|
+
#
|
34
|
+
# [RSpec metadata]: https://relishapp.com/rspec/rspec-core/docs/metadata/user-defined-metadata
|
33
35
|
#
|
34
36
|
# @param [Hash<Symbol, Object>] bindings:
|
37
|
+
# Name to value pairs to bind in the new example group.
|
35
38
|
#
|
39
|
+
# All values will be bound at the example group and example levels -
|
40
|
+
# though if they are {Wrapper}, that wrapper will be available at the
|
41
|
+
# group level, while they will be automatically unwrapped at the
|
42
|
+
# example level (as the requisite context is available there).
|
43
|
+
#
|
44
|
+
# @param [Boolean] bind_subject:
|
45
|
+
# When `true` (and there is a `subject_block`) bind the `subject` inside
|
46
|
+
# the new example group.
|
47
|
+
#
|
48
|
+
#
|
36
49
|
#
|
37
|
-
# @return [
|
38
|
-
# @todo Document return value.
|
50
|
+
# @return [void]
|
39
51
|
#
|
40
52
|
def describe_x *description,
|
41
53
|
type:,
|
42
54
|
metadata: {},
|
43
55
|
bindings: {},
|
44
56
|
add_binding_desc: true,
|
57
|
+
bind_subject: true,
|
45
58
|
subject_block: nil,
|
46
59
|
&body
|
47
60
|
|
@@ -67,30 +80,44 @@ module NRSER::RSpex::ExampleGroup
|
|
67
80
|
END
|
68
81
|
end
|
69
82
|
|
83
|
+
# Add description of the bindings, if we have any and were told to
|
70
84
|
unless bindings.empty? || add_binding_desc == false
|
71
|
-
|
72
|
-
|
85
|
+
bindings_desc = NRSER::RSpex::Format.md_code_quote \
|
86
|
+
bindings.map { |name, value|
|
87
|
+
"#{ name } = #{ value.inspect }"
|
88
|
+
}.join( '; ' )
|
73
89
|
|
74
90
|
if description.empty?
|
75
|
-
description =
|
91
|
+
description = bindings_desc
|
76
92
|
else
|
77
|
-
description
|
93
|
+
description << "(" + bindings_desc + ")"
|
78
94
|
end
|
79
95
|
end
|
80
96
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
97
|
+
# Call up to RSpec's `#describe` method
|
98
|
+
describe(
|
99
|
+
NRSER::RSpex::Format.description( *description, type: type ),
|
100
|
+
**metadata,
|
101
|
+
type: type,
|
102
|
+
) do
|
103
|
+
if subject_block && bind_subject
|
104
|
+
subject &subject_block
|
105
|
+
end
|
85
106
|
|
107
|
+
# Bind bindings
|
86
108
|
unless bindings.empty?
|
87
109
|
bindings.each { |name, value|
|
110
|
+
# Example-level binding
|
88
111
|
let( name ) { unwrap value, context: self }
|
112
|
+
|
113
|
+
# Example group-level binding (which may return a {Wrapper} that
|
114
|
+
# of course can not be unwrapped at the group level)
|
115
|
+
define_singleton_method( name ) { value }
|
89
116
|
}
|
90
117
|
end
|
91
118
|
|
92
119
|
module_exec &body
|
93
|
-
end #
|
120
|
+
end # describe
|
94
121
|
|
95
122
|
end # #describe_x
|
96
123
|
|
@@ -0,0 +1,66 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
# encoding: utf-8
|
3
|
+
|
4
|
+
|
5
|
+
# Definitions
|
6
|
+
# =======================================================================
|
7
|
+
|
8
|
+
module NRSER::RSpex::ExampleGroup
|
9
|
+
|
10
|
+
# HACK HACK HACK-ITY HACK - Allow for overriding RSpec methods
|
11
|
+
#
|
12
|
+
# Yeah, it has to do with mixin mixing-in ordering - seems to be that when
|
13
|
+
#
|
14
|
+
# config.extend NRSER::RSpex::ExampleGroup
|
15
|
+
#
|
16
|
+
# {NRSER::RSpex::ExampleGroup} gets mixed in *very early* in the chain,
|
17
|
+
# before {RSpec::Core::ExampleGroup}... why you would provide an explicit
|
18
|
+
# extension mechanism and not give those extensions priority I'm not sure,
|
19
|
+
# but I'm sure I shouldn't be looking into it right now, so here we are:
|
20
|
+
#
|
21
|
+
# It turns out that {NRSER::RSpex::Example}, which gets mixed with
|
22
|
+
#
|
23
|
+
# config.include NRSER::RSpex::Example
|
24
|
+
#
|
25
|
+
# gets mixed *last*, so by using it's {NRSER::RSpex::Example.included}
|
26
|
+
# hook we can use
|
27
|
+
#
|
28
|
+
# base#extend NRSER::RSpex::ExampleGroup::Overrides
|
29
|
+
#
|
30
|
+
# to mix these guys over the top of RSpec's methods.
|
31
|
+
#
|
32
|
+
# Seems like we could just mix all of {NRSER::RSpex::ExampleGroup} there
|
33
|
+
# to get the behavior I would have expected all along, but maybe it's better
|
34
|
+
# to have these explicit notes for the moment and not change much else until
|
35
|
+
# I get the chance to really check out what's going on.
|
36
|
+
#
|
37
|
+
# And really it's all to override `.described_class` to pick up our
|
38
|
+
# metadata if it's there, but that approach is in quite a bit of use at
|
39
|
+
# this point, and, no, I have no idea how it seemed to work up until this
|
40
|
+
# point :/
|
41
|
+
#
|
42
|
+
module Overrides
|
43
|
+
|
44
|
+
# Override {RSpec::Core::ExampleGroup.described_class} to use RSpex's
|
45
|
+
# `:class` metadata if it's present.
|
46
|
+
#
|
47
|
+
# Because I can't figure out how to feed RSpec the described class
|
48
|
+
# without it being the description, and we want better descriptions.
|
49
|
+
#
|
50
|
+
# Some hackery could def do it, this is RUBY after all, but whatever this
|
51
|
+
# works for now and may even be less fragile.
|
52
|
+
#
|
53
|
+
# @return [Class]
|
54
|
+
# If there's a `:class` in the metadata, or if RSpec has on through the
|
55
|
+
# standard means (`describe MyClass do ...`).
|
56
|
+
#
|
57
|
+
# @return [nil]
|
58
|
+
# If we don't have a class context around.
|
59
|
+
#
|
60
|
+
def described_class
|
61
|
+
metadata[:class] || super()
|
62
|
+
end
|
63
|
+
|
64
|
+
end # module Overrides
|
65
|
+
|
66
|
+
end # module NRSER:RSpex::ExampleGroup
|