nrser 0.1.1 β 0.1.2
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/env/path.rb +325 -0
- data/lib/nrser/env.rb +12 -0
- data/lib/nrser/errors/attr_error.rb +73 -0
- data/lib/nrser/errors/count_error.rb +19 -0
- data/lib/nrser/errors/nicer_error.rb +110 -0
- data/lib/nrser/errors/value_error.rb +72 -0
- data/lib/nrser/errors.rb +23 -6
- data/lib/nrser/functions/enumerable.rb +9 -2
- data/lib/nrser/functions/path.rb +3 -1
- data/lib/nrser/functions/string.rb +28 -11
- data/lib/nrser/functions/text/indentation.rb +16 -4
- data/lib/nrser/mean_streak/document.rb +151 -0
- data/lib/nrser/mean_streak.rb +95 -0
- data/lib/nrser/refinements/array.rb +6 -0
- data/lib/nrser/refinements/string.rb +6 -0
- data/lib/nrser/rspex/example_group/describe_instance.rb +24 -0
- data/lib/nrser/rspex/example_group/describe_instance_method.rb +20 -0
- data/lib/nrser/rspex/example_group/describe_setup.rb +22 -0
- data/lib/nrser/rspex/example_group/describe_spec_file.rb +127 -0
- data/lib/nrser/rspex/example_group/describe_use_case.rb +18 -0
- data/lib/nrser/rspex/example_group/describe_when.rb +25 -0
- data/lib/nrser/rspex/example_group/describe_x.rb +100 -0
- data/lib/nrser/rspex/example_group.rb +270 -0
- data/lib/nrser/rspex/format.rb +174 -0
- data/lib/nrser/rspex.rb +31 -395
- data/lib/nrser/types/paths.rb +2 -3
- data/lib/nrser/types.rb +5 -1
- data/lib/nrser/version.rb +1 -1
- data/lib/nrser.rb +3 -1
- data/spec/nrser/env/path/insert_spec.rb +65 -0
- data/spec/nrser/env/path_spec.rb +12 -0
- metadata +99 -8
data/lib/nrser/functions/path.rb
CHANGED
@@ -121,10 +121,18 @@ module NRSER
|
|
121
121
|
end # .truncate
|
122
122
|
|
123
123
|
|
124
|
-
# Cut the middle out of a
|
124
|
+
# Cut the middle out of a sliceable object with length and stick an ellipsis
|
125
|
+
# in there instead.
|
125
126
|
#
|
126
|
-
#
|
127
|
-
#
|
127
|
+
# Categorized with {String} functions 'cause that's where it started, and
|
128
|
+
# that's probably how it will primarily continue to be used, but tested to
|
129
|
+
# work on {Array} and should for other classes that satisfy the same
|
130
|
+
# slice and interface.
|
131
|
+
#
|
132
|
+
# @param [V & #length & #slice & #<< & #+] source
|
133
|
+
# Source object. In practice, {String} and {Array} work. In theory,
|
134
|
+
# anything that responds to `#length`, `#slice`, `#<<` and `#+` with the
|
135
|
+
# same semantics will work.
|
128
136
|
#
|
129
137
|
# @param [Fixnum] max
|
130
138
|
# Max length to allow for the output string.
|
@@ -134,18 +142,27 @@ module NRSER
|
|
134
142
|
# removed. Defaults to the unicode ellipsis since I'm targeting the CLI
|
135
143
|
# at the moment and it saves precious characters.
|
136
144
|
#
|
137
|
-
# @return [
|
138
|
-
#
|
139
|
-
# to do so
|
140
|
-
|
141
|
-
|
145
|
+
# @return [V]
|
146
|
+
# Object of the same type as `source` of at most `max` length with the
|
147
|
+
# middle chopped out if needed to do so.\*
|
148
|
+
#
|
149
|
+
# \* Really, it has to do with how all the used methods are implemented,
|
150
|
+
# but we hope that conforming classes will return instances of their own
|
151
|
+
# class like {String} and {Array} do.
|
152
|
+
#
|
153
|
+
def self.ellipsis source, max, omission: UNICODE_ELLIPSIS
|
154
|
+
return source unless source.length > max
|
142
155
|
|
143
156
|
trim_to = max - omission.length
|
157
|
+
middle = trim_to / 2
|
158
|
+
remainder = trim_to % 2
|
144
159
|
|
145
|
-
start =
|
146
|
-
|
160
|
+
start = source.slice( 0, middle + remainder )
|
161
|
+
start << omission
|
147
162
|
|
148
|
-
|
163
|
+
finish = source.slice( -( middle - remainder )..-1 )
|
164
|
+
|
165
|
+
start + finish
|
149
166
|
end # .ellipsis
|
150
167
|
|
151
168
|
|
@@ -52,10 +52,16 @@ module NRSER
|
|
52
52
|
end
|
53
53
|
|
54
54
|
|
55
|
-
def self.dedent text,
|
55
|
+
def self.dedent text,
|
56
|
+
ignore_whitespace_lines: true,
|
57
|
+
return_lines: false
|
56
58
|
return text if text.empty?
|
57
59
|
|
58
|
-
all_lines = text.
|
60
|
+
all_lines = if text.is_a?( Array )
|
61
|
+
text
|
62
|
+
else
|
63
|
+
text.lines
|
64
|
+
end
|
59
65
|
|
60
66
|
indent_significant_lines = if ignore_whitespace_lines
|
61
67
|
all_lines.reject { |line| whitespace? line }
|
@@ -67,7 +73,7 @@ module NRSER
|
|
67
73
|
|
68
74
|
return text if indent.empty?
|
69
75
|
|
70
|
-
all_lines.map { |line|
|
76
|
+
dedented_lines = all_lines.map { |line|
|
71
77
|
if line.start_with? indent
|
72
78
|
line[indent.length..-1]
|
73
79
|
elsif line.end_with? "\n"
|
@@ -75,7 +81,13 @@ module NRSER
|
|
75
81
|
else
|
76
82
|
""
|
77
83
|
end
|
78
|
-
}
|
84
|
+
}
|
85
|
+
|
86
|
+
if return_lines
|
87
|
+
dedented_lines
|
88
|
+
else
|
89
|
+
dedented_lines.join
|
90
|
+
end
|
79
91
|
end # .dedent
|
80
92
|
|
81
93
|
# I like dedent better, but other libs seems to call it deindent
|
@@ -0,0 +1,151 @@
|
|
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
|
+
# @todo document NRSER::MeanStreak::Document class.
|
29
|
+
class NRSER::MeanStreak::Document
|
30
|
+
|
31
|
+
# Constants
|
32
|
+
# ======================================================================
|
33
|
+
|
34
|
+
|
35
|
+
# Class Methods
|
36
|
+
# ======================================================================
|
37
|
+
|
38
|
+
# @todo Document from method.
|
39
|
+
#
|
40
|
+
# @param [type] arg_name
|
41
|
+
# @todo Add name param description.
|
42
|
+
#
|
43
|
+
# @return [NRSER::MeanStreak::Document]
|
44
|
+
# @todo Document return value.
|
45
|
+
#
|
46
|
+
def self.parse source,
|
47
|
+
mean_streak:,
|
48
|
+
cm_options: :DEFAULT,
|
49
|
+
cm_extensions: []
|
50
|
+
new mean_streak: mean_streak,
|
51
|
+
source: source,
|
52
|
+
doc: CommonMarker.render_doc( source, options, extensions )
|
53
|
+
end # .parse
|
54
|
+
|
55
|
+
singleton_class.send :alias_method, :from_string, :parse
|
56
|
+
singleton_class.send :alias_method, :from_s, :parse
|
57
|
+
|
58
|
+
|
59
|
+
|
60
|
+
# Attributes
|
61
|
+
# ======================================================================
|
62
|
+
|
63
|
+
# The {NRSER::MeanStreak} instance associated with this document, which
|
64
|
+
# contains the rendering configuration.
|
65
|
+
#
|
66
|
+
# @return [NRSER::MeanStreak]
|
67
|
+
#
|
68
|
+
attr_reader :mean_streak
|
69
|
+
|
70
|
+
|
71
|
+
# The source string.
|
72
|
+
#
|
73
|
+
# @return [String]
|
74
|
+
#
|
75
|
+
attr_reader :source
|
76
|
+
|
77
|
+
|
78
|
+
# The root {CommonMarker::Node} (with {CommonMarker::Node#type}=`:document`).
|
79
|
+
#
|
80
|
+
# @return [CommonMarker::Node]
|
81
|
+
#
|
82
|
+
attr_reader :doc
|
83
|
+
|
84
|
+
|
85
|
+
# Constructor
|
86
|
+
# ======================================================================
|
87
|
+
|
88
|
+
# Instantiate a new `NRSER::MeanStreak::Document`.
|
89
|
+
#
|
90
|
+
# @param mean_streak
|
91
|
+
# See {NRSER::MeanStreak::Document#mean_streak}
|
92
|
+
#
|
93
|
+
def initialize mean_streak:, source:, doc:
|
94
|
+
@mean_streak = mean_streak
|
95
|
+
@source = source.dup.freeze
|
96
|
+
@doc = doc
|
97
|
+
end
|
98
|
+
|
99
|
+
|
100
|
+
# Instance Methods
|
101
|
+
# ======================================================================
|
102
|
+
|
103
|
+
# The lines in {#source} as a {Hamster::Vector} of frozen strings.
|
104
|
+
#
|
105
|
+
# @return [Hamster::Vector<String>]
|
106
|
+
#
|
107
|
+
def source_lines
|
108
|
+
@source_lines = Hamster::Vector.new source.lines.map( &:freeze )
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
# Get the substring of the source that a node came from (via its
|
113
|
+
# `#sourcepos`).
|
114
|
+
#
|
115
|
+
# @return [String]
|
116
|
+
#
|
117
|
+
def source_for_node node
|
118
|
+
pos = node.sourcepos
|
119
|
+
|
120
|
+
if pos[:start_line] == pos[:end_line]
|
121
|
+
source_lines[pos[:start_line] - 1][
|
122
|
+
(pos[:start_column] - 1)...pos[:end_column]
|
123
|
+
]
|
124
|
+
else
|
125
|
+
lines = source_lines[(pos[:start_line] - 1)...pos[:end_line]]
|
126
|
+
|
127
|
+
# Trim the start off the first line, unless the start column is 1
|
128
|
+
unless pos[:start_column] == 1
|
129
|
+
lines[0] = lines[0][(pos[:start_column] - 1)..-1]
|
130
|
+
end
|
131
|
+
|
132
|
+
# Trim the end off the first line, unless the end column is the last
|
133
|
+
# line's length
|
134
|
+
unless pos[:end_column] == lines[-1].length
|
135
|
+
lines[-1] = lines[-1][0...pos[:end_column]]
|
136
|
+
end
|
137
|
+
|
138
|
+
lines.join
|
139
|
+
end
|
140
|
+
end
|
141
|
+
|
142
|
+
|
143
|
+
def render_node node, output = ''
|
144
|
+
|
145
|
+
end
|
146
|
+
|
147
|
+
end # class NRSER::MeanStreak::Document
|
148
|
+
|
149
|
+
|
150
|
+
# Post-Processing
|
151
|
+
# =======================================================================
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
# Requirements
|
4
|
+
# =======================================================================
|
5
|
+
|
6
|
+
# Stdlib
|
7
|
+
# -----------------------------------------------------------------------
|
8
|
+
|
9
|
+
# Deps
|
10
|
+
# -----------------------------------------------------------------------
|
11
|
+
require 'commonmarker'
|
12
|
+
|
13
|
+
# Project / Package
|
14
|
+
# -----------------------------------------------------------------------
|
15
|
+
|
16
|
+
# Refinements
|
17
|
+
# =======================================================================
|
18
|
+
|
19
|
+
|
20
|
+
# Declarations
|
21
|
+
# =======================================================================
|
22
|
+
|
23
|
+
|
24
|
+
# Definitions
|
25
|
+
# =======================================================================
|
26
|
+
|
27
|
+
|
28
|
+
# Tag up terminals with color and style. Uses {CommonMarker} for the parsing
|
29
|
+
# (Markdown / CommonMark / GFM syntax).
|
30
|
+
#
|
31
|
+
# {NRSER::MeanStreak} instances hold configuration and provide functionality
|
32
|
+
# through instance methods, making it easy to use multiple configurations or
|
33
|
+
# subclass {NRSER::MeanStreak} to further customize functionality.
|
34
|
+
#
|
35
|
+
# An instance with default configuration is available via the {.default}
|
36
|
+
# class method, and additional class methods are provided that proxy to the
|
37
|
+
# default's instance methods, providing convenient use of the default config.
|
38
|
+
#
|
39
|
+
class NRSER::MeanStreak
|
40
|
+
|
41
|
+
# Class Methods
|
42
|
+
# ======================================================================
|
43
|
+
|
44
|
+
# Get the default instance, which has the default configuration and is
|
45
|
+
# used by the class methods.
|
46
|
+
#
|
47
|
+
# @return [NRSER::MeanStreak]
|
48
|
+
#
|
49
|
+
def self.default
|
50
|
+
# TODO cache?
|
51
|
+
new
|
52
|
+
end # .default
|
53
|
+
|
54
|
+
|
55
|
+
# Public: Parses a Markdown string into a `document` node.
|
56
|
+
#
|
57
|
+
# string - {String} to be parsed
|
58
|
+
# option - A {Symbol} or {Array of Symbol}s indicating the parse options
|
59
|
+
# extensions - An {Array of Symbol}s indicating the extensions to use
|
60
|
+
#
|
61
|
+
# @return [CommonMarker::Node]
|
62
|
+
# The `document` node.
|
63
|
+
#
|
64
|
+
def self.parse text, options = :DEFAULT, extensions = []
|
65
|
+
|
66
|
+
end
|
67
|
+
|
68
|
+
|
69
|
+
# Instance Methods
|
70
|
+
# ============================================================================
|
71
|
+
|
72
|
+
|
73
|
+
# @todo Document parse method.
|
74
|
+
#
|
75
|
+
# @param [type] arg_name
|
76
|
+
# @todo Add name param description.
|
77
|
+
#
|
78
|
+
# @return [return_type]
|
79
|
+
# @todo Document return value.
|
80
|
+
#
|
81
|
+
def parse source, **options
|
82
|
+
NRSER::MeanStreak::Document.parse \
|
83
|
+
source,
|
84
|
+
**options,
|
85
|
+
mean_streak: self
|
86
|
+
end # #parse
|
87
|
+
|
88
|
+
|
89
|
+
end # class NRSER::ShellDown
|
90
|
+
|
91
|
+
|
92
|
+
# Post-Processing
|
93
|
+
# =======================================================================
|
94
|
+
|
95
|
+
require_relative './mean_streak/document'
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NRSER::RSpex::ExampleGroup
|
4
|
+
|
5
|
+
# @todo Document describe_instance method.
|
6
|
+
#
|
7
|
+
# @param [type] arg_name
|
8
|
+
# @todo Add name param description.
|
9
|
+
#
|
10
|
+
# @return [return_type]
|
11
|
+
# @todo Document return value.
|
12
|
+
#
|
13
|
+
def describe_instance *constructor_args, &body
|
14
|
+
describe_x_type ".new(", Args(*constructor_args), ")",
|
15
|
+
type: :instance,
|
16
|
+
metadata: {
|
17
|
+
constructor_args: constructor_args,
|
18
|
+
},
|
19
|
+
# subject_block: -> { super().new *described_args },
|
20
|
+
subject_block: -> { super().new *described_constructor_args },
|
21
|
+
&body
|
22
|
+
end # #describe_instance
|
23
|
+
|
24
|
+
end # module NRSER::RSpex::ExampleGroup
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NRSER::RSpex::ExampleGroup
|
4
|
+
|
5
|
+
def describe_instance_method name, **metadata, &block
|
6
|
+
describe(
|
7
|
+
"#{ NRSER::RSpex::PREFIXES[:method] } #{ name }",
|
8
|
+
type: :method,
|
9
|
+
method_name: name,
|
10
|
+
**metadata
|
11
|
+
) do
|
12
|
+
if name.is_a? Symbol
|
13
|
+
subject { super().method name }
|
14
|
+
end
|
15
|
+
|
16
|
+
module_exec &block
|
17
|
+
end
|
18
|
+
end # #describe_method
|
19
|
+
|
20
|
+
end # module NRSER::RSpex::ExampleGroup
|
@@ -0,0 +1,22 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NRSER::RSpex::ExampleGroup
|
4
|
+
|
5
|
+
# Setup describes what's going to be *done* in all child examples.
|
6
|
+
#
|
7
|
+
# It's where you setup your `subject`, usually depending on `let`
|
8
|
+
# bindings that are provided in the children.
|
9
|
+
#
|
10
|
+
# @return [void]
|
11
|
+
#
|
12
|
+
def describe_setup *description, **metadata, &body
|
13
|
+
describe_x \
|
14
|
+
*description,
|
15
|
+
type: :setup,
|
16
|
+
metadata: metadata,
|
17
|
+
&body
|
18
|
+
end # #describe_setup
|
19
|
+
|
20
|
+
alias_method :setup, :describe_setup
|
21
|
+
|
22
|
+
end # module NRSER::RSpex::ExampleGroup
|
@@ -0,0 +1,127 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NRSER::RSpex::ExampleGroup
|
4
|
+
|
5
|
+
# **EXPERIMENTAL**
|
6
|
+
#
|
7
|
+
# Example group helper for use at the top level of each spec file to
|
8
|
+
# set a bunch of stuff up and build a helpful description.
|
9
|
+
#
|
10
|
+
# @todo
|
11
|
+
# This is totally just a one-off right now... would need to be
|
12
|
+
# generalized quite a bit...
|
13
|
+
#
|
14
|
+
# 1. Extraction of module, class, etc from metadata should be flexible
|
15
|
+
#
|
16
|
+
# 2. Built description would need to be conditional on what metadata
|
17
|
+
# was found.
|
18
|
+
#
|
19
|
+
# @param [String] description:
|
20
|
+
# A description of the spec file to add to the RSpec description.
|
21
|
+
#
|
22
|
+
# @param [String] spec_path:
|
23
|
+
# The path to the spec file (just feed it `__FILE__`).
|
24
|
+
#
|
25
|
+
# Probably possible to extract this somehow without having to provide it?
|
26
|
+
#
|
27
|
+
# @return [nil]
|
28
|
+
#
|
29
|
+
def describe_spec_file description: nil,
|
30
|
+
spec_path:,
|
31
|
+
bind_subject: true,
|
32
|
+
**metadata,
|
33
|
+
&body
|
34
|
+
|
35
|
+
if metadata[:module] && metadata[:method]
|
36
|
+
meth = metadata[:module].method metadata[:method]
|
37
|
+
file, line = meth.source_location
|
38
|
+
path = Pathname.new file
|
39
|
+
loc = "./#{ path.relative_path_from Pathname.getwd }:#{ line }"
|
40
|
+
|
41
|
+
spec_rel_path = \
|
42
|
+
"./#{ Pathname.new( spec_path ).relative_path_from Pathname.getwd }"
|
43
|
+
|
44
|
+
desc = [
|
45
|
+
"#{ metadata[:module].name }.#{ metadata[:method] }",
|
46
|
+
"(#{ loc })",
|
47
|
+
description,
|
48
|
+
"Spec (#{ spec_rel_path})"
|
49
|
+
].compact.join " "
|
50
|
+
|
51
|
+
subj = meth
|
52
|
+
|
53
|
+
elsif metadata[:class]
|
54
|
+
klass = metadata[:class]
|
55
|
+
|
56
|
+
if metadata[:instance_method]
|
57
|
+
instance_method = klass.instance_method metadata[:instance_method]
|
58
|
+
|
59
|
+
file, line = instance_method.source_location
|
60
|
+
|
61
|
+
name = "#{ klass.name }##{ metadata[:instance_method] }"
|
62
|
+
else
|
63
|
+
name = klass.name
|
64
|
+
|
65
|
+
# Get a reasonable file and line for the class
|
66
|
+
file, line = klass.
|
67
|
+
# Get an array of all instance methods, excluding inherited ones
|
68
|
+
# (the `false` arg)
|
69
|
+
instance_methods( false ).
|
70
|
+
# Add `#initialize` since it isn't in `#instance_methods` for some
|
71
|
+
# reason
|
72
|
+
<<( :initialize ).
|
73
|
+
# Map those to their {UnboundMethod} objects
|
74
|
+
map { |sym| klass.instance_method sym }.
|
75
|
+
# Toss any `nil` values
|
76
|
+
compact.
|
77
|
+
# Get the source locations
|
78
|
+
map( &:source_location ).
|
79
|
+
# Get the first line in the shortest path
|
80
|
+
min_by { |(path, line)| [path.length, line] }
|
81
|
+
|
82
|
+
# Another approach I thought of... (untested)
|
83
|
+
#
|
84
|
+
# Get the path
|
85
|
+
# # Get frequency of the paths
|
86
|
+
# count_by { |(path, line)| path }.
|
87
|
+
# # Get the one with the most occurrences
|
88
|
+
# max_by { |path, count| count }.
|
89
|
+
# # Get just the path (not the count)
|
90
|
+
# first
|
91
|
+
end
|
92
|
+
|
93
|
+
location = if file
|
94
|
+
"(#{ NRSER::RSpex.dot_rel_path file }:#{ line })"
|
95
|
+
end
|
96
|
+
|
97
|
+
desc = [
|
98
|
+
"πππΈπΆ πΉπΌπΏπΈ `#{ NRSER::RSpex.dot_rel_path spec_path }` πΉππ
",
|
99
|
+
name,
|
100
|
+
location,
|
101
|
+
description,
|
102
|
+
].compact.join " "
|
103
|
+
|
104
|
+
subj = klass
|
105
|
+
|
106
|
+
else
|
107
|
+
# TODO Make this work!
|
108
|
+
raise ArgumentError.new binding.erb <<-END
|
109
|
+
Not yet able to handle metadata:
|
110
|
+
|
111
|
+
<%= metadata.pretty_inspect %>
|
112
|
+
|
113
|
+
END
|
114
|
+
end
|
115
|
+
|
116
|
+
describe desc, **metadata do
|
117
|
+
if bind_subject
|
118
|
+
subject { subj }
|
119
|
+
end
|
120
|
+
|
121
|
+
module_exec &body
|
122
|
+
end
|
123
|
+
|
124
|
+
nil
|
125
|
+
end # #describe_spec_file
|
126
|
+
|
127
|
+
end # module NRSER::RSpex::ExampleGroup
|
@@ -0,0 +1,18 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NRSER::RSpex::ExampleGroup
|
4
|
+
|
5
|
+
# @todo Document describe_use_case method.
|
6
|
+
#
|
7
|
+
# @return [void]
|
8
|
+
#
|
9
|
+
def describe_use_case *description, where: {}, **metadata, &body
|
10
|
+
describe_x \
|
11
|
+
*description,
|
12
|
+
type: :use_case,
|
13
|
+
bindings: where,
|
14
|
+
metadata: metadata,
|
15
|
+
&body
|
16
|
+
end # #describe_use_case
|
17
|
+
|
18
|
+
end # module NRSER::RSpex::ExampleGroup
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module NRSER::RSpex::ExampleGroup
|
4
|
+
|
5
|
+
# Define a example group block with `let` bindings and evaluate the `body`
|
6
|
+
# block in it.
|
7
|
+
#
|
8
|
+
# @param [Hash<Symbol, Object>] **bindings
|
9
|
+
# Map of symbol names to value to bind using `let`.
|
10
|
+
#
|
11
|
+
# @param [#call] &body
|
12
|
+
# Body block to evaluate in the context.
|
13
|
+
#
|
14
|
+
# @return
|
15
|
+
# Whatever `context` returns.
|
16
|
+
#
|
17
|
+
def describe_when *description, **bindings, &body
|
18
|
+
describe_x \
|
19
|
+
*description,
|
20
|
+
type: :when,
|
21
|
+
bindings: bindings,
|
22
|
+
&body
|
23
|
+
end
|
24
|
+
|
25
|
+
end # module NRSER::RSpex::ExampleGroup
|