Build2Spec 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/doc/README +2 -0
- data/doc/Specifications +36 -0
- data/lib/build2spec.rb +585 -0
- data/lib/interpose/lib/spec/expectations.rb +28 -0
- data/lib/interpose/lib/spec/runner/context_eval.rb +39 -0
- data/lib/interpose/lib/spec/runner/specification.rb +17 -0
- data/lib/spec_x_example.rb +51 -0
- metadata +70 -0
data/doc/README
ADDED
data/doc/Specifications
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
|
2
|
+
The Builder class
|
3
|
+
- should produce 0 arg method text
|
4
|
+
- should produce 1 arg method text
|
5
|
+
- should produce 1..3 arg method text, with a block
|
6
|
+
|
7
|
+
The Builder class
|
8
|
+
- should create a standin for Kernel
|
9
|
+
|
10
|
+
A covered class
|
11
|
+
- should return instances of itself from ::new
|
12
|
+
- should have an associated StandIn
|
13
|
+
- should collect methods from explicit calls
|
14
|
+
- should collect methods from #should calls
|
15
|
+
- should return false from query? methods
|
16
|
+
|
17
|
+
An UnknownType
|
18
|
+
- should return instances of itself from ::new
|
19
|
+
- should guess nil without method calls
|
20
|
+
- should not guess nil with method calls
|
21
|
+
|
22
|
+
The Kernel module
|
23
|
+
- should be a legitimate target of method creation
|
24
|
+
|
25
|
+
An UnknownStandIn
|
26
|
+
- should not produce module body even without methods
|
27
|
+
- should not produce module body if type guessed
|
28
|
+
|
29
|
+
A StandIn
|
30
|
+
- should not produce module body without methods
|
31
|
+
- should produce module body when instance method recorded
|
32
|
+
- should produce module body when class method recorded
|
33
|
+
|
34
|
+
Finished in 0.01738 seconds
|
35
|
+
|
36
|
+
18 specifications, 0 failures
|
data/lib/build2spec.rb
ADDED
@@ -0,0 +1,585 @@
|
|
1
|
+
require "spec"
|
2
|
+
|
3
|
+
END { Build2Spec::Builder.build unless $UNDER_SPEC }
|
4
|
+
|
5
|
+
unless $UNDER_SPEC
|
6
|
+
require "interpose/lib/spec/expectations"
|
7
|
+
require "interpose/lib/spec/runner/specification"
|
8
|
+
require "interpose/lib/spec/runner/context_eval"
|
9
|
+
module Kernel
|
10
|
+
alias b2s_original_require require
|
11
|
+
def require(path)
|
12
|
+
Build2Spec::Builder::register_file(nil, path)
|
13
|
+
Build2Spec::Builder::cover_for_modules(path)
|
14
|
+
end
|
15
|
+
|
16
|
+
alias b2s_original_autoload autoload
|
17
|
+
def autoload(mod, filename)
|
18
|
+
Build2Spec::Builder::register_file(mod, filename)
|
19
|
+
b2s_original_autoload(mod, filename)
|
20
|
+
Build2Spec::Builder::cover_for_modules(filename)
|
21
|
+
end
|
22
|
+
|
23
|
+
def create_files_in(path)
|
24
|
+
Build2Spec::Builder.create_files_in(path)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
class Module
|
30
|
+
def const_missing(name)
|
31
|
+
Build2Spec::Builder.create_covered_module(name, self)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
class Object
|
36
|
+
def self.const_missing(name)
|
37
|
+
Build2Spec::Builder.create_covered_module(name, self)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
module Build2Spec
|
43
|
+
class Builder
|
44
|
+
@module_homes = Hash.new {|h,k| h.has_key?(nil) ? h[nil] : nil }
|
45
|
+
@create_files_in = nil
|
46
|
+
|
47
|
+
class UnresolvedPath
|
48
|
+
def initialize(path)
|
49
|
+
@path = path
|
50
|
+
end
|
51
|
+
|
52
|
+
def resolve(directory)
|
53
|
+
unless /.rb$/ =~ @path
|
54
|
+
@path += ".rb"
|
55
|
+
end
|
56
|
+
return File::join(directory, @path)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
@standins = {}
|
61
|
+
|
62
|
+
class << self
|
63
|
+
attr_accessor :module_homes
|
64
|
+
attr_accessor :standins
|
65
|
+
|
66
|
+
def create_files_in(path)
|
67
|
+
@create_files_in = path
|
68
|
+
end
|
69
|
+
|
70
|
+
def cover_for_modules(path)
|
71
|
+
existing_modules = all_modules
|
72
|
+
begin
|
73
|
+
b2s_original_require(path)
|
74
|
+
rescue LoadError
|
75
|
+
return
|
76
|
+
end
|
77
|
+
|
78
|
+
new_modules = all_modules - existing_modules
|
79
|
+
new_modules,contexts = new_modules.partition{|m| m.include?(Kernel)}
|
80
|
+
new_modules.sort!{|l, r| l.name.delete("^:").length <=> r.name.delete("^:").length}
|
81
|
+
|
82
|
+
new_modules.each do |mod|
|
83
|
+
cover_for_module(mod)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def all_modules
|
88
|
+
list = []
|
89
|
+
ObjectSpace.each_object(Module){|m| list << m}
|
90
|
+
list
|
91
|
+
end
|
92
|
+
|
93
|
+
def register_file(mod, file)
|
94
|
+
module_homes[mod] = resolve_path(file)
|
95
|
+
end
|
96
|
+
|
97
|
+
def resolve_path(file)
|
98
|
+
$:.each do |lib_path|
|
99
|
+
path = File::expand_path(File::join(lib_path, file))
|
100
|
+
unless /.rb$/ =~ path
|
101
|
+
path += ".rb"
|
102
|
+
end
|
103
|
+
if File::exists?(path) and File::file?(path)
|
104
|
+
return path
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
return UnresolvedPath.new(file)
|
109
|
+
end
|
110
|
+
|
111
|
+
def build
|
112
|
+
create_in = @create_files_in || $:.first
|
113
|
+
|
114
|
+
FakingMethods::unknown_types.each do |type|
|
115
|
+
type.guess!
|
116
|
+
end
|
117
|
+
|
118
|
+
@module_homes.each_pair do |mod, path|
|
119
|
+
if path.respond_to? :resolve
|
120
|
+
@module_homes[mod] = path.resolve(create_in)
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
if @module_homes.values.empty?
|
125
|
+
raise "No files designated to generate code into. Use require or autoload to designate code destinations!"
|
126
|
+
end
|
127
|
+
|
128
|
+
@standins.each_value do |standin|
|
129
|
+
unless File::exists?(@module_homes[standin.name])
|
130
|
+
puts "Creating new code file: #{@module_homes[standin.name]}"
|
131
|
+
end
|
132
|
+
File::open(@module_homes[standin.name], "a") do |file|
|
133
|
+
file.write(standin.mod_text + "\n")
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def add_standin(nesting_path, name, standin)
|
139
|
+
nesting_path = nesting_path.name.to_s if Module === nesting_path
|
140
|
+
list = standin_location(nesting_path)
|
141
|
+
list[name] = standin
|
142
|
+
end
|
143
|
+
|
144
|
+
def standin_for(nesting_path)
|
145
|
+
nesting_path = nesting_path.name.to_s if Module === nesting_path
|
146
|
+
m = /(?:(.*)::)?(.*)/.match nesting_path
|
147
|
+
list = standin_location(m[1])
|
148
|
+
list[m[2]]
|
149
|
+
end
|
150
|
+
|
151
|
+
def standin_location(nesting_path)
|
152
|
+
list = @standins
|
153
|
+
return list if nesting_path.nil?
|
154
|
+
classpath = nesting_path.split("::")
|
155
|
+
create_missing_under = ::Object
|
156
|
+
classpath.each do |klass|
|
157
|
+
unless list.has_key?(klass)
|
158
|
+
unless create_missing_under.const_defined?(klass.intern)
|
159
|
+
raise RuntimeError, "Missing #{klass} in #{classpath}"
|
160
|
+
end
|
161
|
+
list[klass] = StandIn.new(create_missing_under.const_get(klass.intern))
|
162
|
+
end
|
163
|
+
create_missing_under = list[klass].covering_for
|
164
|
+
list = list[klass].nested
|
165
|
+
end
|
166
|
+
return list
|
167
|
+
end
|
168
|
+
|
169
|
+
def cover_for_module(klass)
|
170
|
+
m = /(?:(.*)::)?(.*)/.match klass.name.to_s
|
171
|
+
nesting = m[1] || ""
|
172
|
+
class_name = m[2]
|
173
|
+
klass.class_eval { include CoveredModule }
|
174
|
+
class_name = klass.name.to_s.sub(/.*::/, "")
|
175
|
+
Build2Spec::Builder::add_standin(nesting, class_name, StandIn.new(klass))
|
176
|
+
end
|
177
|
+
|
178
|
+
def create_covered_module(name, nesting, superclass=::Object)
|
179
|
+
classes = name.to_s.split("::")
|
180
|
+
class_name = classes.pop
|
181
|
+
classes.each do |nest|
|
182
|
+
unless nesting.const_defined?(nest)
|
183
|
+
create_covered_module(nest, nesting)
|
184
|
+
end
|
185
|
+
nesting = nesting.const_get(nest)
|
186
|
+
end
|
187
|
+
klass = Class.new(superclass)
|
188
|
+
nesting.const_set(class_name, klass)
|
189
|
+
UnknownType::add_guess_entry(klass, "#{nesting}::#{name}.new")
|
190
|
+
cover_for_module(klass)
|
191
|
+
return klass
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
class StandIn
|
197
|
+
def initialize(klass)
|
198
|
+
@covering_for = klass
|
199
|
+
@faked_instance_methods = {}
|
200
|
+
@faked_module_methods = {}
|
201
|
+
@nested = {}
|
202
|
+
@i_am_module = nil
|
203
|
+
end
|
204
|
+
|
205
|
+
attr_reader :covering_for, :faked_instance_methods, :faked_module_methods, :nested
|
206
|
+
|
207
|
+
Indent=" " * 2
|
208
|
+
|
209
|
+
def method_text(name, spec, indent)
|
210
|
+
args = argument_text(spec)
|
211
|
+
|
212
|
+
result = spec[2].inspect
|
213
|
+
if spec[2].respond_to?(:guess)
|
214
|
+
result = spec[2].guess
|
215
|
+
end
|
216
|
+
|
217
|
+
return "def #{name}#{args}\n#{indent}return #{result}\nend\n"
|
218
|
+
end
|
219
|
+
|
220
|
+
def argument_text(spec)
|
221
|
+
required = spec[0].begin > 0 ? Range.new("a",(?a + spec[0].begin - 1).chr).to_a : []
|
222
|
+
optional = spec[0].end - spec[0].begin > 0 ?
|
223
|
+
Range.new((?a + spec[0].begin).chr,(?a + spec[0].end - 1).chr).to_a.map{|a| "#{a}=nil"} : []
|
224
|
+
|
225
|
+
args = required + optional
|
226
|
+
if spec[1]
|
227
|
+
args << "&block"
|
228
|
+
end
|
229
|
+
return args.length > 0 ? "( #{args.join(", ")} )" : ""
|
230
|
+
end
|
231
|
+
|
232
|
+
def is_module
|
233
|
+
@i_am_module = "module"
|
234
|
+
end
|
235
|
+
|
236
|
+
def is_class
|
237
|
+
@i_am_module = "class"
|
238
|
+
end
|
239
|
+
|
240
|
+
def mod_text(nesting="")
|
241
|
+
return "" if empty?
|
242
|
+
body = body_text(nesting)
|
243
|
+
|
244
|
+
text = mod_opener(nesting)
|
245
|
+
text << body
|
246
|
+
text << "end\n"
|
247
|
+
end
|
248
|
+
|
249
|
+
def nest_standin(other)
|
250
|
+
@nested[other] = nil
|
251
|
+
end
|
252
|
+
|
253
|
+
def name
|
254
|
+
covering_for.name
|
255
|
+
end
|
256
|
+
|
257
|
+
def empty?
|
258
|
+
return faked_instance_methods.values.empty? &&
|
259
|
+
faked_module_methods.values.empty? &&
|
260
|
+
nested.empty?
|
261
|
+
end
|
262
|
+
|
263
|
+
protected
|
264
|
+
|
265
|
+
def body_text(nesting)
|
266
|
+
spacer( mod_methods_text,
|
267
|
+
nested_module_text(nesting_at(nesting), nested),
|
268
|
+
instance_methods_text)
|
269
|
+
end
|
270
|
+
|
271
|
+
def spacer(*args)
|
272
|
+
args.delete_if{|a| /\A\s*\Z/ =~ a}
|
273
|
+
return args.join("\n")
|
274
|
+
end
|
275
|
+
|
276
|
+
def indent
|
277
|
+
string = yield
|
278
|
+
string = string.split("\n").map do |line|
|
279
|
+
Indent + line
|
280
|
+
end.join("\n")
|
281
|
+
unless string.empty?
|
282
|
+
string << "\n"
|
283
|
+
end
|
284
|
+
string
|
285
|
+
end
|
286
|
+
|
287
|
+
def name_at(nesting)
|
288
|
+
name = @covering_for.name
|
289
|
+
if not nesting.empty?
|
290
|
+
if /^#{nesting}::/ =~ name
|
291
|
+
name.sub!(/^#{nesting}::/,"")
|
292
|
+
else
|
293
|
+
name = "::" + name
|
294
|
+
end
|
295
|
+
end
|
296
|
+
return name
|
297
|
+
end
|
298
|
+
|
299
|
+
def nesting_at(nesting)
|
300
|
+
name = name_at(nesting)
|
301
|
+
return name if %r"^::" =~ name or nesting.empty?
|
302
|
+
return [nesting, name].join("::")
|
303
|
+
end
|
304
|
+
|
305
|
+
def mod_opener(nesting)
|
306
|
+
supertext = ""
|
307
|
+
|
308
|
+
if @covering_for.class != Module and @covering_for.superclass != Object
|
309
|
+
supertext = " < #{@covering_for.superclass.name}"
|
310
|
+
end
|
311
|
+
|
312
|
+
is_module if @covering_for.class == Module
|
313
|
+
|
314
|
+
type = @i_am_module || "class"
|
315
|
+
return "#{type} #{name_at(nesting)}#{supertext}\n"
|
316
|
+
end
|
317
|
+
|
318
|
+
def mod_methods_text
|
319
|
+
return "" if @faked_module_methods.empty?
|
320
|
+
indent do
|
321
|
+
"class << self\n" + indent do
|
322
|
+
@faked_module_methods.map do |name, spec|
|
323
|
+
method_text(name, spec, Indent)
|
324
|
+
end.delete_if{|m| m == ""}.join("\n") + "\n"
|
325
|
+
end + "end"
|
326
|
+
end
|
327
|
+
end
|
328
|
+
|
329
|
+
def instance_methods_text
|
330
|
+
return "" if @faked_instance_methods.empty?
|
331
|
+
indent do
|
332
|
+
@faked_instance_methods.map do |name, spec|
|
333
|
+
method_text(name, spec, Indent)
|
334
|
+
end.delete_if{|m| m == ""}.join("\n")
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
def nested_module_text(nesting, nested)
|
339
|
+
return "" if nested.empty?
|
340
|
+
indent do
|
341
|
+
mods = nested.values.map do |mod|
|
342
|
+
mod.mod_text(nesting)
|
343
|
+
end.delete_if{|m| m == ""}.join("\n")
|
344
|
+
end
|
345
|
+
end
|
346
|
+
end
|
347
|
+
|
348
|
+
class UnknownType; end
|
349
|
+
|
350
|
+
module FakingMethods
|
351
|
+
def initialize(*args, &block)
|
352
|
+
return FakingMethods::record_method_spec(return_type_nesting, faked_methods, FakingMethods.current_method, args, block)
|
353
|
+
end
|
354
|
+
|
355
|
+
@@unknown_types = []
|
356
|
+
def self.unknown_types
|
357
|
+
return @@unknown_types
|
358
|
+
end
|
359
|
+
|
360
|
+
def self.current_method
|
361
|
+
called_from = caller.grep(/in `/)[1]
|
362
|
+
if (m = /in `([^']*)/.match called_from)
|
363
|
+
return m[1].intern
|
364
|
+
else
|
365
|
+
raise RuntimeError, called_from
|
366
|
+
end
|
367
|
+
end
|
368
|
+
|
369
|
+
def self.record_method_spec(nesting, faked_methods, name, args, block)
|
370
|
+
method_spec = []
|
371
|
+
if (method_spec = faked_methods[name]).nil?
|
372
|
+
arity = args.length
|
373
|
+
|
374
|
+
result = UnknownType.create(nesting)
|
375
|
+
if name == :initialize
|
376
|
+
result = nil
|
377
|
+
elsif /\?$/ =~ name.to_s
|
378
|
+
result = false
|
379
|
+
end
|
380
|
+
|
381
|
+
if UnknownType === result
|
382
|
+
@@unknown_types << result
|
383
|
+
end
|
384
|
+
|
385
|
+
method_spec = [arity..arity, (not block.nil?), result]
|
386
|
+
faked_methods[name] = method_spec
|
387
|
+
else
|
388
|
+
unless (method_spec[0].include? args.length)
|
389
|
+
if(method_spec[0].begin > args.length)
|
390
|
+
method_spec[0] = args.length..method_spec[0].end
|
391
|
+
else
|
392
|
+
method_spec[0] = method_spec[0].begin..args.length
|
393
|
+
end
|
394
|
+
end
|
395
|
+
|
396
|
+
method_spec[1] ||= !(block.nil?)
|
397
|
+
end
|
398
|
+
|
399
|
+
#p [:rms, name, method_spec]
|
400
|
+
|
401
|
+
return method_spec[2]
|
402
|
+
end
|
403
|
+
|
404
|
+
def method_missing(name, *args, &block)
|
405
|
+
retval = FakingMethods::record_method_spec(return_type_nesting, faked_methods, name, args, block)
|
406
|
+
|
407
|
+
if Module === self
|
408
|
+
define_method(name, instance_method(:initialize))
|
409
|
+
else
|
410
|
+
self.class.class_eval do
|
411
|
+
define_method(name, self.instance_method(:initialize))
|
412
|
+
end
|
413
|
+
end
|
414
|
+
|
415
|
+
return retval
|
416
|
+
end
|
417
|
+
end
|
418
|
+
|
419
|
+
module FakingModules
|
420
|
+
def const_missing(name)
|
421
|
+
Build2Spec::Builder::create_covered_module(name, self)
|
422
|
+
end
|
423
|
+
end
|
424
|
+
|
425
|
+
module CoveredModule
|
426
|
+
def self.included(sub)
|
427
|
+
sub.module_eval do
|
428
|
+
def self.faked_methods
|
429
|
+
Build2Spec::Builder::standin_for(self).faked_module_methods
|
430
|
+
end
|
431
|
+
|
432
|
+
def self.return_type_nesting
|
433
|
+
self.name.to_s
|
434
|
+
end
|
435
|
+
|
436
|
+
include FakingMethods
|
437
|
+
end
|
438
|
+
|
439
|
+
sub.extend FakingMethods
|
440
|
+
sub.extend FakingModules
|
441
|
+
end
|
442
|
+
|
443
|
+
def faked_methods
|
444
|
+
Build2Spec::Builder::standin_for(self.class).faked_instance_methods
|
445
|
+
end
|
446
|
+
|
447
|
+
def return_type_nesting
|
448
|
+
self.class.name.to_s.sub(/(::)?[^:]*$/, "")
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
452
|
+
class UnknownStandIn < StandIn
|
453
|
+
def name_at(nesting)
|
454
|
+
@covering_for.name || "Build2Spec::UnknownType"
|
455
|
+
end
|
456
|
+
|
457
|
+
def mod_text(nesting="")
|
458
|
+
return "" if @covering_for.guessed?
|
459
|
+
super
|
460
|
+
end
|
461
|
+
end
|
462
|
+
|
463
|
+
class UnknownType
|
464
|
+
include FakingMethods
|
465
|
+
|
466
|
+
@@name_suffix = "A"
|
467
|
+
|
468
|
+
@@guessing_table = [
|
469
|
+
[Fixnum, '42'],
|
470
|
+
[String, '"wrong answer"'],
|
471
|
+
[Array, '[]'],
|
472
|
+
[Hash, '{}'],
|
473
|
+
[Object, "Object.new"],
|
474
|
+
[Class, @name],
|
475
|
+
]
|
476
|
+
|
477
|
+
def self.add_guess_entry(klass, exemplar)
|
478
|
+
@@guessing_table.unshift [klass, exemplar]
|
479
|
+
end
|
480
|
+
|
481
|
+
def self.create(nesting, name = nil)
|
482
|
+
type = self.allocate
|
483
|
+
type.setup(nesting, name)
|
484
|
+
type
|
485
|
+
end
|
486
|
+
|
487
|
+
def superclass
|
488
|
+
Object
|
489
|
+
end
|
490
|
+
|
491
|
+
def setup(nesting, name)
|
492
|
+
@standin = UnknownStandIn.new(self)
|
493
|
+
@guess = nil
|
494
|
+
@name = name || "UnknownType#{@@name_suffix}"
|
495
|
+
@nesting = nesting
|
496
|
+
@@name_suffix.succ!
|
497
|
+
Builder::add_standin(nesting, @name, @standin)
|
498
|
+
end
|
499
|
+
|
500
|
+
def inspect
|
501
|
+
"<Build2Spec Dummy Return Value>"
|
502
|
+
end
|
503
|
+
|
504
|
+
attr_reader :standin, :name
|
505
|
+
|
506
|
+
def guess!
|
507
|
+
return if faked_methods.empty?
|
508
|
+
return if guessed?
|
509
|
+
|
510
|
+
@@guessing_table.each do |klass, exemplar|
|
511
|
+
faked = faked_methods.map{|f| f[0].to_s}
|
512
|
+
klass.instance_methods.each do |real|
|
513
|
+
faked.delete(real)
|
514
|
+
end
|
515
|
+
if(faked.empty?)
|
516
|
+
@guess = exemplar
|
517
|
+
return
|
518
|
+
end
|
519
|
+
end
|
520
|
+
end
|
521
|
+
|
522
|
+
def guessed?
|
523
|
+
not @guess.nil?
|
524
|
+
end
|
525
|
+
|
526
|
+
def guess
|
527
|
+
if @guess.nil?
|
528
|
+
if standin.empty?
|
529
|
+
return "nil"
|
530
|
+
else
|
531
|
+
init_spec = @standin.faked_instance_methods[:initialize]
|
532
|
+
if init_spec.nil?
|
533
|
+
return "#@name.new"
|
534
|
+
else
|
535
|
+
return "#@name.new#{@standin.argument_text(init_spec)}"
|
536
|
+
end
|
537
|
+
end
|
538
|
+
else
|
539
|
+
return @guess
|
540
|
+
end
|
541
|
+
end
|
542
|
+
|
543
|
+
def new(*args, &block)
|
544
|
+
instance = im_a_module
|
545
|
+
instance.initialize(*args, &block)
|
546
|
+
return instance
|
547
|
+
end
|
548
|
+
|
549
|
+
def im_a_module
|
550
|
+
return @instance_type unless @instance_type.nil?
|
551
|
+
module_standin = UnknownStandIn.new(self)
|
552
|
+
@standin.faked_instance_methods.each_pair do |k,v|
|
553
|
+
module_standin.faked_module_methods[k] = v
|
554
|
+
end
|
555
|
+
@standin = module_standin
|
556
|
+
class << self
|
557
|
+
def faked_methods
|
558
|
+
@standin.faked_module_methods
|
559
|
+
end
|
560
|
+
|
561
|
+
def guess!
|
562
|
+
end
|
563
|
+
end
|
564
|
+
|
565
|
+
@instance_type = UnknownType.create(@nesting, @name)
|
566
|
+
|
567
|
+
@name += "Class"
|
568
|
+
@guess = nil
|
569
|
+
|
570
|
+
return @instance_type
|
571
|
+
end
|
572
|
+
|
573
|
+
def faked_methods
|
574
|
+
@standin.faked_instance_methods
|
575
|
+
end
|
576
|
+
|
577
|
+
def return_type_nesting
|
578
|
+
@nesting
|
579
|
+
end
|
580
|
+
end
|
581
|
+
|
582
|
+
Builder::add_standin(nil, "Kernel", StandIn.new(Kernel))
|
583
|
+
end
|
584
|
+
|
585
|
+
|
@@ -0,0 +1,28 @@
|
|
1
|
+
|
2
|
+
|
3
|
+
module Spec
|
4
|
+
module Expectations
|
5
|
+
@errors = []
|
6
|
+
|
7
|
+
class << self
|
8
|
+
|
9
|
+
def clear_errors
|
10
|
+
@errors.clear
|
11
|
+
end
|
12
|
+
|
13
|
+
def first_error
|
14
|
+
return if @errors.empty?
|
15
|
+
raise @errors.first
|
16
|
+
end
|
17
|
+
|
18
|
+
alias b2s_fail_with fail_with
|
19
|
+
def fail_with(message, expected=nil, target=nil)
|
20
|
+
begin
|
21
|
+
b2s_fail_with(message, expected, target)
|
22
|
+
rescue Spec::Expectations::ExpectationNotMetError => seenme
|
23
|
+
@errors << seenme
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Spec
|
2
|
+
module Runner
|
3
|
+
module ContextEval
|
4
|
+
module ModuleMethods
|
5
|
+
|
6
|
+
def derive_execution_context_class_from_context_superclass
|
7
|
+
@execution_context_class = Class.new(context_superclass)
|
8
|
+
@execution_context_class.class_eval do
|
9
|
+
def const_missing
|
10
|
+
::Build2Spec::Builder.create_covered_module(name, Object)
|
11
|
+
end
|
12
|
+
|
13
|
+
def self.faked_methods
|
14
|
+
::Build2Spec::Builder::standin_for(Kernel).faked_module_methods
|
15
|
+
end
|
16
|
+
|
17
|
+
def faked_methods
|
18
|
+
::Build2Spec::Builder::standin_for(Kernel).faked_instance_methods
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.return_type_nesting
|
22
|
+
""
|
23
|
+
end
|
24
|
+
|
25
|
+
def return_type_nesting
|
26
|
+
""
|
27
|
+
end
|
28
|
+
|
29
|
+
include ::Build2Spec::FakingMethods
|
30
|
+
include ::Spec::Runner::ExecutionContext::InstanceMethods
|
31
|
+
|
32
|
+
extend ::Build2Spec::FakingMethods
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Spec
|
2
|
+
module Runner
|
3
|
+
class Specification
|
4
|
+
def execute_spec(execution_context, errors)
|
5
|
+
begin
|
6
|
+
Spec::Expectations::clear_errors
|
7
|
+
execution_context.instance_eval(&spec_block)
|
8
|
+
Spec::Expectations::first_error
|
9
|
+
return true
|
10
|
+
rescue Exception => e
|
11
|
+
errors << e
|
12
|
+
return false
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
class SpecXExample
|
2
|
+
class Generator
|
3
|
+
class << self
|
4
|
+
def instance
|
5
|
+
return UnknownTypeA.new
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class UnknownTypeA
|
10
|
+
def initialize
|
11
|
+
return nil
|
12
|
+
end
|
13
|
+
|
14
|
+
def contexts
|
15
|
+
return nil
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
module Kernel
|
22
|
+
def eg( &block )
|
23
|
+
return nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
class SpecXExample
|
28
|
+
class Generator
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
class SpecXExample
|
33
|
+
class Generator
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
class SpecXExample
|
38
|
+
class Generator
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
class SpecXExample
|
43
|
+
class Generator
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class SpecXExample
|
48
|
+
class Generator
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
metadata
ADDED
@@ -0,0 +1,70 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
rubygems_version: 0.9.2
|
3
|
+
specification_version: 1
|
4
|
+
name: Build2Spec
|
5
|
+
version: !ruby/object:Gem::Version
|
6
|
+
version: 0.1.0
|
7
|
+
date: 2007-04-03 00:00:00 -07:00
|
8
|
+
summary: Rapidly produce code skeletons from rspec specifications
|
9
|
+
require_paths:
|
10
|
+
- lib
|
11
|
+
email: judson@redfivellc.com
|
12
|
+
homepage:
|
13
|
+
rubyforge_project:
|
14
|
+
description: Any automated testing should save you effort. Use the work you did writing your specs first to produce the skeleton of new projects or even just new features. Makes BDD discipline effortless to maintain.
|
15
|
+
autorequire:
|
16
|
+
default_executable:
|
17
|
+
bindir: bin
|
18
|
+
has_rdoc: true
|
19
|
+
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">"
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: 0.0.0
|
24
|
+
version:
|
25
|
+
platform: ruby
|
26
|
+
signing_key:
|
27
|
+
cert_chain:
|
28
|
+
post_install_message: Another tidy package brought to you by the cheerful folks at Red Five
|
29
|
+
authors:
|
30
|
+
- Judson Lester
|
31
|
+
files:
|
32
|
+
- lib/build2spec.rb
|
33
|
+
- lib/spec_x_example.rb
|
34
|
+
- lib/interpose
|
35
|
+
- lib/interpose/lib
|
36
|
+
- lib/interpose/lib/spec
|
37
|
+
- lib/interpose/lib/spec/runner
|
38
|
+
- lib/interpose/lib/spec/expectations.rb
|
39
|
+
- lib/interpose/lib/spec/runner/specification.rb
|
40
|
+
- lib/interpose/lib/spec/runner/context_eval.rb
|
41
|
+
- doc/README
|
42
|
+
- doc/Specifications
|
43
|
+
test_files: []
|
44
|
+
|
45
|
+
rdoc_options:
|
46
|
+
- --diagram
|
47
|
+
- --inline-source
|
48
|
+
- --main
|
49
|
+
- Build2Spec
|
50
|
+
- --title
|
51
|
+
- Build2Spec
|
52
|
+
extra_rdoc_files:
|
53
|
+
- doc/README
|
54
|
+
- doc/Specifications
|
55
|
+
executables: []
|
56
|
+
|
57
|
+
extensions: []
|
58
|
+
|
59
|
+
requirements: []
|
60
|
+
|
61
|
+
dependencies:
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: rspec
|
64
|
+
version_requirement:
|
65
|
+
version_requirements: !ruby/object:Gem::Version::Requirement
|
66
|
+
requirements:
|
67
|
+
- - ">="
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: 0.8.0
|
70
|
+
version:
|