rsanheim-micronaut 0.1.3.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. data/LICENSE +45 -0
  2. data/README +17 -0
  3. data/RSPEC-LICENSE +23 -0
  4. data/Rakefile +83 -0
  5. data/bin/micronaut +4 -0
  6. data/examples/example_helper.rb +36 -0
  7. data/examples/lib/micronaut/behaviour_example.rb +188 -0
  8. data/examples/lib/micronaut/configuration_example.rb +70 -0
  9. data/examples/lib/micronaut/example_example.rb +46 -0
  10. data/examples/lib/micronaut/expectations/extensions/object_example.rb +72 -0
  11. data/examples/lib/micronaut/expectations/fail_with_example.rb +17 -0
  12. data/examples/lib/micronaut/expectations/wrap_expectation_example.rb +31 -0
  13. data/examples/lib/micronaut/formatters/base_formatter_example.rb +107 -0
  14. data/examples/lib/micronaut/formatters/documentation_formatter_example.rb +5 -0
  15. data/examples/lib/micronaut/formatters/progress_formatter_example.rb +74 -0
  16. data/examples/lib/micronaut/kernel_extensions_example.rb +13 -0
  17. data/examples/lib/micronaut/matchers/be_close_example.rb +52 -0
  18. data/examples/lib/micronaut/matchers/be_example.rb +298 -0
  19. data/examples/lib/micronaut/matchers/change_example.rb +360 -0
  20. data/examples/lib/micronaut/matchers/description_generation_example.rb +175 -0
  21. data/examples/lib/micronaut/matchers/eql_example.rb +35 -0
  22. data/examples/lib/micronaut/matchers/equal_example.rb +35 -0
  23. data/examples/lib/micronaut/matchers/handler_example.rb +153 -0
  24. data/examples/lib/micronaut/matchers/has_example.rb +71 -0
  25. data/examples/lib/micronaut/matchers/have_example.rb +575 -0
  26. data/examples/lib/micronaut/matchers/include_example.rb +103 -0
  27. data/examples/lib/micronaut/matchers/match_example.rb +43 -0
  28. data/examples/lib/micronaut/matchers/matcher_methods_example.rb +66 -0
  29. data/examples/lib/micronaut/matchers/operator_matcher_example.rb +189 -0
  30. data/examples/lib/micronaut/matchers/raise_error_example.rb +346 -0
  31. data/examples/lib/micronaut/matchers/respond_to_example.rb +54 -0
  32. data/examples/lib/micronaut/matchers/satisfy_example.rb +36 -0
  33. data/examples/lib/micronaut/matchers/simple_matcher_example.rb +93 -0
  34. data/examples/lib/micronaut/matchers/throw_symbol_example.rb +96 -0
  35. data/examples/lib/micronaut/runner_example.rb +5 -0
  36. data/examples/lib/micronaut/runner_options_example.rb +5 -0
  37. data/examples/lib/micronaut/world_example.rb +102 -0
  38. data/examples/lib/micronaut_example.rb +23 -0
  39. data/examples/resources/example_classes.rb +67 -0
  40. data/lib/autotest/discover.rb +3 -0
  41. data/lib/autotest/micronaut.rb +47 -0
  42. data/lib/micronaut/behaviour.rb +211 -0
  43. data/lib/micronaut/configuration.rb +133 -0
  44. data/lib/micronaut/example.rb +28 -0
  45. data/lib/micronaut/expectations/extensions/object.rb +62 -0
  46. data/lib/micronaut/expectations/extensions/string_and_symbol.rb +19 -0
  47. data/lib/micronaut/expectations/handler.rb +52 -0
  48. data/lib/micronaut/expectations/wrap_expectation.rb +57 -0
  49. data/lib/micronaut/expectations.rb +46 -0
  50. data/lib/micronaut/formatters/base_formatter.rb +82 -0
  51. data/lib/micronaut/formatters/base_text_formatter.rb +148 -0
  52. data/lib/micronaut/formatters/documentation_formatter.rb +62 -0
  53. data/lib/micronaut/formatters/progress_formatter.rb +36 -0
  54. data/lib/micronaut/formatters.rb +12 -0
  55. data/lib/micronaut/kernel_extensions.rb +11 -0
  56. data/lib/micronaut/matchers/be.rb +204 -0
  57. data/lib/micronaut/matchers/be_close.rb +22 -0
  58. data/lib/micronaut/matchers/change.rb +148 -0
  59. data/lib/micronaut/matchers/eql.rb +26 -0
  60. data/lib/micronaut/matchers/equal.rb +26 -0
  61. data/lib/micronaut/matchers/generated_descriptions.rb +36 -0
  62. data/lib/micronaut/matchers/has.rb +19 -0
  63. data/lib/micronaut/matchers/have.rb +153 -0
  64. data/lib/micronaut/matchers/include.rb +80 -0
  65. data/lib/micronaut/matchers/match.rb +22 -0
  66. data/lib/micronaut/matchers/method_missing.rb +9 -0
  67. data/lib/micronaut/matchers/operator_matcher.rb +50 -0
  68. data/lib/micronaut/matchers/raise_error.rb +128 -0
  69. data/lib/micronaut/matchers/respond_to.rb +50 -0
  70. data/lib/micronaut/matchers/satisfy.rb +50 -0
  71. data/lib/micronaut/matchers/simple_matcher.rb +135 -0
  72. data/lib/micronaut/matchers/throw_symbol.rb +108 -0
  73. data/lib/micronaut/matchers.rb +148 -0
  74. data/lib/micronaut/mocking/with_absolutely_nothing.rb +11 -0
  75. data/lib/micronaut/mocking/with_mocha.rb +13 -0
  76. data/lib/micronaut/mocking/with_rr.rb +24 -0
  77. data/lib/micronaut/mocking.rb +7 -0
  78. data/lib/micronaut/runner.rb +57 -0
  79. data/lib/micronaut/runner_options.rb +33 -0
  80. data/lib/micronaut/world.rb +75 -0
  81. data/lib/micronaut.rb +37 -0
  82. metadata +149 -0
@@ -0,0 +1,36 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../../example_helper")
2
+
3
+ describe "should satisfy { block }" do
4
+ it "should pass if block returns true" do
5
+ true.should satisfy { |val| val }
6
+ true.should satisfy do |val|
7
+ val
8
+ end
9
+ end
10
+
11
+ it "should fail if block returns false" do
12
+ lambda {
13
+ false.should satisfy { |val| val }
14
+ }.should fail_with("expected false to satisfy block")
15
+ lambda do
16
+ false.should satisfy do |val|
17
+ val
18
+ end
19
+ end.should fail_with("expected false to satisfy block")
20
+ end
21
+ end
22
+
23
+ describe "should_not satisfy { block }" do
24
+ it "should pass if block returns false" do
25
+ false.should_not satisfy { |val| val }
26
+ false.should_not satisfy do |val|
27
+ val
28
+ end
29
+ end
30
+
31
+ it "should fail if block returns true" do
32
+ lambda {
33
+ true.should_not satisfy { |val| val }
34
+ }.should fail_with("expected true not to satisfy block")
35
+ end
36
+ end
@@ -0,0 +1,93 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../../example_helper")
2
+
3
+ module Micronaut
4
+ module Matchers
5
+ describe SimpleMatcher do
6
+ it "should pass match arg to block" do
7
+ actual = nil
8
+ matcher = simple_matcher("message") do |given| actual = given end
9
+ matcher.matches?("foo")
10
+ actual.should == "foo"
11
+ end
12
+
13
+ it "should provide a stock failure message" do
14
+ matcher = simple_matcher("thing") do end
15
+ matcher.matches?("other")
16
+ matcher.failure_message.should =~ /expected \"thing\" but got \"other\"/
17
+ end
18
+
19
+ it "should provide a stock negative failure message" do
20
+ matcher = simple_matcher("thing") do end
21
+ matcher.matches?("other")
22
+ matcher.negative_failure_message.should =~ /expected not to get \"thing\", but got \"other\"/
23
+ end
24
+
25
+ it "should provide the given description" do
26
+ matcher = simple_matcher("thing") do end
27
+ matcher.description.should =="thing"
28
+ end
29
+
30
+ it "should fail if a wrapped 'should' fails" do
31
+ matcher = simple_matcher("should fail") do
32
+ 2.should == 3
33
+ end
34
+ lambda do
35
+ matcher.matches?("anything").should be_true
36
+ end.should fail_with(/expected: 3/)
37
+ end
38
+ end
39
+
40
+ describe "with arity of 2" do
41
+ it "should provide the matcher so you can access its messages" do
42
+ provided_matcher = nil
43
+ matcher = simple_matcher("thing") do |given, matcher|
44
+ provided_matcher = matcher
45
+ end
46
+ matcher.matches?("anything")
47
+ provided_matcher.should equal(matcher)
48
+ end
49
+
50
+ it "should support a custom failure message" do
51
+ matcher = simple_matcher("thing") do |given, matcher|
52
+ matcher.failure_message = "custom message"
53
+ end
54
+ matcher.matches?("other")
55
+ matcher.failure_message.should == "custom message"
56
+ end
57
+
58
+ it "should complain when asked for a failure message if you don't give it a description or a message" do
59
+ matcher = simple_matcher do |given, matcher| end
60
+ matcher.matches?("other")
61
+ matcher.failure_message.should =~ /No description provided/
62
+ end
63
+
64
+ it "should support a custom negative failure message" do
65
+ matcher = simple_matcher("thing") do |given, matcher|
66
+ matcher.negative_failure_message = "custom message"
67
+ end
68
+ matcher.matches?("other")
69
+ matcher.negative_failure_message.should == "custom message"
70
+ end
71
+
72
+ it "should complain when asked for a negative failure message if you don't give it a description or a message" do
73
+ matcher = simple_matcher do |given, matcher| end
74
+ matcher.matches?("other")
75
+ matcher.negative_failure_message.should =~ /No description provided/
76
+ end
77
+
78
+ it "should support a custom description" do
79
+ matcher = simple_matcher("thing") do |given, matcher|
80
+ matcher.description = "custom message"
81
+ end
82
+ matcher.matches?("description")
83
+ matcher.description.should == "custom message"
84
+ end
85
+
86
+ it "should tell you no description was provided when it doesn't receive one" do
87
+ matcher = simple_matcher do end
88
+ matcher.description.should =~ /No description provided/
89
+ end
90
+ end
91
+
92
+ end
93
+ end
@@ -0,0 +1,96 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../../example_helper")
2
+
3
+ module Micronaut
4
+ module Matchers
5
+ describe ThrowSymbol do
6
+ describe "with no args" do
7
+ before { @matcher = ThrowSymbol.new }
8
+
9
+ it "should match if any Symbol is thrown" do
10
+ @matcher.matches?(lambda{ throw :sym }).should be_true
11
+ end
12
+ it "should match if any Symbol is thrown with an arg" do
13
+ @matcher.matches?(lambda{ throw :sym, "argument" }).should be_true
14
+ end
15
+ it "should not match if no Symbol is thrown" do
16
+ @matcher.matches?(lambda{ }).should be_false
17
+ end
18
+ it "should provide a failure message" do
19
+ @matcher.matches?(lambda{})
20
+ @matcher.failure_message.should == "expected a Symbol but nothing was thrown"
21
+ end
22
+ it "should provide a negative failure message" do
23
+ @matcher.matches?(lambda{ throw :sym})
24
+ @matcher.negative_failure_message.should == "expected no Symbol, got :sym"
25
+ end
26
+ end
27
+
28
+ describe "with a symbol" do
29
+ before { @matcher = ThrowSymbol.new(:sym) }
30
+
31
+ it "should match if correct Symbol is thrown" do
32
+ @matcher.matches?(lambda{ throw :sym }).should be_true
33
+ end
34
+ it "should match if correct Symbol is thrown with an arg" do
35
+ @matcher.matches?(lambda{ throw :sym, "argument" }).should be_true
36
+ end
37
+ it "should not match if no Symbol is thrown" do
38
+ @matcher.matches?(lambda{ }).should be_false
39
+ end
40
+ it "should not match if correct Symbol is thrown" do
41
+ @matcher.matches?(lambda{ throw :other_sym }).should be_false
42
+ end
43
+ it "should provide a failure message when no Symbol is thrown" do
44
+ @matcher.matches?(lambda{})
45
+ @matcher.failure_message.should == "expected :sym but nothing was thrown"
46
+ end
47
+ it "should provide a failure message when wrong Symbol is thrown" do
48
+ @matcher.matches?(lambda{ throw :other_sym })
49
+ @matcher.failure_message.should == "expected :sym, got :other_sym"
50
+ end
51
+ it "should provide a negative failure message" do
52
+ @matcher.matches?(lambda{ throw :sym })
53
+ @matcher.negative_failure_message.should == "expected :sym not to be thrown"
54
+ end
55
+ it "should only match NameErrors raised by uncaught throws" do
56
+ @matcher.matches?(lambda{ sym }).should be_false
57
+ end
58
+ end
59
+
60
+ describe "with a symbol and an arg" do
61
+ before { @matcher = ThrowSymbol.new(:sym, "a") }
62
+
63
+ it "should match if correct Symbol and args are thrown" do
64
+ @matcher.matches?(lambda{ throw :sym, "a" }).should be_true
65
+ end
66
+ it "should not match if nothing is thrown" do
67
+ @matcher.matches?(lambda{ }).should be_false
68
+ end
69
+ it "should not match if other Symbol is thrown" do
70
+ @matcher.matches?(lambda{ throw :other_sym, "a" }).should be_false
71
+ end
72
+ it "should not match if no arg is thrown" do
73
+ @matcher.matches?(lambda{ throw :sym }).should be_false
74
+ end
75
+ it "should not match if wrong arg is thrown" do
76
+ @matcher.matches?(lambda{ throw :sym, "b" }).should be_false
77
+ end
78
+ it "should provide a failure message when no Symbol is thrown" do
79
+ @matcher.matches?(lambda{})
80
+ @matcher.failure_message.should == %q[expected :sym with "a" but nothing was thrown]
81
+ end
82
+ it "should provide a failure message when wrong Symbol is thrown" do
83
+ @matcher.matches?(lambda{ throw :other_sym })
84
+ @matcher.failure_message.should == %q[expected :sym with "a", got :other_sym]
85
+ end
86
+ it "should provide a negative failure message" do
87
+ @matcher.matches?(lambda{ throw :sym })
88
+ @matcher.negative_failure_message.should == %q[expected :sym with "a" not to be thrown]
89
+ end
90
+ it "should only match NameErrors raised by uncaught throws" do
91
+ @matcher.matches?(lambda{ sym }).should be_false
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,5 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../example_helper")
2
+
3
+ describe Micronaut::Runner do
4
+
5
+ end
@@ -0,0 +1,5 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../example_helper")
2
+
3
+ describe Micronaut::RunnerOptions do
4
+
5
+ end
@@ -0,0 +1,102 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../../example_helper")
2
+
3
+ class Bar; end
4
+
5
+ describe Micronaut::World do
6
+
7
+ describe "behaviour groups" do
8
+
9
+ it "should contain all defined behaviour groups" do
10
+ behaviour_group = Micronaut::Behaviour.describe(Bar, 'Empty Behaviour Group') { }
11
+ Micronaut::World.behaviours.should include(behaviour_group)
12
+ remove_last_describe_from_world
13
+ end
14
+
15
+ end
16
+
17
+ describe "find" do
18
+
19
+ before(:all) do
20
+ options_1 = { :foo => 1, :color => 'blue', :feature => 'reporting' }
21
+ options_2 = { :pending => true, :feature => 'reporting' }
22
+ options_3 = { :array => [1,2,3,4], :color => 'blue', :feature => 'weather status' }
23
+ @bg1 = Micronaut::Behaviour.describe(Bar, "find group-1", options_1) { }
24
+ @bg2 = Micronaut::Behaviour.describe(Bar, "find group-2", options_2) { }
25
+ @bg3 = Micronaut::Behaviour.describe(Bar, "find group-3", options_3) { }
26
+ @behaviours = [@bg1, @bg2, @bg3]
27
+ end
28
+
29
+ after(:all) do
30
+ Micronaut::World.behaviours.delete(@bg1)
31
+ Micronaut::World.behaviours.delete(@bg2)
32
+ Micronaut::World.behaviours.delete(@bg3)
33
+ end
34
+
35
+ it "should find no groups when given no search parameters" do
36
+ Micronaut::World.find([]).should == []
37
+ end
38
+
39
+ it "should find three groups when searching for :described_type => Bar" do
40
+ Micronaut::World.find(@behaviours, :described_type => Bar).should == [@bg1, @bg2, @bg3]
41
+ end
42
+
43
+ it "should find one group when searching for :description => 'find group-1'" do
44
+ Micronaut::World.find(@behaviours, :description => 'find group-1').should == [@bg1]
45
+ end
46
+
47
+ it "should find two groups when searching for :description => lambda { |v| v.include?('-1') || v.include?('-3') }" do
48
+ Micronaut::World.find(@behaviours, :description => lambda { |v| v.include?('-1') || v.include?('-3') }).should == [@bg1, @bg3]
49
+ end
50
+
51
+ it "should find three groups when searching for :description => /find group/" do
52
+ Micronaut::World.find(@behaviours, :description => /find group/).should == [@bg1, @bg2, @bg3]
53
+ end
54
+
55
+ it "should find one group when searching for :options => { :foo => 1 }" do
56
+ Micronaut::World.find(@behaviours, :options => { :foo => 1 }).should == [@bg1]
57
+ end
58
+
59
+ it "should find one group when searching for :options => { :pending => true }" do
60
+ Micronaut::World.find(@behaviours, :options => { :pending => true }).should == [@bg2]
61
+ end
62
+
63
+ it "should find one group when searching for :options => { :array => [1,2,3,4] }" do
64
+ Micronaut::World.find(@behaviours, :options => { :array => [1,2,3,4] }).should == [@bg3]
65
+ end
66
+
67
+ it "should find no group when searching for :options => { :array => [4,3,2,1] }" do
68
+ Micronaut::World.find(@behaviours, :options => { :array => [4,3,2,1] }).should be_empty
69
+ end
70
+
71
+ it "should find two groups when searching for :options => { :color => 'blue' }" do
72
+ Micronaut::World.find(@behaviours, :options => { :color => 'blue' }).should == [@bg1, @bg3]
73
+ end
74
+
75
+ it "should find two groups when searching for :options => { :feature => 'reporting' }" do
76
+ Micronaut::World.find(@behaviours, :options => { :feature => 'reporting' }).should == [@bg1, @bg2]
77
+ end
78
+
79
+ end
80
+
81
+ describe "reset" do
82
+
83
+ it "should clear the list of behaviour groups" do
84
+ original_groups = Micronaut::World.behaviours
85
+
86
+ Micronaut::World.behaviours.should_not be_empty
87
+ Micronaut::World.reset
88
+ Micronaut::World.behaviours.should be_empty
89
+
90
+ Micronaut::World.behaviours.concat(original_groups)
91
+ end
92
+
93
+ end
94
+
95
+ describe "filter_behaviours_to_run" do
96
+
97
+ it "does nothing if there are no filters"
98
+ # how do you spec this kind of behavior? It feels like we need to be able to create new instances of Micronaut to properly spec
99
+ # this kind of thing, so we can mock/stub or interrogate state without affecting the actual running instance.
100
+ end
101
+
102
+ end
@@ -0,0 +1,23 @@
1
+ require File.expand_path(File.dirname(__FILE__) + "/../example_helper")
2
+
3
+ describe Micronaut do
4
+
5
+ describe "configuration" do
6
+
7
+ it "should return an instance of Micronaut::Configuration" do
8
+ Micronaut.configuration.should be_an_instance_of(Micronaut::Configuration)
9
+ end
10
+
11
+ end
12
+
13
+ describe "configure" do
14
+
15
+ it "should yield the current configuration" do
16
+ Micronaut.configure do |config|
17
+ config.should == Micronaut.configuration
18
+ end
19
+ end
20
+
21
+ end
22
+
23
+ end
@@ -0,0 +1,67 @@
1
+ # This file contains various classes used by the specs.
2
+ module Micronaut
3
+ module Expectations
4
+ class Person
5
+ attr_reader :name
6
+ def initialize name
7
+ @name = name
8
+ end
9
+ def == other
10
+ return @name == other.name
11
+ end
12
+ end
13
+
14
+ class ClassWithMultiWordPredicate
15
+ def multi_word_predicate?
16
+ true
17
+ end
18
+ end
19
+
20
+ module Helper
21
+ class CollectionWithSizeMethod
22
+ def initialize; @list = []; end
23
+ def size; @list.size; end
24
+ def push(item); @list.push(item); end
25
+ end
26
+
27
+ class CollectionWithLengthMethod
28
+ def initialize; @list = []; end
29
+ def length; @list.size; end
30
+ def push(item); @list.push(item); end
31
+ end
32
+
33
+ class CollectionOwner
34
+ attr_reader :items_in_collection_with_size_method, :items_in_collection_with_length_method
35
+
36
+ def initialize
37
+ @items_in_collection_with_size_method = CollectionWithSizeMethod.new
38
+ @items_in_collection_with_length_method = CollectionWithLengthMethod.new
39
+ end
40
+
41
+ def add_to_collection_with_size_method(item)
42
+ @items_in_collection_with_size_method.push(item)
43
+ end
44
+
45
+ def add_to_collection_with_length_method(item)
46
+ @items_in_collection_with_length_method.push(item)
47
+ end
48
+
49
+ def items_for(arg)
50
+ return [1, 2, 3] if arg == 'a'
51
+ [1]
52
+ end
53
+
54
+ def items
55
+ @items_in_collection_with_size_method
56
+ end
57
+ end
58
+
59
+ class ClassWithUnqueriedPredicate
60
+ attr_accessor :foo
61
+ def initialize(foo)
62
+ @foo = foo
63
+ end
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,3 @@
1
+ Autotest.add_discovery do
2
+ "micronaut" if File.directory?('examples')
3
+ end
@@ -0,0 +1,47 @@
1
+ require 'autotest'
2
+
3
+ Autotest.add_hook :initialize do |at|
4
+ at.clear_mappings
5
+ # watch out: Ruby bug (1.8.6):
6
+ # %r(/) != /\//
7
+ at.add_mapping(%r%^examples/.*_example.rb$%) { |filename, _|
8
+ filename
9
+ }
10
+ at.add_mapping(%r%^lib/(.*)\.rb$%) { |filename, m|
11
+ ["examples/lib/#{m[1]}_example.rb"]
12
+ }
13
+ at.add_mapping(%r%^examples/(example_helper|shared/.*)\.rb$%) {
14
+ at.files_matching %r%^examples/.*_example\.rb$%
15
+ }
16
+ end
17
+
18
+ class MicronautCommandError < StandardError; end
19
+
20
+ class Autotest::Micronaut < Autotest
21
+
22
+ def initialize
23
+ super
24
+ self.failed_results_re = /^\d+\)\n(?:\e\[\d*m)?(?:.*?Error in )?'([^\n]*)'(?: FAILED)?(?:\e\[\d*m)?\n(.*?)\n\n/m
25
+ self.completed_re = /\n(?:\e\[\d*m)?\d* examples?/m
26
+ end
27
+
28
+ def consolidate_failures(failed)
29
+ filters = new_hash_of_arrays
30
+ failed.each do |spec, trace|
31
+ if trace =~ /\n(\.\/)?(.*example\.rb):[\d]+:\Z?/
32
+ filters[$2] << spec
33
+ end
34
+ end
35
+ return filters
36
+ end
37
+
38
+ def make_test_cmd(files_to_test)
39
+ return '' if files_to_test.empty?
40
+
41
+ examples = files_to_test.keys.flatten
42
+
43
+
44
+ "#{ruby} #{examples.join(" ")}"
45
+ end
46
+
47
+ end
@@ -0,0 +1,211 @@
1
+ module Micronaut
2
+ class Behaviour
3
+ include Micronaut::Matchers
4
+
5
+ def self.inherited(klass)
6
+ super
7
+ Micronaut::World.behaviours << klass
8
+ end
9
+
10
+ def self.extended_modules #:nodoc:
11
+ ancestors = class << self; ancestors end
12
+ ancestors.select { |mod| mod.class == Module } - [ Object, Kernel ]
13
+ end
14
+
15
+ def self.befores
16
+ @_befores ||= { :all => [], :each => [] }
17
+ end
18
+
19
+ def self.before_eachs
20
+ befores[:each]
21
+ end
22
+
23
+ def self.before_alls
24
+ befores[:all]
25
+ end
26
+
27
+ def self.before(type=:each, options={}, &block)
28
+ befores[type] << [options, block]
29
+ end
30
+
31
+ def self.afters
32
+ @_afters ||= { :all => [], :each => [] }
33
+ end
34
+
35
+ def self.after_eachs
36
+ afters[:each]
37
+ end
38
+
39
+ def self.after_alls
40
+ afters[:all]
41
+ end
42
+
43
+ def self.after(type=:each, options={}, &block)
44
+ afters[type] << [options, block]
45
+ end
46
+
47
+ def self.it(desc=nil, options={}, &block)
48
+ examples << Micronaut::Example.new(self, desc, options, block)
49
+ end
50
+
51
+ def self.focused(desc=nil, options={}, &block)
52
+ it(desc, options.update(:focused => true), &block)
53
+ end
54
+
55
+ def self.examples
56
+ @_examples ||= []
57
+ end
58
+
59
+ def self.examples_to_run
60
+ @_examples_to_run ||= []
61
+ end
62
+
63
+ def self.set_it_up(*args)
64
+ metadata[:options] = args.last.is_a?(Hash) ? args.pop : {}
65
+ metadata[:described_type] = args.first.is_a?(String) ? self.superclass.described_type : args.shift
66
+ metadata[:description] = args.shift || ''
67
+ metadata[:name] = "#{metadata[:described_type]} #{metadata[:description]}".strip
68
+
69
+ Micronaut.configuration.find_modules(self).each do |include_or_extend, mod, opts|
70
+ if include_or_extend == :extend
71
+ send(:extend, mod) unless extended_modules.include?(mod)
72
+ else
73
+ send(:include, mod) unless included_modules.include?(mod)
74
+ end
75
+ end
76
+ end
77
+
78
+ def self.metadata
79
+ @_metadata ||= {}
80
+ end
81
+
82
+ def self.name
83
+ metadata[:name]
84
+ end
85
+
86
+ def self.described_type
87
+ metadata[:described_type]
88
+ end
89
+
90
+ def self.description
91
+ metadata[:description]
92
+ end
93
+
94
+ def self.options
95
+ metadata[:options]
96
+ end
97
+
98
+ def self.describe(*args, &describe_block)
99
+ raise ArgumentError if args.empty? || describe_block.nil?
100
+ subclass('NestedLevel') do
101
+ set_it_up(*args)
102
+ module_eval(&describe_block)
103
+ end
104
+ end
105
+
106
+ def self.ancestors(superclass_last=false)
107
+ classes = []
108
+ current_class = self
109
+
110
+ while current_class < Micronaut::Behaviour
111
+ superclass_last ? classes << current_class : classes.unshift(current_class)
112
+ current_class = current_class.superclass
113
+ end
114
+
115
+ classes
116
+ end
117
+
118
+ def self.before_ancestors
119
+ @_before_ancestors ||= ancestors
120
+ end
121
+
122
+ def self.after_ancestors
123
+ @_after_ancestors ||= ancestors(true)
124
+ end
125
+
126
+ def self.eval_before_alls(example)
127
+ Micronaut.configuration.find_before_or_after(:before, :all, self).each { |blk| example.instance_eval(&blk) }
128
+
129
+ before_ancestors.each do |ancestor|
130
+ ancestor.before_alls.each { |opts, blk| example.instance_eval(&blk) }
131
+ end
132
+ end
133
+
134
+ def self.eval_before_eachs(example)
135
+ Micronaut.configuration.find_before_or_after(:before, :each, self).each { |blk| example.instance_eval(&blk) }
136
+
137
+ before_ancestors.each do |ancestor|
138
+ ancestor.before_eachs.each { |opts, blk| example.instance_eval(&blk) }
139
+ end
140
+ end
141
+
142
+ def self.eval_after_alls(example)
143
+ Micronaut.configuration.find_before_or_after(:after, :all, self).each { |blk| example.instance_eval(&blk) }
144
+
145
+ after_ancestors.each do |ancestor|
146
+ ancestor.after_alls.each { |opts, blk| example.instance_eval(&blk) }
147
+ end
148
+ end
149
+
150
+ def self.eval_after_eachs(example)
151
+ Micronaut.configuration.find_before_or_after(:after, :each, self).each { |blk| example.instance_eval(&blk) }
152
+
153
+ after_ancestors.each do |ancestor|
154
+ ancestor.after_eachs.each { |opts, blk| example.instance_eval(&blk) }
155
+ end
156
+ end
157
+
158
+ def self.run(reporter)
159
+ return true if examples_to_run.empty?
160
+
161
+ reporter.add_behaviour(self)
162
+
163
+ group = new
164
+ eval_before_alls(group)
165
+ success = true
166
+
167
+ examples_to_run.each do |ex|
168
+ reporter.example_started(ex)
169
+
170
+ execution_error = nil
171
+ begin
172
+ group._setup_mocks
173
+ eval_before_eachs(group)
174
+
175
+ if ex.example_block
176
+ group.instance_eval(&ex.example_block)
177
+ group._verify_mocks
178
+ reporter.example_passed(ex)
179
+ else
180
+ reporter.example_pending(ex, 'Not yet implemented')
181
+ end
182
+ eval_after_eachs(group)
183
+ rescue Exception => e
184
+ reporter.example_failed(ex, e)
185
+ execution_error ||= e
186
+ ensure
187
+ group._teardown_mocks
188
+ end
189
+
190
+ success &= execution_error.nil?
191
+ end
192
+ eval_after_alls(group)
193
+ success
194
+ end
195
+
196
+ def self.subclass(base_name, &body) # :nodoc:
197
+ @_sub_class_count ||= 0
198
+ @_sub_class_count += 1
199
+ klass = Class.new(self)
200
+ class_name = "#{base_name}_#{@_sub_class_count}"
201
+ const_set(class_name, klass)
202
+ klass.instance_eval(&body)
203
+ klass
204
+ end
205
+
206
+ def self.to_s
207
+ self == Micronaut::Behaviour ? 'Micronaut::Behaviour' : name
208
+ end
209
+
210
+ end
211
+ end