Module: NRSER::RSpex::ExampleGroup
- Defined in:
- lib/nrser/rspex/example_group/overrides.rb,
lib/nrser/rspex/example_group.rb,
lib/nrser/rspex/example_group/describe_x.rb,
lib/nrser/rspex/example_group/describe_case.rb,
lib/nrser/rspex/example_group/describe_when.rb,
lib/nrser/rspex/example_group/describe_class.rb,
lib/nrser/rspex/example_group/describe_group.rb,
lib/nrser/rspex/example_group/describe_setup.rb,
lib/nrser/rspex/example_group/describe_method.rb,
lib/nrser/rspex/example_group/describe_module.rb,
lib/nrser/rspex/example_group/describe_message.rb,
lib/nrser/rspex/example_group/describe_section.rb,
lib/nrser/rspex/example_group/describe_sent_to.rb,
lib/nrser/rspex/example_group/describe_subject.rb,
lib/nrser/rspex/example_group/describe_instance.rb,
lib/nrser/rspex/example_group/describe_attribute.rb,
lib/nrser/rspex/example_group/describe_spec_file.rb,
lib/nrser/rspex/example_group/describe_called_with.rb,
lib/nrser/rspex/example_group/describe_response_to.rb,
lib/nrser/rspex/example_group/describe_source_file.rb,
lib/nrser/rspex/example_group/describe_instance_method.rb
Overview
Definitions
Defined Under Namespace
Modules: Overrides
Instance Method Summary collapse
-
#describe_attribute(symbol, **metadata, &body) ⇒ void
(also: #describe_attr, #ATTRIBUTE)
Describe an attribute of the parent subject.
-
#describe_called(&body) ⇒ void
(also: #called, #when_called, #CALLED)
Version of #describe_called_with for when you have no arguments.
-
#describe_called_with(*args, &body) ⇒ void
(also: #called_with, #CALLED_WITH)
Create a new RSpec.describe section where the subject is set by calling the parent subject with ‘args` and evaluate `block` in it.
- #describe_case(*description, where: {}, **metadata, &body) ⇒ void (also: #use_case, #CASE, #describe_use_case)
- #describe_class(klass, *description, bind_subject: true, **metadata, &body) ⇒ void (also: #CLASS)
-
#describe_group(*description, **metadata, &body) ⇒ void
Describe a “group”.
-
#describe_instance(*constructor_args, &body) ⇒ void
(also: #INSTANCE)
Describe an instance of the described class by providing arguments for it’s construction.
- #describe_instance_method(name, **metadata, &block) ⇒ Object
-
#describe_message(*args, &body) ⇒ void
(also: #MESSAGE)
Describe a Message.
-
#describe_method(method, *description, bind_subject: nil, **metadata, &body) ⇒ void
(also: #METHOD)
Describe a method of the parent subject.
- #describe_module(mod, bind_subject: true, **metadata, &body) ⇒ Object
-
#describe_response_to(*args, &body) ⇒ void
(also: #describe_return_value)
Describe the response of the subject to a Message.
-
#describe_section(*description, **metadata, &body) ⇒ void
(also: #describe_topic, #SECTION)
Describe a “section”.
-
#describe_sent_to(receiver, publicly: true, bind_subject: true, &body) ⇒ void
(also: #sent_to)
For use when ‘subject` is a Message.
-
#describe_setup(*description, **metadata, &body) ⇒ void
(also: #setup, #SETUP)
Setup describes what’s going to be done in all child examples.
-
#describe_source_file(path, *description, **metadata, &body) ⇒ void
Create an example group covering a source file.
-
#describe_spec_file(description: nil, spec_path:, bind_subject: true, **metadata, &body) ⇒ void
(also: #SPEC_FILE)
EXPERIMENTAL.
-
#describe_subject(subject, **metadata, &body) ⇒ void
(also: #SUBJECT)
Define a example group binding a subject.
-
#describe_when(*description, **bindings, &body) ⇒ void
(also: #context_where, #_when, #WHEN)
Define a example group with the keyword args as bindings.
-
#describe_x(*description, type:, metadata: {}, bindings: {}, add_binding_desc: true, bind_subject: true, subject_block: nil, &body) ⇒ void
(also: #describe_x_type)
The core, mostly internal method that all RSpex’s description methods lead back too (or should / will when refactoring is done).
- #dive_x(current, *rest, **kwds, &body) ⇒ Object
Instance Method Details
#describe_attribute(symbol, **metadata, &body) ⇒ void Also known as: describe_attr, ATTRIBUTE
This method returns an undefined value.
Describe an attribute of the parent subject.
10 11 12 13 14 15 16 17 18 19 |
# File 'lib/nrser/rspex/example_group/describe_attribute.rb', line 10 def describe_attribute symbol, **, &body describe_x \ NRSER::RSpex::Format.md_code_quote( "##{ symbol }" ), type: :attribute, metadata: , subject_block: -> { super().public_send symbol }, &body end |
#describe_called(&body) ⇒ void Also known as: called, when_called, CALLED
This method returns an undefined value.
Version of #describe_called_with for when you have no arguments.
49 50 51 52 53 54 |
# File 'lib/nrser/rspex/example_group/describe_called_with.rb', line 49 def describe_called &body describe_x Args(), type: :called_with, subject_block: -> { super().call }, &body end |
#describe_called_with(*args, &body) ⇒ void Also known as: called_with, CALLED_WITH
This method returns an undefined value.
Create a new RSpec.describe section where the subject is set by calling the parent subject with ‘args` and evaluate `block` in it.
27 28 29 30 31 32 |
# File 'lib/nrser/rspex/example_group/describe_called_with.rb', line 27 def describe_called_with *args, &body describe_x Args(*args), type: :called_with, subject_block: -> { super().call *args }, &body end |
#describe_case(*description, where: {}, **metadata, &body) ⇒ void Also known as: use_case, CASE, describe_use_case
Document describe_use_case method.
This method returns an undefined value.
9 10 11 12 13 14 15 16 |
# File 'lib/nrser/rspex/example_group/describe_case.rb', line 9 def describe_case *description, where: {}, **, &body describe_x \ *description, type: :case, bindings: where, metadata: , &body end |
#describe_class(klass, *description, bind_subject: true, **metadata, &body) ⇒ void Also known as: CLASS
Document describe_class method.
This method returns an undefined value.
10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
# File 'lib/nrser/rspex/example_group/describe_class.rb', line 10 def describe_class klass, *description, bind_subject: true, **, &body subject_block = if bind_subject -> { klass } end describe_x \ NRSER::RSpex::Format.md_code_quote( klass.name ), klass.source_location, *description, type: :class, metadata: { **, class: klass, }, subject_block: subject_block, &body end |
#describe_group(*description, **metadata, &body) ⇒ void
This method returns an undefined value.
Describe a “group”. Doesn’t really do much. Didn’t end up getting used much. Probably not long for this world.
20 21 22 23 24 25 26 27 |
# File 'lib/nrser/rspex/example_group/describe_group.rb', line 20 def describe_group *description, **, &body # Pass up to {#describe_x} describe_x \ *description, type: :group, metadata: , &body end |
#describe_instance(*constructor_args, &body) ⇒ void Also known as: INSTANCE
This method returns an undefined value.
Describe an instance of the described class by providing arguments for it’s construction.
13 14 15 16 17 18 19 20 21 22 23 |
# File 'lib/nrser/rspex/example_group/describe_instance.rb', line 13 def describe_instance *constructor_args, &body describe_x ".new", Args(*constructor_args), type: :instance, metadata: { constructor_args: constructor_args, }, subject_block: -> { described_class.new *described_constructor_args }, &body end |
#describe_instance_method(name, **metadata, &block) ⇒ Object
5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
# File 'lib/nrser/rspex/example_group/describe_instance_method.rb', line 5 def describe_instance_method name, **, &block describe( "##{ name }", type: :instance_method, method_name: name, ** ) do if name.is_a? Symbol subject { super().method name } end module_exec &block end end |
#describe_message(*args, &body) ⇒ void Also known as: MESSAGE
Since the block is used for the example group body, if you want to describe a message with a Message#block your need to create the message yourself and pass it as the only argument.
This method returns an undefined value.
Describe a Message. Useful when you have a message that you want to send to many receivers (see #describe_sent_to).
32 33 34 35 36 37 38 39 40 41 42 43 |
# File 'lib/nrser/rspex/example_group/describe_message.rb', line 32 def *args, &body = NRSER::Message.from *args describe_x \ , type: :message, metadata: { message: , }, subject_block: -> { .send_to super() }, &body end |
#describe_method(method, *description, bind_subject: nil, **metadata, &body) ⇒ void Also known as: METHOD
This method returns an undefined value.
Describe a method of the parent subject.
17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/nrser/rspex/example_group/describe_method.rb', line 17 def describe_method method, *description, bind_subject: nil, **, &body case method when Method method_name = method.name subject_block = -> { method } bind_subject = true name_string = NRSER::RSpex::Format.md_code_quote \ "#{ method.receiver }.#{ method.name }" when Symbol, String method_name = method # Due to legacy, we only auto-bind if the name is a symbol # # TODO Get rid of this # bind_subject = method_name.is_a?( Symbol ) if bind_subject.nil? subject_block = if bind_subject -> { super().method method_name } end name_prefix = if self.respond_to?( :metadata ) && self..key?( :constructor_args ) '#' else '.' end method = if self.try( :metadata ) getter = if self..key?( :constructor_args ) :instance_method else :method end target = self.[:class] || self.[:module] if target begin target.public_send getter, method_name rescue nil end end end name_string = NRSER::RSpex::Format.md_code_quote \ "#{ name_prefix }#{ method_name }" else raise NRSER::TypeError.new \ "Expected Method, Symbol or String for `method_name`, found", method_name end # case method_arg # Create the RSpec example group context describe_x \ name_string, NRSER::Meta::Source::Location.new( method ), *description, type: :method, metadata: { **, method_name: method_name, }, bind_subject: bind_subject, subject_block: subject_block, &body end |
#describe_module(mod, bind_subject: true, **metadata, &body) ⇒ Object
6 7 8 9 10 11 12 13 14 15 16 17 |
# File 'lib/nrser/rspex/example_group/describe_module.rb', line 6 def describe_module mod, bind_subject: true, **, &body describe_x \ mod, type: :module, metadata: { module: mod, **, }, bind_subject: bind_subject, subject_block: -> { mod }, &body end |
#describe_response_to(*args, &body) ⇒ void Also known as: describe_return_value
This method returns an undefined value.
Describe the response of the subject to a Message.
Pretty much a short-cut for nesting #describe_method / #describe_called_with. Meh.
18 19 20 21 22 23 24 25 26 27 |
# File 'lib/nrser/rspex/example_group/describe_response_to.rb', line 18 def describe_response_to *args, &body msg = NRSER::Message.from *args # Pass up to {#describe_x} describe_x \ msg, type: :response_to, subject_block: -> { msg.send_to super() }, &body end |
#describe_section(*description, **metadata, &body) ⇒ void Also known as: describe_topic, SECTION
This method returns an undefined value.
Describe a “section”. Just like RSpec.describe except it:
-
Expects a string title.
-
Prepends a little section squiggle Ԥ` to the title so sections are easier to pick out visually.
-
Adds ‘type: :section` metadata.
26 27 28 29 30 31 32 33 |
# File 'lib/nrser/rspex/example_group/describe_section.rb', line 26 def describe_section *description, **, &body # Pass up to {#describe_x} describe_x \ *description, type: :section, metadata: , &body end |
#describe_sent_to(receiver, publicly: true, bind_subject: true, &body) ⇒ void Also known as: sent_to
This method returns an undefined value.
For use when ‘subject` is a Message. Create a new context for the `receiver` where the subject is the result of sending that message to the receiver.
25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
# File 'lib/nrser/rspex/example_group/describe_sent_to.rb', line 25 def describe_sent_to receiver, publicly: true, bind_subject: true, &body mode = if publicly "publicly" else "privately" end describe_x \ receiver, "(#{ mode })", type: :sent_to, bind_subject: bind_subject, subject_block: -> { super().send_to \ unwrap( receiver, context: self ), publicly: publicly }, &body end |
#describe_setup(*description, **metadata, &body) ⇒ void Also known as: setup, SETUP
This method returns an undefined value.
Setup describes what’s going to be done in all child examples.
It’s where you setup your ‘subject`, usually depending on `let` bindings that are provided in the children.
12 13 14 15 16 17 18 |
# File 'lib/nrser/rspex/example_group/describe_setup.rb', line 12 def describe_setup *description, **, &body describe_x \ *description, type: :setup, metadata: , &body end |
#describe_source_file(path, *description, **metadata, &body) ⇒ void
Honestly, now that modules, classes and methods described through RSpex add their source locations, this is not all that useful. But it was there from before that, which is why for the moment it’s still here.
This method returns an undefined value.
Create an example group covering a source file.
Useful for when method implementations are spread out across multiple files but you want to group examples by the source file they’re in.
35 36 37 38 39 40 41 42 43 44 45 46 47 |
# File 'lib/nrser/rspex/example_group/describe_source_file.rb', line 35 def describe_source_file path, *description, **, &body path = path.to_pn describe_x \ path, *description, type: :source_file, metadata: { source_file: path, **, }, &body end |
#describe_spec_file(description: nil, spec_path:, bind_subject: true, **metadata, &body) ⇒ void Also known as: SPEC_FILE
This is totally just a one-off right now… would need to be generalized quite a bit…
-
Extraction of module, class, etc from metadata should be flexible
-
Built description would need to be conditional on what metadata was found.
This method returns an undefined value.
EXPERIMENTAL
Example group helper for use at the top level of each spec file to set a bunch of stuff up and build a helpful description.
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/nrser/rspex/example_group/describe_spec_file.rb', line 51 def describe_spec_file description: nil, spec_path:, bind_subject: true, **, &body chain = [] [ :source_file, :module, :class, :instance, :method, :instance_method, :called_with, :attribute, ].each do |type| if data = .delete( type ) chain << [type, data] end end describe_x_body = if chain.empty? body else -> { dive_x *chain, bind_subject: bind_subject, &body } end describe_x \ NRSER::RSpex.dot_rel_path( spec_path ), *description, type: :spec_file, metadata: , &describe_x_body end |
#describe_subject(subject, **metadata, &body) ⇒ void Also known as: SUBJECT
Experimental - only used in Rash at the moment. I’ve wanted something like this to make binding subject less noisy, but I’m not sure this is exactly it yet…
This method returns an undefined value.
Define a example group binding a subject.
34 35 36 37 38 39 40 41 |
# File 'lib/nrser/rspex/example_group/describe_subject.rb', line 34 def describe_subject subject, **, &body describe_x \ subject, type: :subject, metadata: , subject_block: -> { unwrap subject, context: self }, &body end |
#describe_when(*description, **bindings, &body) ⇒ void Also known as: context_where, _when, WHEN
This method returns an undefined value.
Define a example group with the keyword args as bindings.
19 20 21 22 23 24 25 |
# File 'lib/nrser/rspex/example_group/describe_when.rb', line 19 def describe_when *description, **bindings, &body describe_x \ *description, type: :when, bindings: bindings, &body end |
#describe_x(*description, type:, metadata: {}, bindings: {}, add_binding_desc: true, bind_subject: true, subject_block: nil, &body) ⇒ void Also known as: describe_x_type
This method returns an undefined value.
The core, mostly internal method that all RSpex’s description methods lead back too (or should / will when refactoring is done).
Keyword options are explicitly broken out in this method, versus the sugary ones that call it, so ‘metadata` can be set without restriction (save the `type` key, which is also it’s own keyword here). You can use this method if you want the RSpex functionality but absolutely have to set some metadata key that we use for something else.
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/nrser/rspex/example_group/describe_x.rb', line 52 def describe_x *description, type:, metadata: {}, bindings: {}, add_binding_desc: true, bind_subject: true, subject_block: nil, &body # Check that `metadata` doesn't have a `:type` value too... although we # allow it if's equal to `type` or `nil` 'cause why not I guess? # if .key?( :type ) && [:type] != nil && [:type] != type raise ArgumentError.new binding.erb <<-END `metadata:` keyword argument may not have a `:type` key that conflicts with the `type:` keyword argument. Received: `type`: <%= type.inspect %> `metadata[:type]`: <%= metadata[:type].pretty_inspect %> END end # Add description of the bindings, if we have any and were told to unless bindings.empty? || add_binding_desc == false bindings_desc = NRSER::RSpex::Format.md_code_quote \ bindings.map { |name, value| "#{ name } = #{ value.inspect }" }.join( '; ' ) if description.empty? description = bindings_desc else description << "(" + bindings_desc + ")" end end # Call up to RSpec's `#describe` method describe( NRSER::RSpex::Format.description( *description, type: type ), **, type: type, ) do if subject_block && bind_subject subject &subject_block end # Bind bindings unless bindings.empty? bindings.each { |name, value| # Example-level binding let( name ) { unwrap value, context: self } # Example group-level binding (which may return a {Wrapper} that # of course can not be unwrapped at the group level) define_singleton_method( name ) { value } } end module_exec &body end # describe end |
#dive_x(current, *rest, **kwds, &body) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
# File 'lib/nrser/rspex/example_group/describe_spec_file.rb', line 7 def dive_x current, *rest, **kwds, &body type, data = current method_name = "describe_#{ type }" block = if rest.empty? body else -> { dive_x *rest, &body } end begin public_send method_name, data, **kwds, &block rescue NoMethodError => error pp self.methods raise error end end |