diff --git a/src/spectator.cr b/src/spectator.cr index cf21730..7a0b0bd 100644 --- a/src/spectator.cr +++ b/src/spectator.cr @@ -41,12 +41,6 @@ module Spectator include ::Spectator::DSL::StructureDSL # Include the DSL for creating groups, example, and more. include ::Spectator::DSL::ExampleDSL # Mix in methods and macros specifically for example DSL. - # Placeholder initializer. - # This is needed because examples and groups call super in their initializer. - # Those initializers pass the sample values upward through their hierarchy. - def initialize(_sample_values : ::Spectator::Internals::SampleValues) - end - # Pass off the "what" argument and block to `DSL::StructureDSL.describe`. # That method will handle creating a new group for this spec. describe({{what}}) {{block}} diff --git a/src/spectator/dsl/example_factory.cr b/src/spectator/dsl/example_factory.cr index 91ee4b6..6271683 100644 --- a/src/spectator/dsl/example_factory.cr +++ b/src/spectator/dsl/example_factory.cr @@ -7,9 +7,9 @@ module Spectator::DSL end # Constructs a new example instance and returns it. - # The *group* and *sample_values* are passed to `Example#initialize`. - def build(group : ExampleGroup, sample_values : Internals::SampleValues) : Example - @example_type.new(group, sample_values) + # The *group* is passed to `Example#initialize`. + def build(group : ExampleGroup, _sample_values : Internals::SampleValues) : Example + @example_type.new(group) end end end diff --git a/src/spectator/dsl/nested_example_group_builder.cr b/src/spectator/dsl/nested_example_group_builder.cr index a711d74..efee6d1 100644 --- a/src/spectator/dsl/nested_example_group_builder.cr +++ b/src/spectator/dsl/nested_example_group_builder.cr @@ -26,7 +26,7 @@ module Spectator::DSL # The *parent* should be the group that contains this group. # The *sample_values* will be given to all of the examples (and groups) nested in this group. def build(parent : ExampleGroup, sample_values : Internals::SampleValues) : NestedExampleGroup - NestedExampleGroup.new(@what, parent, hooks, conditions).tap do |group| + NestedExampleGroup.new(@what, parent, hooks, conditions, sample_values).tap do |group| # Set the group's children to built versions of the children from this instance. group.children = @children.map do |child| # Build the child and up-cast to prevent type errors. diff --git a/src/spectator/dsl/root_example_group_builder.cr b/src/spectator/dsl/root_example_group_builder.cr index d6df2fd..03b13fb 100644 --- a/src/spectator/dsl/root_example_group_builder.cr +++ b/src/spectator/dsl/root_example_group_builder.cr @@ -6,7 +6,7 @@ module Spectator::DSL # Creates a `RootExampleGroup` which can have instances of `Example` and `ExampleGroup` nested in it. # The *sample_values* will be given to all of the examples (and groups) nested in this group. def build(sample_values : Internals::SampleValues) : RootExampleGroup - RootExampleGroup.new(hooks, conditions).tap do |group| + RootExampleGroup.new(hooks, conditions, sample_values).tap do |group| # Set the group's children to built versions of the children from this instance. group.children = @children.map do |child| # Build the child and up-cast to prevent type errors. diff --git a/src/spectator/dsl/sample_example_group_builder.cr b/src/spectator/dsl/sample_example_group_builder.cr index 62c0746..9f1e144 100644 --- a/src/spectator/dsl/sample_example_group_builder.cr +++ b/src/spectator/dsl/sample_example_group_builder.cr @@ -39,11 +39,11 @@ module Spectator::DSL # The *parent* should be the group that contains this group. # The *sample_values* will be given to all of the examples (and groups) nested in this group. def build(parent : ExampleGroup, sample_values : Internals::SampleValues) : NestedExampleGroup - collection = @collection_builder.call(@collection_type.new(sample_values)) + collection = @collection_builder.call(@collection_type.new) # This creates the container for the sub-groups. # The hooks are defined here, instead of repeating for each sub-group. - NestedExampleGroup.new(@what, parent, hooks, conditions).tap do |group| + NestedExampleGroup.new(@what, parent, hooks, conditions, sample_values).tap do |group| # Set the container group's children to be sub-groups for each item in the collection. group.children = collection.map do |value| # Create a sub-group for each item in the collection. @@ -61,7 +61,7 @@ module Spectator::DSL private def build_sub_group(parent : ExampleGroup, sample_values : Internals::SampleValues, value : T) : NestedExampleGroup # Add the value to sample values for this sub-group. sub_values = sample_values.add(@symbol, @name, value) - NestedExampleGroup.new(value.to_s, parent, ExampleHooks.empty, ExampleConditions.empty).tap do |group| + NestedExampleGroup.new(value.to_s, parent, ExampleHooks.empty, ExampleConditions.empty, sub_values).tap do |group| # Set the sub-group's children to built versions of the children from this instance. group.children = @children.map do |child| # Build the child and up-cast to prevent type errors. diff --git a/src/spectator/dsl/structure_dsl.cr b/src/spectator/dsl/structure_dsl.cr index df9d5e6..a43a378 100644 --- a/src/spectator/dsl/structure_dsl.cr +++ b/src/spectator/dsl/structure_dsl.cr @@ -503,13 +503,6 @@ module Spectator::DSL # The collection could reference a helper method # or anything else in the parent scope. class Sample%sample < {{@type.id}} - # Placeholder initializer. - # This is needed because examples and groups call super in their initializer. - # Those initializers pass the sample values upward through their hierarchy. - def initialize(_sample_values : ::Spectator::Internals::SampleValues) - super - end - # Method that returns an array containing the collection. # This method should be called only once. # The framework stores the collection as an array for a couple of reasons. @@ -543,9 +536,9 @@ module Spectator::DSL end # Initializer to extract current element of the collection from sample values. - def initialize(sample_values : ::Spectator::Internals::SampleValues) + def initialize super - @%wrapper = sample_values.get_wrapper(:%sample) + @%wrapper = ::Spectator::Internals::Harness.current.group.sample_values.get_wrapper(:%sample) end # Start a new example group. @@ -656,9 +649,9 @@ module Spectator::DSL end # Initializer to extract current element of the collection from sample values. - def initialize(sample_values : ::Spectator::Internals::SampleValues) + def initialize super - @%wrapper = sample_values.get_wrapper(:%sample) + @%wrapper = ::Spectator::Internals::Harness.current.group.sample_values.get_wrapper(:%sample) end # Start a new example group. @@ -1576,13 +1569,6 @@ module Spectator::DSL private macro _spectator_test(class_name, run_method_name) # Wrapper class for isolating the test code. class {{class_name.id}} < {{@type.id}} - # Initializer that accepts sample values. - # The sample values are passed upward to the group modules. - # Any module that adds sample values can pull their values from this instance. - def initialize(sample_values : ::Spectator::Internals::SampleValues) - super - end - # Generated method for actually running the test code. def {{run_method_name.id}} {{yield}} @@ -1614,9 +1600,9 @@ module Spectator::DSL # Stores the group the example belongs to # and sample values specific to this instance of the test. # This method's signature must match the one used in `ExampleFactory#build`. - def initialize(group : ::Spectator::ExampleGroup, sample_values : ::Spectator::Internals::SampleValues) + def initialize(group : ::Spectator::ExampleGroup) super - @instance = {{test_class_name.id}}.new(sample_values) + @instance = {{test_class_name.id}}.new end # Retrieves the underlying, wrapped test code. diff --git a/src/spectator/example.cr b/src/spectator/example.cr index d12363e..d8185ef 100644 --- a/src/spectator/example.cr +++ b/src/spectator/example.cr @@ -31,8 +31,7 @@ module Spectator # Creates the base of the example. # The group should be the example group the example belongs to. - # The *sample_values* are passed to the example code. - def initialize(@group, sample_values : Internals::SampleValues) + def initialize(@group) end # Indicates there is only one example to run. diff --git a/src/spectator/example_group.cr b/src/spectator/example_group.cr index 6e25a93..c4708b2 100644 --- a/src/spectator/example_group.cr +++ b/src/spectator/example_group.cr @@ -15,9 +15,11 @@ module Spectator include Enumerable(ExampleComponent) include Iterable(ExampleComponent) + getter sample_values : Internals::SampleValues + # Creates the example group. # The hooks are stored to be triggered later. - def initialize(@hooks : ExampleHooks, @conditions : ExampleConditions) + def initialize(@hooks : ExampleHooks, @conditions : ExampleConditions, @sample_values) @before_all_hooks_run = false @after_all_hooks_run = false end diff --git a/src/spectator/internals/harness.cr b/src/spectator/internals/harness.cr index b9de70b..8f70045 100644 --- a/src/spectator/internals/harness.cr +++ b/src/spectator/internals/harness.cr @@ -34,6 +34,11 @@ module Spectator::Internals # Retrieves the current running example. getter example : Example + # Retrieves the group for the current running example. + def group + example.group + end + # Reports the outcome of an expectation. # An exception will be raised when a failing result is given. def report_expectation(expectation : Expectations::Expectation) : Nil diff --git a/src/spectator/nested_example_group.cr b/src/spectator/nested_example_group.cr index 0a90b86..2bd1e09 100644 --- a/src/spectator/nested_example_group.cr +++ b/src/spectator/nested_example_group.cr @@ -18,8 +18,8 @@ module Spectator # The parent's children must contain this group, # otherwise there may be unexpected behavior. # The *hooks* are stored to be triggered later. - def initialize(@what, @parent, hooks : ExampleHooks, conditions : ExampleConditions) - super(hooks, conditions) + def initialize(@what, @parent, hooks : ExampleHooks, conditions : ExampleConditions, sample_values) + super(hooks, conditions, sample_values) end # Indicates wheter the group references a type.