quarry 0.3.0

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 (112) hide show
  1. data/CHANGES +6 -0
  2. data/COPYING +344 -0
  3. data/MANIFEST +151 -0
  4. data/METADATA +22 -0
  5. data/NEWS +8 -0
  6. data/README +75 -0
  7. data/VERSION +1 -0
  8. data/bin/rubybreak +3 -0
  9. data/bin/xact-ruby +6 -0
  10. data/demo/spec/demo_check.rb +21 -0
  11. data/demo/spec/demo_outline.rb +25 -0
  12. data/demo/test/demo_run.rb +21 -0
  13. data/doc/manual.html2 +1416 -0
  14. data/doc/rdoc/classes/Assertion.html +101 -0
  15. data/doc/rdoc/classes/Assertion/False.html +132 -0
  16. data/doc/rdoc/classes/Assertion/True.html +137 -0
  17. data/doc/rdoc/classes/Kernel.html +86 -0
  18. data/doc/rdoc/classes/Method.html +137 -0
  19. data/doc/rdoc/classes/Module.html +165 -0
  20. data/doc/rdoc/classes/Object.html +154 -0
  21. data/doc/rdoc/classes/Quarry.html +177 -0
  22. data/doc/rdoc/classes/Quarry/Design.html +170 -0
  23. data/doc/rdoc/classes/Quarry/Design/Specification.html +265 -0
  24. data/doc/rdoc/classes/Quarry/Design/Specification/Context.html +174 -0
  25. data/doc/rdoc/classes/Quarry/MethodProbe.html +267 -0
  26. data/doc/rdoc/classes/Quarry/Mock.html +89 -0
  27. data/doc/rdoc/classes/Quarry/Mock/Object.html +276 -0
  28. data/doc/rdoc/created.rid +1 -0
  29. data/doc/rdoc/files/CHANGES.html +100 -0
  30. data/doc/rdoc/files/COPYING.html +457 -0
  31. data/doc/rdoc/files/MANIFEST.html +630 -0
  32. data/doc/rdoc/files/METADATA.html +92 -0
  33. data/doc/rdoc/files/NEWS.html +99 -0
  34. data/doc/rdoc/files/README.html +171 -0
  35. data/doc/rdoc/files/VERSION.html +96 -0
  36. data/doc/rdoc/files/bin/rubybreak.html +96 -0
  37. data/doc/rdoc/files/bin/xact-ruby.html +92 -0
  38. data/doc/rdoc/files/lib/quarry/assert/must_rb.html +96 -0
  39. data/doc/rdoc/files/lib/quarry/assert/should_rb.html +96 -0
  40. data/doc/rdoc/files/lib/quarry/assertion_rb.html +96 -0
  41. data/doc/rdoc/files/lib/quarry/breakout_rb.html +144 -0
  42. data/doc/rdoc/files/lib/quarry/design/spec_rb.html +100 -0
  43. data/doc/rdoc/files/lib/quarry/document_rb.html +92 -0
  44. data/doc/rdoc/files/lib/quarry/loadmonitor_rb.html +92 -0
  45. data/doc/rdoc/files/lib/quarry/methodprobe_rb.html +111 -0
  46. data/doc/rdoc/files/lib/quarry/mock/object_rb.html +123 -0
  47. data/doc/rdoc/files/lib/quarry/mockery_rb.html +115 -0
  48. data/doc/rdoc/fr_class_index.html +60 -0
  49. data/doc/rdoc/fr_file_index.html +65 -0
  50. data/doc/rdoc/fr_method_index.html +77 -0
  51. data/doc/rdoc/index.html +26 -0
  52. data/doc/rdoc/rdoc-style.css +175 -0
  53. data/doc/ri/Assertion/False/assert-i.yaml +10 -0
  54. data/doc/ri/Assertion/False/cdesc-False.yaml +19 -0
  55. data/doc/ri/Assertion/False/message-i.yaml +10 -0
  56. data/doc/ri/Assertion/True/assert-i.yaml +11 -0
  57. data/doc/ri/Assertion/True/cdesc-True.yaml +24 -0
  58. data/doc/ri/Assertion/True/message-c.yaml +11 -0
  59. data/doc/ri/Assertion/True/message-i.yaml +11 -0
  60. data/doc/ri/Assertion/True/method_missing-i.yaml +11 -0
  61. data/doc/ri/Assertion/True/new-c.yaml +11 -0
  62. data/doc/ri/Assertion/cdesc-Assertion.yaml +17 -0
  63. data/doc/ri/Kernel/cdesc-Kernel.yaml +15 -0
  64. data/doc/ri/Method/cdesc-Method.yaml +18 -0
  65. data/doc/ri/Method/migration-i.yaml +12 -0
  66. data/doc/ri/Method/signature-i.yaml +12 -0
  67. data/doc/ri/Module/cdesc-Module.yaml +21 -0
  68. data/doc/ri/Module/doc-i.yaml +16 -0
  69. data/doc/ri/Module/method_added-i.yaml +10 -0
  70. data/doc/ri/Object/assert%21-i.yaml +14 -0
  71. data/doc/ri/Object/assert-i.yaml +14 -0
  72. data/doc/ri/Object/cdesc-Object.yaml +20 -0
  73. data/doc/ri/Quarry/Design/Specification/Context/after-i.yaml +10 -0
  74. data/doc/ri/Quarry/Design/Specification/Context/before-i.yaml +10 -0
  75. data/doc/ri/Quarry/Design/Specification/Context/cdesc-Context.yaml +24 -0
  76. data/doc/ri/Quarry/Design/Specification/Context/method_missing-i.yaml +10 -0
  77. data/doc/ri/Quarry/Design/Specification/Context/specifications-i.yaml +10 -0
  78. data/doc/ri/Quarry/Design/Specification/cdesc-Specification.yaml +44 -0
  79. data/doc/ri/Quarry/Design/Specification/check-i.yaml +12 -0
  80. data/doc/ri/Quarry/Design/Specification/new-c.yaml +12 -0
  81. data/doc/ri/Quarry/Design/Specification/outline-i.yaml +12 -0
  82. data/doc/ri/Quarry/Design/cdesc-Design.yaml +22 -0
  83. data/doc/ri/Quarry/Design/check-c.yaml +12 -0
  84. data/doc/ri/Quarry/Design/outline-c.yaml +10 -0
  85. data/doc/ri/Quarry/Design/specification-c.yaml +10 -0
  86. data/doc/ri/Quarry/Design/specifications-c.yaml +10 -0
  87. data/doc/ri/Quarry/MethodProbe/cdesc-MethodProbe.yaml +46 -0
  88. data/doc/ri/Quarry/MethodProbe/duckcall-c.yaml +10 -0
  89. data/doc/ri/Quarry/MethodProbe/initialize_copy-i.yaml +10 -0
  90. data/doc/ri/Quarry/MethodProbe/method_missing-i.yaml +10 -0
  91. data/doc/ri/Quarry/MethodProbe/new-c.yaml +10 -0
  92. data/doc/ri/Quarry/Mock/Object/cdesc-Object.yaml +52 -0
  93. data/doc/ri/Quarry/Mock/Object/echo-c.yaml +12 -0
  94. data/doc/ri/Quarry/Mock/Object/keys-c.yaml +12 -0
  95. data/doc/ri/Quarry/Mock/Object/mock-c.yaml +12 -0
  96. data/doc/ri/Quarry/Mock/Object/mocks-c.yaml +10 -0
  97. data/doc/ri/Quarry/Mock/Object/spin-c.yaml +12 -0
  98. data/doc/ri/Quarry/Mock/cdesc-Mock.yaml +15 -0
  99. data/doc/ri/Quarry/Mockery-i.yaml +12 -0
  100. data/doc/ri/Quarry/cdesc-Quarry.yaml +17 -0
  101. data/doc/ri/created.rid +1 -0
  102. data/lib/quarry/assert/must.rb +8 -0
  103. data/lib/quarry/assert/should.rb +9 -0
  104. data/lib/quarry/assertion.rb +95 -0
  105. data/lib/quarry/breakout.rb +45 -0
  106. data/lib/quarry/design/spec.rb +197 -0
  107. data/lib/quarry/document.rb +35 -0
  108. data/lib/quarry/loadmonitor.rb +14 -0
  109. data/lib/quarry/methodprobe.rb +216 -0
  110. data/lib/quarry/mock/object.rb +169 -0
  111. data/lib/quarry/mockery.rb +85 -0
  112. metadata +214 -0
@@ -0,0 +1,35 @@
1
+ $_doc = []
2
+
3
+
4
+ class Module
5
+
6
+ attr :docs
7
+
8
+ # The idea here is to have dynamic docs.
9
+ #
10
+ # doc "X does such and such"
11
+ # doc "it is very powerful"
12
+ # class X
13
+ # doc "f does such and such"
14
+ # doc "it is where the power lies"
15
+ # def f
16
+ # ...
17
+ # end
18
+ # end
19
+ #
20
+ # One of the great things about doc, is that
21
+ # it can be used to "inherit" documentation.
22
+
23
+ def doc(str)
24
+ $_doc << string
25
+ end
26
+
27
+ def method_added(meth)
28
+ @docs ||= {}
29
+ @docs[self, meth] << $_doc
30
+ $_doc.clear
31
+ nil
32
+ end
33
+
34
+ end
35
+
@@ -0,0 +1,14 @@
1
+ BEGIN {
2
+ module Kernel
3
+ h = Hash.new
4
+ define_method(:requiree) do
5
+ h
6
+ end
7
+
8
+ r = method :require
9
+ define_method(:require) do |a|
10
+ r.call a
11
+ h[a] = caller
12
+ end
13
+ end
14
+ }
@@ -0,0 +1,216 @@
1
+ # = methodprobe.rb
2
+ #
3
+ # == Copyright (c) 2004 Thomas Sawyer
4
+ #
5
+ # Ruby License
6
+ #
7
+ # This module is free software. You may use, modify, and/or redistribute this
8
+ # software under the same terms as Ruby.
9
+ #
10
+ # This program is distributed in the hope that it will be useful, but WITHOUT
11
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12
+ # FOR A PARTICULAR PURPOSE.
13
+ #
14
+ # == Author(s)
15
+ #
16
+ # * Thomas Sawyer
17
+
18
+ # Author:: Thomas Sawyer
19
+ # Copyright:: Copyright (c) 2006 Thomas Sawyer
20
+ # License:: Ruby License
21
+
22
+ #
23
+
24
+ module Quarry
25
+
26
+ # = Method Probe
27
+ #
28
+ # Method::Probe (aka DuckHunter) is a decoy object which is dropped into
29
+ # methods which records the calls made against it --hence a method probe.
30
+ # Of course, it is not perfect --an inescapable matter it seems for any
31
+ # internal probe. There are a couple of issues related to conditionals.
32
+ # Since the method test for a certain condition against the decoy, how
33
+ # is the decoy to respond? Thus ceratin paths in the code may never get
34
+ # exceuted and thus go unmapped. If Ruby had better conditional reflection
35
+ # (i.e. if 'if', 'case', 'unless', 'when', etc. were true methods) then
36
+ # this could be fixed by making the Probe reentrant, mapping out variant
37
+ # true/false/nil replies. The likely insurmountable problem though is the
38
+ # Halting problem. A probe can cause some methods to complete execution.
39
+ # It's pretty rare, but it can happen and little can be done about it (I think).
40
+ #
41
+ # Note, the alternative to this kind of probe is a program that examines, rather
42
+ # then executes, the code. This would circumvent the above problems, but run
43
+ # into difficulties with dynamic evals. It would also be more complicated,
44
+ # but might prove a better means in the future.
45
+ #
46
+ # This script is provided for experimetnal purposes. Please inform the author
47
+ # if you find ways to improve it or put it to an interesting use.
48
+ #
49
+ # == Synopsis
50
+ #
51
+ # require 'methodprobe'
52
+ #
53
+ # def amethod(x)
54
+ # x + 1
55
+ # end
56
+ #
57
+ # p method(:amethod).signiture
58
+ # p method(:amethod).signiture(:class)
59
+ # p method(:amethod).signiture(:pretty)
60
+ #
61
+ # produces
62
+ #
63
+ # [["+"]]
64
+ # [{"+"=>[["Fixnum"]]}]
65
+ # [["+( Fixnum )"]]
66
+ #
67
+
68
+ class MethodProbe
69
+
70
+ def MethodProbe.duckcall
71
+ begin
72
+ yield
73
+ rescue TypeError => e
74
+ self.send(e.message)
75
+ retry
76
+ end
77
+ end
78
+
79
+ attr_reader :ducks, :decoys
80
+
81
+ def initialize
82
+ @ducks, @decoys = {}, {}
83
+ end
84
+
85
+ def initialize_copy(from)
86
+ initialize
87
+ end
88
+
89
+ def method_missing(aSym, *args)
90
+ aSymStr = aSym.to_s
91
+
92
+ # This will happen the first time
93
+ @ducks[aSymStr] ||= [] #unless @ducks[aSymStr]
94
+ @ducks[aSymStr] << args.collect { |a| "#{a.class}" }
95
+
96
+ decoy = self.dup
97
+
98
+ @decoys[aSymStr] ||= [] #unless @decoys[aSymStr]
99
+ @decoys[aSymStr] << decoy
100
+
101
+ # build proxy?
102
+ #begin
103
+ # d = <<-HERE
104
+ # def self.#{aSymStr}(*args)
105
+ # # This will happen the subsequent times
106
+ # @ducks["#{aSymStr}"] << args.collect { |a| #{'"#{a.class}"'} }
107
+ # @ducks["#{aSymStr}"].uniq!
108
+ # decoy = self.dup
109
+ # @decoys["#{aSymStr}"] = [] unless @decoys["#{aSymStr}"]
110
+ # @decoys["#{aSymStr}"] << decoy
111
+ # decoy
112
+ # end
113
+ # HERE
114
+ # instance_eval d
115
+ #rescue SyntaxError
116
+ # puts "This error may be avoidable by returning the failing duck type as the error message."
117
+ # raise
118
+ #end
119
+
120
+ decoy
121
+ end
122
+
123
+ end # class MethodProbe
124
+
125
+ end
126
+
127
+
128
+ class Method
129
+
130
+ # Outputs migration information.
131
+ def migration
132
+ parameters = []; argc = self.arity
133
+ if argc > 0
134
+ argc.times { parameters << MethodProbe.new }
135
+ Probe.duckcall { self.call(*parameters) }
136
+ elsif argc < 0
137
+ raise "(NYI) method takes unlimited arguments"
138
+ end
139
+ return parameters
140
+ end
141
+ private :migration
142
+
143
+ # Outputs signiture information.
144
+ def signature(detail=nil)
145
+ ds = []
146
+ case detail
147
+ when :complete, :all, :full
148
+ ds = migration
149
+ when :class, :with_class
150
+ migration.each { |dh| ds << dh.ducks }
151
+ when :pp, :pretty, :prettyprint, :pretty_print
152
+ migration.each do |dh|
153
+ responders = []
154
+ dh.ducks.each do |responder, argss|
155
+ argss.each { |args| responders << "#{responder}( #{args.join(',')} )" }
156
+ end
157
+ ds << responders
158
+ end
159
+ else
160
+ migration.each { |dh| ds << dh.ducks.keys }
161
+ end
162
+ return ds
163
+ end
164
+
165
+ end
166
+
167
+
168
+
169
+
170
+ # _____ _
171
+ # |_ _|__ ___| |_
172
+ # | |/ _ \/ __| __|
173
+ # | | __/\__ \ |_
174
+ # |_|\___||___/\__|
175
+ #
176
+
177
+ =begin testing
178
+
179
+ require 'test/unit'
180
+
181
+ # " I am a Duck Hunter ! "
182
+
183
+ class TC_MethodProbe < Test::Unit::TestCase
184
+
185
+ # fixture
186
+ def amethod(x)
187
+ x + 1
188
+ end
189
+
190
+ def test_signiture_default
191
+ assert_nothing_raised {
192
+ method(:amethod).signature
193
+ }
194
+ end
195
+
196
+ def test_signiture_with_class
197
+ assert_nothing_raised {
198
+ method(:amethod).signature(:class)
199
+ }
200
+ end
201
+
202
+ def test_signiture_pp
203
+ assert_nothing_raised {
204
+ method(:amethod).signature(:pp)
205
+ }
206
+ end
207
+
208
+ def test_signiture_all
209
+ assert_nothing_raised {
210
+ method(:amethod).signature(:complete)
211
+ }
212
+ end
213
+
214
+ end
215
+
216
+ =end
@@ -0,0 +1,169 @@
1
+ # = mock.rb
2
+ #
3
+ # == Copyright (c) 2005 Thomas Sawyer, Michael Granger
4
+ #
5
+ # Ruby License
6
+ #
7
+ # This module is free software. You may use, modify, and/or redistribute this
8
+ # software under the same terms as Ruby.
9
+ #
10
+ # This program is distributed in the hope that it will be useful, but WITHOUT
11
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12
+ # FOR A PARTICULAR PURPOSE.
13
+ #
14
+ # == Special Thanks
15
+ #
16
+ # Thanks goes to Michael Granger for Test::Unit::Mock on which
17
+ # this library is partially based.
18
+ #
19
+ # == Author(s)
20
+ #
21
+ # * Thomas Sawyer
22
+ # * Michael Granger
23
+
24
+ require 'ostruct'
25
+
26
+ module Quarry
27
+
28
+ module Mock
29
+
30
+ # = Mock Object
31
+ #
32
+ # A straightfoward mocking facility. Typically used in test cases.
33
+ # The Mock class offers a few constructors for quickly building
34
+ # mockups.
35
+ #
36
+ # mock - Returns a static reponse.
37
+ # echo - Returns the arguments passed-in.
38
+ # spin - Returns a rotation of responses.
39
+ # keys - Returns an index of responses.
40
+ #
41
+ # Mock classes can be built from sratch or partially framed
42
+ # against other classes.
43
+ #
44
+ # === Usage
45
+ #
46
+ # class ContextMock < Mock
47
+ # mock :response_headers, {}
48
+ # spin :host_url, ['http://www.nitrohq.com','http://www.rubyforge.com']
49
+ # end
50
+ #
51
+ # ctx = ContextMock.new
52
+ # ctx.response_headers['location'] = url
53
+ # ctx.host_url #=> "http://www.nitrohq.com"
54
+ # ctx.host_url #=> "http://www.rubyforge.com"
55
+ #
56
+ # Or
57
+ #
58
+ # class ContextMock < Mock(Context)
59
+ # ...
60
+ # end
61
+ #
62
+ class Object < OpenStruct
63
+
64
+ # include these?
65
+ #include Test::Unit::Assertions
66
+
67
+ # Certain methods are not mocked:
68
+ # inspect (tricky)
69
+ # class (delegated)
70
+ # kind_of? (delegated)
71
+ # is_a? (delegated)
72
+ # instance_of? (delegated)
73
+ # method (works as-is)
74
+ # send (works as-is)
75
+ # respond_to? (works as-is)
76
+ # hash (no way to mock)
77
+ #
78
+ # __id__, __call__, etc. (not meant to be mocked, ever!)
79
+ #
80
+
81
+ UnmockedMethods = %r{^(
82
+ |inspect
83
+ |kind_of\?|is_a\?|instance_of\?|class
84
+ |method|send|respond_to\?
85
+ |hash
86
+ |__
87
+ )}x
88
+
89
+ class << self
90
+
91
+ attr :mocked_class
92
+
93
+ def mocks
94
+ self.methods(false)
95
+ end
96
+
97
+ # Mock a static repsonse.
98
+ def mock( sym, val )
99
+ define_method( sym ) { |*args| val }
100
+ end
101
+
102
+ # Responds with input.
103
+ def echo( sym )
104
+ define_method( sym ) { |*args| args }
105
+ end
106
+
107
+ # Reponds with a rotation of reponses.
108
+ def spin( sym, arr )
109
+ define_method( sym ) { |*args| arr.push(arr.shift) ; arr[-1] }
110
+ end
111
+
112
+ # Responds according to a mapping of input parameters.
113
+ def keys( sym, hsh )
114
+ define_method( sym ) { |*args| hsh[args] }
115
+ end
116
+
117
+ end
118
+
119
+ # Delegate methods: #class, instance_of?, kind_of?, and is_a?
120
+
121
+ alias :__class :class
122
+
123
+ def class # :nodoc:
124
+ return __class.mocked_class
125
+ end
126
+
127
+ def instance_of?( klass ) # :nodoc:
128
+ self.class == klass
129
+ end
130
+
131
+ def kind_of?( klass ) # :nodoc:
132
+ self.class <= klass
133
+ end
134
+
135
+ alias_method :is_a?, :kind_of?
136
+
137
+ end
138
+
139
+ end
140
+
141
+ end
142
+
143
+
144
+ # TODO
145
+
146
+ =begin #test
147
+
148
+ class MyMock < Mock::Object
149
+ mock :m, 10
150
+ echo :e
151
+ spin :s, [1,2,3]
152
+ keys :i, { [:foo] => 'Hello', [:boo] => 'Frog' }
153
+
154
+ def a(k) k+1 end
155
+ end
156
+
157
+ my = MyMock.new
158
+
159
+ p my.m
160
+ p my.e('hi')
161
+ p my.s
162
+ p my.s
163
+ p my.s
164
+ p my.i(:foo)
165
+ p my.i(:boo)
166
+ p my.a(1)
167
+
168
+ =end
169
+
@@ -0,0 +1,85 @@
1
+ # = mock.rb
2
+ #
3
+ # == Copyright (c) 2005 George Moschovitis
4
+ #
5
+ # Ruby License
6
+ #
7
+ # This module is free software. You may use, modify, and/or redistribute this
8
+ # software under the same terms as Ruby.
9
+ #
10
+ # This program is distributed in the hope that it will be useful, but WITHOUT
11
+ # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
12
+ # FOR A PARTICULAR PURPOSE.
13
+ #
14
+ # == Author(s)
15
+ #
16
+ # * George Moschovitis
17
+
18
+ require 'ostruct'
19
+
20
+ module Quarry
21
+
22
+ # Factory method for creating semi-functional mock object classes given the
23
+ # class which is to be mocked. It looks like a constant for purposes
24
+ # of syntactic sugar.
25
+ def Mockery( realclass )
26
+
27
+ mockclass = Class.new( Mock )
28
+
29
+ mockclass.instance_eval do @mocked_class = realclass end
30
+
31
+ # Provide an accessor to class instance var that holds the class
32
+ # object we're faking
33
+ class << mockclass
34
+ # The actual class being mocked
35
+ attr_reader :mocked_class
36
+
37
+ # Propagate the mocked class ivar to derivatives so it can be
38
+ # called like:
39
+ # class MockFoo < Mock( RealClass )
40
+ def inherited( subclass )
41
+ mc = self.mockedClass
42
+ subclass.instance_eval do @mocked_class = mc end
43
+ end
44
+ end
45
+
46
+ # Build method definitions for all the mocked class's instance
47
+ # methods, as well as those given to it by its superclasses, since
48
+ # we're not really inheriting from it.
49
+ imethods = realclass.instance_methods(true).collect do |name|
50
+ next if name =~ ::Mock::UnmockedMethods
51
+
52
+ # Figure out the argument list
53
+ arity = realclass.instance_method( name ).arity
54
+ optargs = false
55
+
56
+ if arity < 0
57
+ optargs = true
58
+ arity = (arity+1).abs
59
+ end
60
+
61
+ args = []
62
+ arity.times do |n| args << "arg#{n+1}" end
63
+ args << "*optargs" if optargs
64
+
65
+ # Build a method definition. Some methods need special
66
+ # declarations.
67
+ argsj = args.join(',')
68
+ case name.intern
69
+ when :initialize
70
+ "def initialize(#{argsj}) ; super ; end"
71
+ else
72
+ "def #{name}(#{argsj}) ; self.send(#{name},#{argsj}) ; end"
73
+ #"def %s( %s ) ; self.__mockRegisterCall(%s) ; end" %
74
+ # [ name, argstr, [":#{name}", *args].join(',') ]
75
+ end
76
+ end
77
+
78
+ # Now add the instance methods to the mockclass class
79
+ mockclass.class_eval imethods.join( "\n" )
80
+
81
+ return mockclass
82
+ end
83
+
84
+ end
85
+