MacSpec 0.3.1

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 (59) hide show
  1. data/.document +5 -0
  2. data/.gitignore +21 -0
  3. data/LICENSE +20 -0
  4. data/README.rdoc +20 -0
  5. data/Rakefile +53 -0
  6. data/lib/mac_spec.rb +59 -0
  7. data/lib/mac_spec/matcher_system.rb +19 -0
  8. data/lib/mac_spec/matcher_system/built_in/change_expectations.rb +36 -0
  9. data/lib/mac_spec/matcher_system/built_in/enumerable_expectations.rb +43 -0
  10. data/lib/mac_spec/matcher_system/built_in/error_expectations.rb +68 -0
  11. data/lib/mac_spec/matcher_system/built_in/operator_expectations.rb +45 -0
  12. data/lib/mac_spec/matcher_system/built_in/truth_expectations.rb +148 -0
  13. data/lib/mac_spec/matcher_system/core/def_matcher.rb +14 -0
  14. data/lib/mac_spec/matcher_system/core/exceptions.rb +7 -0
  15. data/lib/mac_spec/matcher_system/core/expectation_builder.rb +11 -0
  16. data/lib/mac_spec/matcher_system/core/matcher_builder.rb +53 -0
  17. data/lib/mac_spec/matcher_system/core/modals.rb +36 -0
  18. data/lib/mac_spec/mocking_framework.rb +13 -0
  19. data/lib/mac_spec/mocking_framework/extensions/kernel_extension.rb +14 -0
  20. data/lib/mac_spec/mocking_framework/extensions/object_extension.rb +74 -0
  21. data/lib/mac_spec/mocking_framework/message_expectation.rb +127 -0
  22. data/lib/mac_spec/mocking_framework/mock.rb +20 -0
  23. data/lib/mac_spec/testing_framework.rb +13 -0
  24. data/lib/mac_spec/testing_framework/core/functions.rb +26 -0
  25. data/lib/mac_spec/testing_framework/core/kernel_extension.rb +27 -0
  26. data/lib/mac_spec/testing_framework/core/test_case_class_methods.rb +90 -0
  27. data/lib/mac_spec/version.rb +3 -0
  28. data/test/all.rb +6 -0
  29. data/test/mac_spec/matcher_system/built_in/change_expectations_test.rb +68 -0
  30. data/test/mac_spec/matcher_system/built_in/enumerable_expectations_test.rb +91 -0
  31. data/test/mac_spec/matcher_system/built_in/error_expectations_test.rb +144 -0
  32. data/test/mac_spec/matcher_system/built_in/operator_expectations_test.rb +136 -0
  33. data/test/mac_spec/matcher_system/built_in/truth_expectations_test.rb +373 -0
  34. data/test/mac_spec/matcher_system/core/def_matcher_test.rb +100 -0
  35. data/test/mac_spec/matcher_system/core/expectation_builder_test.rb +34 -0
  36. data/test/mac_spec/matcher_system/core/matcher_builder_test.rb +72 -0
  37. data/test/mac_spec/matcher_system/core/modals_test.rb +39 -0
  38. data/test/mac_spec/matcher_system/script.rb +29 -0
  39. data/test/mac_spec/matcher_system/test_helper.rb +2 -0
  40. data/test/mac_spec/mocking_framework/extensions/kernel_extension_test.rb +37 -0
  41. data/test/mac_spec/mocking_framework/extensions/object_extension_test.rb +9 -0
  42. data/test/mac_spec/mocking_framework/message_expectation_test.rb +9 -0
  43. data/test/mac_spec/mocking_framework/mock_test.rb +9 -0
  44. data/test/mac_spec/mocking_framework/regression/mocking_class_methods_test.rb +96 -0
  45. data/test/mac_spec/mocking_framework/regression/negative_expectation_test.rb +33 -0
  46. data/test/mac_spec/mocking_framework/regression/stub_test.rb +19 -0
  47. data/test/mac_spec/mocking_framework/test_helper.rb +1 -0
  48. data/test/mac_spec/test_helper.rb +1 -0
  49. data/test/mac_spec/testing_framework/performance/x_test_performance.rb +125 -0
  50. data/test/mac_spec/testing_framework/regression/before_test.rb +32 -0
  51. data/test/mac_spec/testing_framework/regression/deep_nested_example_groups_test.rb +20 -0
  52. data/test/mac_spec/testing_framework/regression/description_string_test.rb +13 -0
  53. data/test/mac_spec/testing_framework/regression/example_name_test.rb +11 -0
  54. data/test/mac_spec/testing_framework/regression/inherit_not_double_test.rb +39 -0
  55. data/test/mac_spec/testing_framework/regression/surrounding_module_scope_test.rb +31 -0
  56. data/test/mac_spec/testing_framework/regression/testing_functions_test.rb +66 -0
  57. data/test/mac_spec/testing_framework/test_helper.rb +1 -0
  58. data/test/test_helper.rb +1 -0
  59. metadata +150 -0
@@ -0,0 +1,14 @@
1
+ module MacSpec
2
+ module MatcherSystem
3
+ module DefMatcher
4
+ include MacSpec::MatcherSystem::MatcherBuilder
5
+ def def_matcher(matcher_name, &block)
6
+ Kernel.module_eval do
7
+ define_method matcher_name do |*args|
8
+ build_matcher(matcher_name, args, &block)
9
+ end
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,7 @@
1
+ module MacSpec
2
+ module MatcherSystem
3
+ module Exceptions
4
+ class UnsupportedMessageSentToMatcher < StandardError; end
5
+ end
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ module MacSpec
2
+ module MatcherSystem
3
+ module ExpectationBuilder
4
+ def self.build_expectation(match, exp, obj)
5
+ return MacSpec::MatcherSystem::Expectations::OperatorExpectation.new(obj, match) unless exp
6
+
7
+ (exp.matches?(obj) != match) ? exp.fail!(match) : exp.pass!(match)
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,53 @@
1
+ module MacSpec
2
+ module MatcherSystem
3
+ module MatcherBuilder
4
+ def build_matcher(matcher_name=nil, args=[], &block)
5
+ match_block = lambda do |actual, matcher|
6
+ block.call(actual, matcher, args)
7
+ end
8
+ body = lambda do |klass|
9
+ include MacSpec.assertions_module
10
+ @matcher_name = matcher_name.to_s
11
+ def self.matcher_name
12
+ @matcher_name
13
+ end
14
+
15
+ attr_accessor :positive_msg, :negative_msg, :msgs
16
+ alias :positive_failure_message :positive_msg
17
+ alias :positive_failure_message= :positive_msg=
18
+ alias :negative_failure_message :negative_msg
19
+ alias :negative_failure_message= :negative_msg=
20
+ alias :chained_messages :msgs
21
+ attr_reader :matcher_name
22
+ def initialize(match_block, test_case)
23
+ @match_block, @test_case = match_block, test_case
24
+ @matcher_name = self.class.matcher_name
25
+ end
26
+
27
+ def method_missing(id, *args, &block)
28
+ require 'ostruct'
29
+ (self.msgs ||= []) << OpenStruct.new( "name" => id, "args" => args, "block" => block )
30
+ self
31
+ end
32
+
33
+ def matches?(given)
34
+ @positive_msg ||= "Matching with '#{matcher_name}' failed, although it should match."
35
+ @negative_msg ||= "Matching with '#{matcher_name}' passed, although it should_not match."
36
+ @match_block.call(given, self)
37
+ end
38
+
39
+ def fail!(which)
40
+ @test_case.flunk(which ? failure_message : negative_failure_message)
41
+ end
42
+
43
+ def pass!(which)
44
+ @test_case.assert true
45
+ end
46
+ alias_method :failure_message, :positive_msg
47
+ alias_method :negative_failure_message, :negative_msg
48
+ end
49
+ Class.new(&body).new(match_block, self)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,36 @@
1
+ module MacSpec
2
+ module MatcherSystem
3
+ module Modals
4
+ # Tests an expectation against the given object.
5
+ #
6
+ # ==== Examples
7
+ #
8
+ # "hello".should eql("hello")
9
+ # 13.should equal(13)
10
+ # lambda { raise "u r doomed" }.should raise_error
11
+ #
12
+ def should(expectation = nil)
13
+ MacSpec::MatcherSystem::ExpectationBuilder.build_expectation(true, expectation, self)
14
+ end
15
+
16
+ alias :will :should
17
+
18
+ # Tests that an expectation doesn't match the given object.
19
+ #
20
+ # ==== Examples
21
+ #
22
+ # "hello".should_not eql("hi")
23
+ # 41.should_not equal(13)
24
+ # lambda { "savd bai da bell" }.should_not raise_error
25
+ #
26
+ def should_not(expectation = nil)
27
+ MacSpec::MatcherSystem::ExpectationBuilder.build_expectation(false, expectation, self)
28
+ end
29
+
30
+ alias :will_not :should_not
31
+ alias :wont :should_not
32
+ end
33
+ end
34
+ end
35
+
36
+ Object.send(:include, MacSpec::MatcherSystem::Modals)
@@ -0,0 +1,13 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+ require "mocking_framework/message_expectation"
5
+ require "mocking_framework/mock"
6
+ require "mocking_framework/extensions/kernel_extension"
7
+ require "mocking_framework/extensions/object_extension"
8
+
9
+ module MacSpec
10
+ module MockingFramework
11
+ # doc
12
+ end
13
+ end
@@ -0,0 +1,14 @@
1
+ module MacSpec
2
+ module MockingFramework
3
+ module KernelExtension
4
+ def mock(name, options={})
5
+ mock_options = {}
6
+ mock_options[:null_object] = options.delete(:null_object)
7
+ mock_options[:stubs] = options
8
+ MacSpec::MockingFramework::Mock.new(name,mock_options)
9
+ end
10
+ end
11
+ end
12
+ end
13
+
14
+ Kernel.send(:include, MacSpec::MockingFramework::KernelExtension)
@@ -0,0 +1,74 @@
1
+ module MacSpec
2
+ module MockingFramework
3
+ module ObjectExtension
4
+ def should_receive(msg)
5
+ @__macspec__message_expectations ||= []
6
+ options = {
7
+ :receiver => self,
8
+ :positive => true,
9
+ :msg => msg,
10
+ :stub => false
11
+ }
12
+ message_expectation = MacSpec::MockingFramework::MessageExpectation.new(options)
13
+ @__macspec__message_expectations << message_expectation
14
+ return message_expectation
15
+ # @__macspec__mock ||= MacSpec::MockingFramework::Mock.new(self.to_s, :belongs_to => self)
16
+ # __macspec__proxy_service(@__macspec__mock.__add_positive_message_expectation(msg))
17
+ end
18
+
19
+ def should_not_receive(msg)
20
+ @__macspec__message_expectations ||= []
21
+ options = {
22
+ :receiver => self,
23
+ :positive => false,
24
+ :msg => msg,
25
+ :stub => false
26
+ }
27
+ message_expectation = MacSpec::MockingFramework::MessageExpectation.new(options)
28
+ @__macspec__message_expectations << message_expectation
29
+ return message_expectation
30
+ end
31
+
32
+ def stub!(hash)
33
+ @__macspec__message_expectations ||= []
34
+ hash.each do |meth_to_stub, ret_val|
35
+ options = {
36
+ :receiver => self,
37
+ :positive => true,
38
+ :msg => meth_to_stub,
39
+ :stub => true,
40
+ :stub_return_value => ret_val
41
+ }
42
+ message_expectation = MacSpec::MockingFramework::MessageExpectation.new(options)
43
+ @__macspec__message_expectations << message_expectation
44
+ end
45
+ end
46
+
47
+ def __macspec__verify
48
+ begin
49
+ @__macspec__message_expectations && @__macspec__message_expectations.each do |me|
50
+ me && me.verify
51
+ end
52
+ ensure
53
+ __macspec__reset!
54
+ end
55
+ end
56
+
57
+ def __macspec__reset!
58
+ @__macspec__message_expectations && @__macspec__message_expectations.each do |me|
59
+ if respond_to?(me.unique_alias) && respond_to?(me.msg)
60
+ (class<<self;self;end).instance_eval do
61
+ undef_method me.msg
62
+ alias_method me.msg, me.unique_alias
63
+ undef_method me.unique_alias
64
+ end
65
+ else
66
+ end
67
+ end
68
+ @__macspec__message_expectations = nil
69
+ end
70
+ end
71
+ end
72
+ end
73
+
74
+ Object.send(:include, MacSpec::MockingFramework::ObjectExtension)
@@ -0,0 +1,127 @@
1
+ module MacSpec
2
+ module MockingFramework
3
+ class MessageExpectation
4
+ @register = []
5
+ attr_reader :msg, :return_value, :unique_alias
6
+ def initialize(options)
7
+ @receiver = options[:receiver]
8
+ @msg = options[:msg]
9
+ @positive = options[:positive]
10
+ @stub = options[:stub]
11
+ @stub_return_value = options[:stub_return_value]
12
+
13
+ @unique_alias = "__macspec__alias_for_#{@msg}".to_sym
14
+ me = self
15
+ if respond_to?(@msg) && !respond_to?(@unique_alias)
16
+ # todo refactor to singletonclass.instance_eval
17
+ (class<<@receiver;self;end).send(:alias_method, @unique_alias, @msg)
18
+ (class<<@receiver;self;end).send(:define_method, @msg) do |*args|
19
+ received_args = args == [] ? nil : args
20
+ me.received_with_args!(received_args)
21
+ me.return_value_for_args(received_args)
22
+ end
23
+ elsif !respond_to?(@msg) && !respond_to?(@unique_alias)
24
+ (class<<@receiver;self;end).send(:define_method, me.msg) do |*args|
25
+ received_args = args == [] ? nil : args
26
+
27
+ me.received_with_args!(received_args)
28
+ me.return_value_for_args(received_args)
29
+ end
30
+ else
31
+ #
32
+ end
33
+ MessageExpectation.register_for_verification(@receiver)
34
+ @return_value = {}
35
+ @received = {}
36
+ @args_expectation = :__macspec_anyargs
37
+ end
38
+
39
+ def self.register_for_verification(obj)
40
+ @register << obj
41
+ end
42
+
43
+ def self.register
44
+ @register
45
+ end
46
+
47
+ def self.verify
48
+ begin
49
+ @register.uniq.each do |obj|
50
+ obj && obj.__macspec__verify
51
+ end
52
+ ensure
53
+ @register = []
54
+ end
55
+ end
56
+
57
+ def verify
58
+ unless self.stub?
59
+ @return_value.each do |args,value|
60
+ args_string = (args == :__macspec_anyargs) ? "Any Args" : args.inspect
61
+ if (@received[args] && @positive) || (!@received[args] && !@positive)
62
+ MacSpec.assert(true)
63
+ elsif (!@received[args] && @positive)
64
+ received_with_args_string = if !@received.keys.include?(:__macspec_anyargs)
65
+ "not at all."
66
+ else
67
+ @received.delete(:__macspec_anyargs)
68
+ "#{@received.keys}"
69
+ end
70
+
71
+ err_msg = """
72
+ '#{@receiver}' should have received '#{msg}' with '#{args_string}'.
73
+ But received it #{received_with_args_string}
74
+ """
75
+ MacSpec.flunk err_msg
76
+ elsif (@received[args] && !@positive)
77
+ err_msg = "'#{@receiver}' should *not* have received '#{msg}' with '#{args_string}'."
78
+ MacSpec.flunk err_msg
79
+ end
80
+ end
81
+ end
82
+ @return_value = {}
83
+ end
84
+
85
+ def stub?
86
+ @stub
87
+ end
88
+
89
+ def negative?
90
+ !@positive
91
+ end
92
+
93
+ def received_with_args!(args)
94
+ @received[args] = true unless args == nil
95
+ @received[:__macspec_anyargs] = true
96
+ @return_value[:__macspec_anyargs] ||= true
97
+ end
98
+
99
+ def return_value_for_args(args)
100
+ return @stub_return_value if stub?
101
+ args ||= :__macspec_anyargs
102
+ received_args = @return_value.keys
103
+ unless received_args.include?(args) || received_args.include?(:__macspec_anyargs)
104
+ args_string = args == :__macspec_anyargs ? "No Args" : args
105
+ err_msg = "Wrong Argument(s): '#{args_string}' For message '#{msg}'. Receiver: '#{@receiver}'"
106
+ MacSpec.flunk err_msg
107
+ end
108
+ @return_value[args]
109
+ end
110
+
111
+ def with(*args)
112
+ unless stub?
113
+ @args_expectation = args
114
+ @return_value[@args_expectation] = nil
115
+ self
116
+ end
117
+ end
118
+
119
+ def and_return(value)
120
+ unless stub? || negative?
121
+ @return_value[@args_expectation] = value
122
+ self
123
+ end
124
+ end
125
+ end
126
+ end
127
+ end
@@ -0,0 +1,20 @@
1
+ module MacSpec
2
+ module MockingFramework
3
+ class Mock
4
+ def initialize(name, options={})
5
+ (class<<self;self;end).instance_eval do
6
+ if options[:null_object]
7
+ define_method :method_missing do |name, *args, &block|
8
+ Mock.new(:null_object, :null_object => true)
9
+ end
10
+ end
11
+ options[:stubs] && options[:stubs].each do |stub_method, return_value|
12
+ define_method stub_method do |*args|
13
+ return_value
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,13 @@
1
+ $:.unshift(File.dirname(__FILE__)) unless
2
+ $:.include?(File.dirname(__FILE__)) || $:.include?(File.expand_path(File.dirname(__FILE__)))
3
+
4
+
5
+ require "testing_framework/core/test_case_class_methods"
6
+ require "testing_framework/core/kernel_extension"
7
+ require "testing_framework/core/functions"
8
+
9
+ module MacSpec
10
+ module TestingFramework
11
+ # todo doc
12
+ end
13
+ end
@@ -0,0 +1,26 @@
1
+ module MacSpec
2
+ module TestingFramework
3
+ # == Temporary
4
+ # A temporary module that holds functionality
5
+ # that awaits to be refactored to the right place.
6
+ module Functions
7
+
8
+ def self.string?(string)
9
+ string.is_a?(String) ? true : false
10
+ end
11
+
12
+ def self.determine_class_name(name) #:nodoc:
13
+ name.to_s.split(/\W+/).map { |s| s[0..0].upcase + s[1..-1] }.join
14
+ end
15
+
16
+ def self.make_constantizeable(string)
17
+ return string unless self.string?(string)
18
+ string = string.gsub(/[^\w\s]/,"").gsub(/^[\d\s]*/,"")
19
+ raise ArgumentError.new(
20
+ "Invalid argument: #{string}. Must not be empty after removing '\W'-class chars."
21
+ ) if string.gsub(/\s/,"").empty?
22
+ string
23
+ end
24
+ end # Functions
25
+ end # TestingFramework
26
+ end #MacSpec
@@ -0,0 +1,27 @@
1
+
2
+ module Kernel
3
+ def describe(*args, &block)
4
+ super_class = (Hash === args.last && (args.last[:type] || args.last[:testcase])) || MacSpec.test_case_class
5
+ super_class.class_eval {extend MacSpec::TestingFramework::TestCaseClassMethods}
6
+ cls = Class.new(super_class)
7
+ cnst, desc = args
8
+ cnst = MacSpec::TestingFramework::Functions.make_constantizeable(cnst)
9
+ Object.const_set MacSpec::TestingFramework::Functions::determine_class_name(cnst.to_s + "Test"), cls
10
+ cls.desc = String === desc ? desc : cnst.to_s
11
+ if self.class.to_s == "Module"
12
+ orig_block = block
13
+ mod_context = self
14
+ #mods = self.ancestors.select {|m| m.class.to_s == "Module"}
15
+ block = lambda {include mod_context; instance_eval(&orig_block)}
16
+ end
17
+ cls.teardown_chained = lambda {MacSpec::MockingFramework::MessageExpectation.verify}
18
+ cls.macspec_superclass = super_class
19
+ cls.class_eval(&block)
20
+ cls.testcases.each do |testcase|
21
+ for test in cls.all_tests.reject {|t| testcase.own_tests.include?(t)}
22
+ testcase.send(:undef_method, test) if testcase.send(:method_defined?, test)
23
+ end
24
+ end
25
+ end
26
+ private :describe
27
+ end # Kernel