micronaut 0.2.9

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.
Files changed (79) hide show
  1. data/History.txt +15 -0
  2. data/LICENSE +45 -0
  3. data/README.markdown +66 -0
  4. data/RSPEC-LICENSE +23 -0
  5. data/Rakefile +78 -0
  6. data/VERSION.yml +4 -0
  7. data/bin/micronaut +4 -0
  8. data/examples/example_helper.rb +54 -0
  9. data/examples/lib/micronaut/behaviour_example.rb +351 -0
  10. data/examples/lib/micronaut/configuration_example.rb +133 -0
  11. data/examples/lib/micronaut/example_example.rb +67 -0
  12. data/examples/lib/micronaut/expectations/extensions/object_example.rb +146 -0
  13. data/examples/lib/micronaut/expectations/fail_with_example.rb +17 -0
  14. data/examples/lib/micronaut/expectations/wrap_expectation_example.rb +27 -0
  15. data/examples/lib/micronaut/formatters/base_formatter_example.rb +117 -0
  16. data/examples/lib/micronaut/formatters/documentation_formatter_example.rb +5 -0
  17. data/examples/lib/micronaut/formatters/progress_formatter_example.rb +29 -0
  18. data/examples/lib/micronaut/kernel_extensions_example.rb +13 -0
  19. data/examples/lib/micronaut/matchers/be_close_example.rb +52 -0
  20. data/examples/lib/micronaut/matchers/be_example.rb +298 -0
  21. data/examples/lib/micronaut/matchers/change_example.rb +360 -0
  22. data/examples/lib/micronaut/matchers/description_generation_example.rb +175 -0
  23. data/examples/lib/micronaut/matchers/eql_example.rb +35 -0
  24. data/examples/lib/micronaut/matchers/equal_example.rb +35 -0
  25. data/examples/lib/micronaut/matchers/has_example.rb +69 -0
  26. data/examples/lib/micronaut/matchers/have_example.rb +392 -0
  27. data/examples/lib/micronaut/matchers/include_example.rb +103 -0
  28. data/examples/lib/micronaut/matchers/match_example.rb +43 -0
  29. data/examples/lib/micronaut/matchers/matcher_methods_example.rb +78 -0
  30. data/examples/lib/micronaut/matchers/operator_matcher_example.rb +193 -0
  31. data/examples/lib/micronaut/matchers/raise_error_example.rb +348 -0
  32. data/examples/lib/micronaut/matchers/respond_to_example.rb +54 -0
  33. data/examples/lib/micronaut/matchers/satisfy_example.rb +36 -0
  34. data/examples/lib/micronaut/matchers/simple_matcher_example.rb +93 -0
  35. data/examples/lib/micronaut/matchers/throw_symbol_example.rb +125 -0
  36. data/examples/lib/micronaut/mocha_example.rb +29 -0
  37. data/examples/lib/micronaut/runner_example.rb +41 -0
  38. data/examples/lib/micronaut/world_example.rb +98 -0
  39. data/examples/lib/micronaut_example.rb +43 -0
  40. data/examples/resources/example_classes.rb +67 -0
  41. data/lib/micronaut.rb +40 -0
  42. data/lib/micronaut/behaviour.rb +217 -0
  43. data/lib/micronaut/configuration.rb +162 -0
  44. data/lib/micronaut/example.rb +112 -0
  45. data/lib/micronaut/expectations.rb +45 -0
  46. data/lib/micronaut/expectations/extensions/object.rb +92 -0
  47. data/lib/micronaut/expectations/handler.rb +51 -0
  48. data/lib/micronaut/expectations/wrap_expectation.rb +52 -0
  49. data/lib/micronaut/formatters.rb +12 -0
  50. data/lib/micronaut/formatters/base_formatter.rb +127 -0
  51. data/lib/micronaut/formatters/base_text_formatter.rb +139 -0
  52. data/lib/micronaut/formatters/documentation_formatter.rb +78 -0
  53. data/lib/micronaut/formatters/progress_formatter.rb +30 -0
  54. data/lib/micronaut/kernel_extensions.rb +11 -0
  55. data/lib/micronaut/matchers.rb +141 -0
  56. data/lib/micronaut/matchers/be.rb +204 -0
  57. data/lib/micronaut/matchers/be_close.rb +37 -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/mocking/with_absolutely_nothing.rb +11 -0
  74. data/lib/micronaut/mocking/with_mocha.rb +15 -0
  75. data/lib/micronaut/mocking/with_rr.rb +24 -0
  76. data/lib/micronaut/rake_task.rb +84 -0
  77. data/lib/micronaut/runner.rb +60 -0
  78. data/lib/micronaut/world.rb +75 -0
  79. metadata +165 -0
@@ -0,0 +1,112 @@
1
+ module Micronaut
2
+
3
+ class Example
4
+
5
+ attr_reader :behaviour, :description, :metadata, :example_block
6
+
7
+ def initialize(behaviour, desc, options, example_block=nil)
8
+ @behaviour, @description, @options, @example_block = behaviour, desc, options, example_block
9
+ @metadata = @behaviour.metadata.dup
10
+ @metadata[:description] = description
11
+ @metadata[:execution_result] = {}
12
+ @metadata[:caller] = options.delete(:caller)
13
+ if @metadata[:caller]
14
+ @metadata[:file_path] = @metadata[:caller].split(":")[0].strip
15
+ @metadata[:line_number] = @metadata[:caller].split(":")[1].to_i
16
+ end
17
+ @metadata.update(options)
18
+ end
19
+
20
+ def record_results(results={})
21
+ @metadata[:execution_result].update(results)
22
+ end
23
+
24
+ def execution_result
25
+ @metadata[:execution_result]
26
+ end
27
+
28
+ def file_path
29
+ @metadata[:file_path] || behaviour.file_path
30
+ end
31
+
32
+ def run_started
33
+ record_results :started_at => Time.now
34
+ end
35
+
36
+ def run_passed
37
+ run_finished 'passed'
38
+ end
39
+
40
+ def run_pending(message='Not yet implemented')
41
+ run_finished 'pending', :pending_message => message
42
+ end
43
+
44
+ def run_failed(exception)
45
+ run_finished 'failed', :exception_encountered => exception
46
+ end
47
+
48
+ def run_finished(status, results={})
49
+ record_results results.update(:status => status)
50
+ finish_time = Time.now
51
+ record_results :finished_at => finish_time, :run_time => (finish_time - execution_result[:started_at])
52
+ Micronaut.configuration.formatter.example_finished(self)
53
+ end
54
+
55
+ def run_before_each
56
+ @behaviour_instance._setup_mocks if @behaviour_instance.respond_to?(:_setup_mocks)
57
+ @behaviour.eval_before_eachs(@behaviour_instance)
58
+ end
59
+
60
+ def run_after_each
61
+ @behaviour.eval_after_eachs(@behaviour_instance)
62
+ @behaviour_instance._verify_mocks if @behaviour_instance.respond_to?(:_verify_mocks)
63
+ ensure
64
+ @behaviour_instance._teardown_mocks if @behaviour_instance.respond_to?(:_teardown_mocks)
65
+ end
66
+
67
+ def run(behaviour_instance)
68
+ @behaviour_instance = behaviour_instance
69
+ @behaviour_instance.running_example = self
70
+
71
+ run_started
72
+
73
+ all_systems_nominal = true
74
+ exception_encountered = nil
75
+
76
+ begin
77
+ run_before_each
78
+ @behaviour_instance.instance_eval(&example_block) if example_block
79
+ rescue Exception => e
80
+ exception_encountered = e
81
+ all_systems_nominal = false
82
+ end
83
+
84
+ begin
85
+ run_after_each
86
+ rescue Exception => e
87
+ exception_encountered ||= e
88
+ all_systems_nominal = false
89
+ ensure
90
+ @behaviour_instance.running_example = nil
91
+ end
92
+
93
+ if exception_encountered
94
+ run_failed(exception_encountered)
95
+ else
96
+ example_block ? run_passed : run_pending
97
+ end
98
+
99
+ all_systems_nominal
100
+ end
101
+
102
+ def inspect
103
+ "#{@metadata[:behaviour][:name]} - #{@metadata[:description]}"
104
+ end
105
+
106
+ def to_s
107
+ inspect
108
+ end
109
+
110
+ end
111
+
112
+ end
@@ -0,0 +1,45 @@
1
+ require 'micronaut/matchers'
2
+ require 'micronaut/expectations/extensions/object'
3
+ require 'micronaut/expectations/handler'
4
+ require 'micronaut/expectations/wrap_expectation'
5
+
6
+ module Micronaut
7
+
8
+ # Micronaut::Expectations lets you set expectations on your objects.
9
+ #
10
+ # result.should == 37
11
+ # team.should have(11).players_on_the_field
12
+ #
13
+ # == How Expectations work.
14
+ #
15
+ # Micronaut::Expectations adds two methods to Object:
16
+ #
17
+ # should(matcher=nil)
18
+ # should_not(matcher=nil)
19
+ #
20
+ # Both methods take an optional Expression Matcher (See Micronaut::Matchers).
21
+ #
22
+ # When +should+ receives an Expression Matcher, it calls <tt>matches?(self)</tt>. If
23
+ # it returns +true+, the spec passes and execution continues. If it returns
24
+ # +false+, then the spec fails with the message returned by <tt>matcher.failure_message</tt>.
25
+ #
26
+ # Similarly, when +should_not+ receives a matcher, it calls <tt>matches?(self)</tt>. If
27
+ # it returns +false+, the spec passes and execution continues. If it returns
28
+ # +true+, then the spec fails with the message returned by <tt>matcher.negative_failure_message</tt>.
29
+ #
30
+ # Micronaut ships with a standard set of useful matchers, and writing your own
31
+ # matchers is quite simple. See Micronaut::Matchers for details.
32
+ module Expectations
33
+
34
+ class ExpectationNotMetError < ::StandardError; end
35
+
36
+ def self.fail_with(message, expected=nil, target=nil) # :nodoc:
37
+ if Array === message && message.length == 3
38
+ message, expected, target = message[0], message[1], message[2]
39
+ end
40
+ Kernel::raise(Micronaut::Expectations::ExpectationNotMetError.new(message))
41
+ end
42
+
43
+ end
44
+
45
+ end
@@ -0,0 +1,92 @@
1
+ module Micronaut
2
+ module Expectations
3
+ class InvalidMatcherError < ArgumentError; end
4
+
5
+ module ObjectExpectations
6
+ # :call-seq:
7
+ # should(matcher)
8
+ # should == expected
9
+ # should === expected
10
+ # should =~ expected
11
+ #
12
+ # receiver.should(matcher)
13
+ # => Passes if matcher.matches?(receiver)
14
+ #
15
+ # receiver.should == expected #any value
16
+ # => Passes if (receiver == expected)
17
+ #
18
+ # receiver.should === expected #any value
19
+ # => Passes if (receiver === expected)
20
+ #
21
+ # receiver.should =~ regexp
22
+ # => Passes if (receiver =~ regexp)
23
+ #
24
+ # See Micronaut::Matchers for more information about matchers
25
+ #
26
+ # == Warning
27
+ # NOTE that this does NOT support receiver.should != expected.
28
+ # Instead, use receiver.should_not == expected
29
+ def should(matcher=nil, &block)
30
+ ::Micronaut::Matchers.last_should = "should"
31
+ return ::Micronaut::Matchers::PositiveOperatorMatcher.new(self) if matcher.nil?
32
+
33
+ unless matcher.respond_to?(:matches?)
34
+ raise InvalidMatcherError, "Expected a matcher, got #{matcher.inspect}."
35
+ end
36
+
37
+ match_found = matcher.matches?(self, &block)
38
+ ::Micronaut::Matchers.last_matcher = matcher
39
+
40
+ ::Micronaut::Expectations.fail_with(matcher.failure_message) unless match_found
41
+ match_found
42
+ end
43
+
44
+ # :call-seq:
45
+ # should_not(matcher)
46
+ # should_not == expected
47
+ # should_not === expected
48
+ # should_not =~ expected
49
+ #
50
+ # receiver.should_not(matcher)
51
+ # => Passes unless matcher.matches?(receiver)
52
+ #
53
+ # receiver.should_not == expected
54
+ # => Passes unless (receiver == expected)
55
+ #
56
+ # receiver.should_not === expected
57
+ # => Passes unless (receiver === expected)
58
+ #
59
+ # receiver.should_not =~ regexp
60
+ # => Passes unless (receiver =~ regexp)
61
+ #
62
+ # See Micronaut::Matchers for more information about matchers
63
+ def should_not(matcher=nil, &block)
64
+ ::Micronaut::Matchers.last_should = "should not"
65
+ return ::Micronaut::Matchers::NegativeOperatorMatcher.new(self) if matcher.nil?
66
+
67
+ unless matcher.respond_to?(:matches?)
68
+ raise InvalidMatcherError, "Expected a matcher, got #{matcher.inspect}."
69
+ end
70
+
71
+ unless matcher.respond_to?(:negative_failure_message)
72
+ ::Micronaut::Expectations.fail_with(
73
+ <<-EOF
74
+ Matcher does not support should_not.
75
+ See Micronaut::Matchers for more information about matchers.
76
+ EOF
77
+ )
78
+ end
79
+ match_found = matcher.matches?(self, &block)
80
+ ::Micronaut::Matchers.last_matcher = matcher
81
+
82
+ ::Micronaut::Expectations.fail_with(matcher.negative_failure_message) if match_found
83
+ match_found
84
+ end
85
+
86
+ end
87
+ end
88
+ end
89
+
90
+ class Object
91
+ include Micronaut::Expectations::ObjectExpectations
92
+ end
@@ -0,0 +1,51 @@
1
+ module Micronaut
2
+ module Expectations
3
+
4
+
5
+ # class ExpectationMatcherHandler
6
+ #
7
+ # def self.handle_matcher(actual, matcher, &block)
8
+ # ::Micronaut::Matchers.last_should = "should"
9
+ # return Micronaut::Matchers::PositiveOperatorMatcher.new(actual) if matcher.nil?
10
+ #
11
+ # unless matcher.respond_to?(:matches?)
12
+ # raise InvalidMatcherError, "Expected a matcher, got #{matcher.inspect}."
13
+ # end
14
+ #
15
+ # match = matcher.matches?(actual, &block)
16
+ # ::Micronaut::Matchers.last_matcher = matcher
17
+ # Micronaut::Expectations.fail_with(matcher.failure_message) unless match
18
+ # match
19
+ # end
20
+ #
21
+ # end
22
+
23
+ # class NegativeExpectationMatcherHandler
24
+ #
25
+ # def self.handle_matcher(actual, matcher, &block)
26
+ # ::Micronaut::Matchers.last_should = "should not"
27
+ # return Micronaut::Matchers::NegativeOperatorMatcher.new(actual) if matcher.nil?
28
+ #
29
+ # unless matcher.respond_to?(:matches?)
30
+ # raise InvalidMatcherError, "Expected a matcher, got #{matcher.inspect}."
31
+ # end
32
+ #
33
+ # unless matcher.respond_to?(:negative_failure_message)
34
+ # Micronaut::Expectations.fail_with(
35
+ # <<-EOF
36
+ # Matcher does not support should_not.
37
+ # See Micronaut::Matchers for more information
38
+ # about matchers.
39
+ # EOF
40
+ # )
41
+ # end
42
+ # match = matcher.matches?(actual, &block)
43
+ # ::Micronaut::Matchers.last_matcher = matcher
44
+ # Micronaut::Expectations.fail_with(matcher.negative_failure_message) if match
45
+ # match
46
+ # end
47
+
48
+ # end
49
+
50
+ end
51
+ end
@@ -0,0 +1,52 @@
1
+ module Micronaut
2
+ module Matchers
3
+
4
+ # wraps an expectation in a block that will return true if the
5
+ # expectation passes and false if it fails (without bubbling up
6
+ # the failure).
7
+ #
8
+ # This is intended to be used in the context of a simple matcher,
9
+ # and is especially useful for wrapping multiple expectations or
10
+ # one or more assertions from test/unit extensions when running
11
+ # with test/unit.
12
+ #
13
+ # == Examples
14
+ #
15
+ # def eat_cheese(cheese)
16
+ # simple_matcher do |mouse, matcher|
17
+ # matcher.negative_failure_message = "expected #{mouse} not to eat cheese"
18
+ # wrap_expectation do |matcher|
19
+ # assert_eats_cheese(mouse)
20
+ # end
21
+ # end
22
+ # end
23
+ #
24
+ # describe Mouse do
25
+ # it "eats cheese" do
26
+ # Mouse.new.should eat_cheese
27
+ # end
28
+ # end
29
+ #
30
+ # The other benefit you get is that you can use the negative version
31
+ # of the matcher:
32
+ #
33
+ # describe Cat do
34
+ # it "does not eat cheese" do
35
+ # Cat.new.should_not eat_cheese
36
+ # end
37
+ # end
38
+ #
39
+ # So in the event there is no assert_does_not_eat_cheese available,
40
+ # you're all set!
41
+ def wrap_expectation(matcher, &block)
42
+ begin
43
+ block.call(matcher)
44
+ return true
45
+ rescue Exception => e
46
+ matcher.failure_message = e.message
47
+ return false
48
+ end
49
+ end
50
+
51
+ end
52
+ end
@@ -0,0 +1,12 @@
1
+ require 'micronaut/formatters/base_formatter'
2
+ require 'micronaut/formatters/base_text_formatter'
3
+ require 'micronaut/formatters/documentation_formatter'
4
+ require 'micronaut/formatters/progress_formatter'
5
+
6
+ module Micronaut
7
+
8
+ module Formatters
9
+
10
+ end
11
+
12
+ end
@@ -0,0 +1,127 @@
1
+ module Micronaut
2
+ module Formatters
3
+
4
+ class BaseFormatter
5
+ attr_accessor :behaviour
6
+ attr_reader :example_count, :duration, :examples
7
+
8
+ def initialize
9
+ @example_count = 0
10
+ @examples = []
11
+ @behaviour = nil
12
+ end
13
+
14
+ def configuration
15
+ Micronaut.configuration
16
+ end
17
+
18
+ def output
19
+ Micronaut.configuration.output
20
+ end
21
+
22
+ def trace(&blk)
23
+ Micronaut.configuration.trace(trace_override_flag, &blk)
24
+ end
25
+
26
+ # Allow setting trace at the behaviour level as well globally
27
+ def trace_override_flag
28
+ behaviour && behaviour.metadata[:trace]
29
+ end
30
+
31
+ def profile_examples?
32
+ Micronaut.configuration.profile_examples
33
+ end
34
+
35
+ def color_enabled?
36
+ configuration.color_enabled?
37
+ end
38
+
39
+ def pending_examples
40
+ @pending_examples ||= ::Micronaut.world.find(examples, :execution_result => { :status => 'pending' })
41
+ end
42
+
43
+ def failed_examples
44
+ @failed_examples ||= ::Micronaut.world.find(examples, :execution_result => { :status => 'failed' })
45
+ end
46
+
47
+ # This method is invoked before any examples are run, right after
48
+ # they have all been collected. This can be useful for special
49
+ # formatters that need to provide progress on feedback (graphical ones)
50
+ #
51
+ # This method will only be invoked once, and the next one to be invoked
52
+ # is #add_behaviour
53
+ def start(example_count)
54
+ @example_count = example_count
55
+ end
56
+
57
+ def example_finished(example)
58
+ examples << example
59
+ end
60
+
61
+ # This method is invoked at the beginning of the execution of each behaviour.
62
+ # +behaviour+ is the behaviour.
63
+ #
64
+ # The next method to be invoked after this is #example_failed or #example_finished
65
+ def add_behaviour(behaviour)
66
+ @behaviour = behaviour
67
+ end
68
+
69
+ # This method is invoked after all of the examples have executed. The next method
70
+ # to be invoked after this one is #dump_failure (once for each failed example),
71
+ def start_dump(duration)
72
+ @duration = duration
73
+ end
74
+
75
+ # Dumps detailed information about each example failure.
76
+ def dump_failures
77
+ end
78
+
79
+ # This method is invoked after the dumping of examples and failures.
80
+ def dump_summary
81
+ end
82
+
83
+ # This gets invoked after the summary if option is set to do so.
84
+ def dump_pending
85
+ end
86
+
87
+ # This method is invoked at the very end. Allows the formatter to clean up, like closing open streams.
88
+ def close
89
+ end
90
+
91
+ def format_backtrace(backtrace, example)
92
+ return "" unless backtrace
93
+ return backtrace if example.metadata[:full_backtrace] == true
94
+
95
+ cleansed = backtrace.select { |line| backtrace_line(line) }
96
+ # Kick the describe stack info off the list, just keep the line the problem happened on from that file
97
+ # cleansed = [cleansed.detect { |line| line.split(':').first == example.metadata[:caller].split(':').first }] if cleansed.size > 1
98
+ cleansed.empty? ? backtrace : cleansed
99
+ end
100
+
101
+ protected
102
+
103
+ def backtrace_line(line)
104
+ return nil if configuration.cleaned_from_backtrace?(line)
105
+ line.sub!(/\A([^:]+:\d+)$/, '\\1')
106
+ return nil if line == '-e:1'
107
+ line
108
+ end
109
+
110
+ def read_failed_line(exception, example)
111
+ original_file = example.file_path.to_s.downcase
112
+ matching_line = exception.backtrace.detect { |line| line.split(':').first.downcase == original_file.downcase }
113
+
114
+ return "Unable to find matching line from backtrace" if matching_line.nil?
115
+
116
+ file_path, line_number = matching_line.split(':')
117
+ if File.exist?(file_path)
118
+ open(file_path, 'r') { |f| f.readlines[line_number.to_i - 1] }
119
+ else
120
+ "Unable to find #{file_path} to read failed line"
121
+ end
122
+ end
123
+
124
+ end
125
+
126
+ end
127
+ end