diff --git a/spec/example_iterator_spec.cr b/spec/example_iterator_spec.cr new file mode 100644 index 0000000..d929321 --- /dev/null +++ b/spec/example_iterator_spec.cr @@ -0,0 +1,205 @@ +require "./spec_helper" + +describe Spectator::ExampleIterator do + describe "#next" do + context "with one example" do + it "returns the example" do + example = PassingExample.create + iterator = Spectator::ExampleIterator.new(example.group) + iterator.next.should eq(example) + end + + it "returns 'stop' after the example" do + example = PassingExample.create + iterator = Spectator::ExampleIterator.new(example.group) + iterator.next # Should return example. + iterator.next.should be_a(Iterator::Stop) + end + end + + context "when empty" do + it "returns 'stop'" do + group = Spectator::RootExampleGroup.new(Spectator::ExampleHooks.empty) + group.children = [] of Spectator::ExampleComponent + iterator = Spectator::ExampleIterator.new(group) + iterator.next.should be_a(Iterator::Stop) + end + end + + context "with one level of examples" do + it "iterates through all examples" do + examples = [] of Spectator::Example + group = Spectator::RootExampleGroup.new(Spectator::ExampleHooks.empty) + group.children = Array(Spectator::ExampleComponent).new(5) do |_| + PassingExample.new(group, Spectator::Internals::SampleValues.empty) + end + iterator = Spectator::ExampleIterator.new(group) + 5.times { examples << iterator.next.as(Spectator::Example) } + examples.should eq(group.children) + end + + it "returns 'stop' at the end" do + group = Spectator::RootExampleGroup.new(Spectator::ExampleHooks.empty) + group.children = Array(Spectator::ExampleComponent).new(5) do |_| + PassingExample.new(group, Spectator::Internals::SampleValues.empty) + end + iterator = Spectator::ExampleIterator.new(group) + 5.times { iterator.next } + iterator.next.should be_a(Iterator::Stop) + end + end + + context "with empty sub-groups" do + context "one level deep" do + it "returns 'stop'" do + group = Spectator::RootExampleGroup.new(Spectator::ExampleHooks.empty) + group.children = Array(Spectator::ExampleComponent).new(5) do |i| + Spectator::NestedExampleGroup.new(i.to_s, group, Spectator::ExampleHooks.empty).tap do |sub_group| + sub_group.children = [] of Spectator::ExampleComponent + end + end + iterator = Spectator::ExampleIterator.new(group) + iterator.next.should be_a(Iterator::Stop) + end + end + + context "multiple levels deep" do + it "returns 'stop'" do + group = Spectator::RootExampleGroup.new(Spectator::ExampleHooks.empty) + group.children = Array(Spectator::ExampleComponent).new(5) do |i| + Spectator::NestedExampleGroup.new(i.to_s, group, Spectator::ExampleHooks.empty).tap do |sub_group| + sub_group.children = Array(Spectator::ExampleComponent).new(5) do |j| + Spectator::NestedExampleGroup.new(j.to_s, group, Spectator::ExampleHooks.empty).tap do |sub_sub_group| + sub_sub_group.children = [] of Spectator::ExampleComponent + end + end + end + end + iterator = Spectator::ExampleIterator.new(group) + iterator.next.should be_a(Iterator::Stop) + end + end + end + + context "with multiple levels of examples" do + it "iterates through all examples" do + actual_examples = [] of Spectator::Example + expected_examples = [] of Spectator::Example + group = Spectator::RootExampleGroup.new(Spectator::ExampleHooks.empty) + group.children = Array(Spectator::ExampleComponent).new(5) do |i| + if i % 2 == 0 + PassingExample.new(group, Spectator::Internals::SampleValues.empty).tap do |example| + expected_examples << example + end + else + Spectator::NestedExampleGroup.new(i.to_s, group, Spectator::ExampleHooks.empty).tap do |sub_group| + sub_group.children = Array(Spectator::ExampleComponent).new(5) do |j| + PassingExample.new(sub_group, Spectator::Internals::SampleValues.empty).tap do |example| + expected_examples << example + end + end + end + end + end + iterator = Spectator::ExampleIterator.new(group) + 13.times { actual_examples << iterator.next.as(Spectator::Example) } + actual_examples.should eq(expected_examples) + end + + it "returns 'stop' at the end" do + group = Spectator::RootExampleGroup.new(Spectator::ExampleHooks.empty) + group.children = Array(Spectator::ExampleComponent).new(5) do |i| + if i % 2 == 0 + PassingExample.new(group, Spectator::Internals::SampleValues.empty) + else + Spectator::NestedExampleGroup.new(i.to_s, group, Spectator::ExampleHooks.empty).tap do |sub_group| + sub_group.children = Array(Spectator::ExampleComponent).new(5) do |j| + PassingExample.new(sub_group, Spectator::Internals::SampleValues.empty) + end + end + end + end + iterator = Spectator::ExampleIterator.new(group) + 13.times { iterator.next } + iterator.next.should be_a(Iterator::Stop) + end + end + + context "with deep nesting" do + # Sorry for this atrocity, + # but it was fun to write. + it "iterates through all examples" do + actual_examples = [] of Spectator::Example + expected_examples = [] of Spectator::Example + group = Spectator::RootExampleGroup.new(Spectator::ExampleHooks.empty) + group.children = Array(Spectator::ExampleComponent).new(5) do |i| + Spectator::NestedExampleGroup.new(i.to_s, group, Spectator::ExampleHooks.empty).tap do |sub_group1| + sub_group1.children = Array(Spectator::ExampleComponent).new(5) do |j| + Spectator::NestedExampleGroup.new(j.to_s, sub_group1, Spectator::ExampleHooks.empty).tap do |sub_group2| + sub_group2.children = Array(Spectator::ExampleComponent).new(5) do |k| + Spectator::NestedExampleGroup.new(k.to_s, sub_group2, Spectator::ExampleHooks.empty).tap do |sub_group3| + sub_group3.children = Array(Spectator::ExampleComponent).new(5) do |_| + PassingExample.new(sub_group3, Spectator::Internals::SampleValues.empty).tap do |example| + expected_examples << example + end + end + end + end + end + end + end + end + iterator = Spectator::ExampleIterator.new(group) + (5 ** 4).times { actual_examples << iterator.next.as(Spectator::Example) } + actual_examples.should eq(expected_examples) + end + + it "returns 'stop' at the end" do + group = Spectator::RootExampleGroup.new(Spectator::ExampleHooks.empty) + group.children = Array(Spectator::ExampleComponent).new(5) do |i| + Spectator::NestedExampleGroup.new(i.to_s, group, Spectator::ExampleHooks.empty).tap do |sub_group1| + sub_group1.children = Array(Spectator::ExampleComponent).new(5) do |j| + Spectator::NestedExampleGroup.new(j.to_s, sub_group1, Spectator::ExampleHooks.empty).tap do |sub_group2| + sub_group2.children = Array(Spectator::ExampleComponent).new(5) do |k| + Spectator::NestedExampleGroup.new(k.to_s, sub_group2, Spectator::ExampleHooks.empty).tap do |sub_group3| + sub_group3.children = Array(Spectator::ExampleComponent).new(5) do |_| + PassingExample.new(sub_group3, Spectator::Internals::SampleValues.empty) + end + end + end + end + end + end + end + iterator = Spectator::ExampleIterator.new(group) + (5 ** 4).times { iterator.next } + iterator.next.should be_a(Iterator::Stop) + end + end + + it "returns 'stop' after the end has been reached" do + example = PassingExample.create + iterator = Spectator::ExampleIterator.new(example.group) + iterator.next # Should return example. + iterator.next # Should return "stop". + iterator.next.should be_a(Iterator::Stop) # Should still return "stop". + end + end + + describe "#rewind" do + it "restarts the iterator" do + example = PassingExample.create + iterator = Spectator::ExampleIterator.new(example.group) + iterator.next + iterator.rewind + iterator.next.should eq(example) + end + + it "can be called before #next" do + example = PassingExample.create + iterator = Spectator::ExampleIterator.new(example.group) + iterator.rewind + iterator.next.should eq(example) + end + end +end