pretentious 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +22 -2
- data/bin/pretentious +57 -42
- data/lib/pretentious.rb +6 -0
- data/lib/pretentious/generator.rb +18 -13
- data/lib/pretentious/lazy_trigger.rb +21 -0
- data/lib/pretentious/rspec_generator.rb +1 -1
- data/lib/pretentious/version.rb +1 -1
- data/run_test.sh +1 -1
- data/spec/generated/test_class1_spec.rb +1 -1
- data/test/generated/test_test_class1.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fc5e9755c5726a466b3e5236c8a3a6f31598edcf
|
4
|
+
data.tar.gz: 877f5c3cce5e9ebfe6707e81ab9e2f8af608720b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6662b618095ad53bc7c13c3f26e2aafa12e2db6d7cb171eb00e4dd2add29f13fbfc2d92ff282930fef0d5a83d96493fbb07d9b251a9e76835d15680636faf9af
|
7
|
+
data.tar.gz: 8fb21e772ea8b3fce3281664a4c0967f57132465c0a64e5dba40a0dc63c51b721423a799f72c58e9893dabf50f62cb8dc796eb6a108950b721617b1bb5b04fc1
|
data/README.md
CHANGED
@@ -43,7 +43,9 @@ The are various ways to use the pretentious gem. First is using an example file.
|
|
43
43
|
|
44
44
|
The other way is using an init file to declare which classes to test and when. This is useful if you want to document how a class is used in an existing application. This is the prefered method for characterization testing on framework like rails.
|
45
45
|
|
46
|
-
|
46
|
+
There are also various commandline options available.
|
47
|
+
|
48
|
+
Please refer to the table of contents to skip directly to the specific use case.
|
47
49
|
|
48
50
|
### Using an example file
|
49
51
|
First Create an example file (etc. example.rb) and define the classes that you want to test, if the class is already defined elsewhere just require them. Below is an example:
|
@@ -162,7 +164,7 @@ RSpec.describe Fibonacci do
|
|
162
164
|
end
|
163
165
|
```
|
164
166
|
|
165
|
-
awesome!
|
167
|
+
awesome! Note that this approach is the only way to capture calls to class methods.
|
166
168
|
|
167
169
|
You can also try this out with libraries like MD5 for example ...
|
168
170
|
|
@@ -192,6 +194,24 @@ end
|
|
192
194
|
|
193
195
|
Note: If your test subject is already part of a larger application and would like to capture behavior in the manner that the application uses it, please look at [Declarative Generation](#declarative-generation-without-using-example-files).
|
194
196
|
|
197
|
+
### Commandline options
|
198
|
+
If you already have an example file you can also use various command line options.
|
199
|
+
|
200
|
+
passing --help will show these options
|
201
|
+
|
202
|
+
```ruby
|
203
|
+
pretentious --help
|
204
|
+
```
|
205
|
+
|
206
|
+
The command below will generate tests for Meme using the provided example file.
|
207
|
+
|
208
|
+
```ruby
|
209
|
+
pretentious -t Meme sample.rb
|
210
|
+
pretentious -t $/Meme/ sample.rb # generate tests for all classes starting with Meme
|
211
|
+
```
|
212
|
+
|
213
|
+
Note: class methods are not captured using this method
|
214
|
+
|
195
215
|
### Using pretentious.yml
|
196
216
|
If you run pretentious without passing an example file, it will look for pretentious.yml in the current location. Below is an example pretentious.yml file:
|
197
217
|
|
data/bin/pretentious
CHANGED
@@ -33,8 +33,37 @@ def process_file(filename, output_folder, output_subfolder, last_results = nil)
|
|
33
33
|
write_output(output_folder, output_subfolder, last_results)
|
34
34
|
end
|
35
35
|
|
36
|
+
def generate_specs(examples, generators, output_folder, output_subfolder)
|
37
|
+
Pretentious.watch {
|
38
|
+
examples.each do |f|
|
39
|
+
puts "executing target #{f}"
|
40
|
+
eval_example(f)
|
41
|
+
end
|
42
|
+
}
|
43
|
+
|
44
|
+
generator_classes = generators.collect do |g|
|
45
|
+
case g
|
46
|
+
when 'rspec'
|
47
|
+
Pretentious::RspecGenerator
|
48
|
+
when 'minitest'
|
49
|
+
Pretentious::MinitestGenerator
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
per_spec = {}
|
54
|
+
generator_classes.each do |generator_class|
|
55
|
+
puts "generating #{generator_class.to_sym} tests"
|
56
|
+
per_spec[generator_class.to_sym] = Pretentious::LazyTrigger.generate_for_class(generator_class)
|
57
|
+
end
|
58
|
+
per_spec = Pretentious.deep_merge(per_spec, Pretentious.last_results)
|
59
|
+
write_output(output_folder, output_subfolder, per_spec)
|
60
|
+
end
|
61
|
+
|
36
62
|
output_folder = nil
|
37
|
-
output_subfolder =nil
|
63
|
+
output_subfolder = nil
|
64
|
+
targets = nil
|
65
|
+
generators = "rspec"
|
66
|
+
help = false
|
38
67
|
|
39
68
|
# pretentious example.rb -t rspec -o rspec/
|
40
69
|
options = OptionParser.new do |o|
|
@@ -42,8 +71,12 @@ options = OptionParser.new do |o|
|
|
42
71
|
"Usage: pretentious FILENAME [options] # Generates tests using the specified example file\n"
|
43
72
|
o.separator ''
|
44
73
|
o.separator "options:"
|
74
|
+
o.on('-h', '--help', 'show this help module') { help = true }
|
75
|
+
o.on('-t=classnames', '--target=classnames',
|
76
|
+
'target class to generate tests for') { |b| targets = b}
|
77
|
+
o.on('-g=GENERATORS', '--generators=GENERATORS', 'comma separated list of generators to use valid values rspec, minitest (defaults rspec)') { |b| generators = b}
|
45
78
|
o.on('-n=namespace', '--namespace=NAMESPACE',
|
46
|
-
'sub folder to place the generated files in (defaults to generated)') { |b| output_subfolder }
|
79
|
+
'sub folder to place the generated files in (defaults to generated)') { |b| output_subfolder = b }
|
47
80
|
o.on('-o=OUTPUT_DIR', '--output-dir=OUTPUT_DIR',
|
48
81
|
'folder to place the files in -- defaults to spec (RSpec) or test (minitest)') { |b| output_folder = b}
|
49
82
|
o.parse!
|
@@ -51,6 +84,10 @@ end
|
|
51
84
|
|
52
85
|
filename = ARGV[0]
|
53
86
|
|
87
|
+
if help
|
88
|
+
puts options
|
89
|
+
exit(1)
|
90
|
+
end
|
54
91
|
if filename.nil?
|
55
92
|
if File.exists?('pretentious.yml')
|
56
93
|
targets_file = YAML.load_file('pretentious.yml')
|
@@ -64,51 +101,29 @@ if filename.nil?
|
|
64
101
|
end
|
65
102
|
end
|
66
103
|
|
67
|
-
|
68
|
-
|
69
|
-
puts "executing target #{f}"
|
70
|
-
eval_example(f)
|
71
|
-
end
|
72
|
-
}
|
73
|
-
|
74
|
-
generator_classes = targets_file['generators'].collect do |g|
|
75
|
-
case g
|
76
|
-
when 'rspec'
|
77
|
-
Pretentious::RspecGenerator
|
78
|
-
when 'minitest'
|
79
|
-
Pretentious::MinitestGenerator
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
|
-
per_spec = {}
|
84
|
-
generator_classes.each do |generator_class|
|
85
|
-
puts "generating #{generator_class.to_sym} tests"
|
86
|
-
all_results = {}
|
87
|
-
Pretentious::LazyTrigger.collect_targets.each do |target|
|
88
|
-
standin_klass = target.stand_in_klass
|
89
|
-
klass = target.original_klass
|
90
|
-
puts "generate for #{klass}"
|
91
|
-
generator = generator_class.new
|
92
|
-
|
93
|
-
generator.begin_spec(klass)
|
94
|
-
generator.body(standin_klass._instances) unless standin_klass._instances.nil?
|
95
|
-
generator.end_spec
|
104
|
+
examples = targets_file['examples']
|
105
|
+
generators = targets_file['generators']
|
96
106
|
|
97
|
-
|
98
|
-
all_results[klass] = [] if result.nil?
|
99
|
-
|
100
|
-
result_output = generator.output.is_a?(String) ? generator.output.chomp : generator.output
|
101
|
-
all_results[klass] = { output: result_output, generator: generator.class }
|
102
|
-
end
|
103
|
-
per_spec[generator_class.to_sym] = all_results
|
104
|
-
end
|
105
|
-
puts "writing output..."
|
106
|
-
write_output(output_folder, output_subfolder, per_spec)
|
107
|
+
generate_specs examples, generators, output_folder, output_subfolder
|
107
108
|
else
|
108
109
|
puts 'a target or an example file is required.'
|
109
110
|
puts options
|
110
111
|
exit(1)
|
111
112
|
end
|
112
113
|
else
|
113
|
-
|
114
|
+
if !targets.nil?
|
115
|
+
targets.split(',').each do |target|
|
116
|
+
if target.start_with?('$')
|
117
|
+
target[0] = ''
|
118
|
+
Pretentious::LazyTrigger.new(eval(target), {})
|
119
|
+
else
|
120
|
+
puts target
|
121
|
+
Pretentious::LazyTrigger.new(target, {})
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
generate_specs filename.split(','), generators.split(','), output_folder, output_subfolder
|
126
|
+
else
|
127
|
+
process_file(filename, output_folder, output_subfolder)
|
128
|
+
end
|
114
129
|
end
|
data/lib/pretentious.rb
CHANGED
@@ -140,4 +140,10 @@ module Pretentious
|
|
140
140
|
def self.on(target_class)
|
141
141
|
Pretentious::Trigger.new(target_class)
|
142
142
|
end
|
143
|
+
|
144
|
+
# deep merge without active support and does array deep merges as well
|
145
|
+
def self.deep_merge(hash, second)
|
146
|
+
merger = proc { |key, v1, v2| Hash === v1 && Hash === v2 ? v1.merge(v2, &merger) : Array === v1 && Array === v2 ? v1 | v2 : [:undefined, nil, :nil].include?(v2) ? v1 : v2 }
|
147
|
+
hash.merge(second, &merger)
|
148
|
+
end
|
143
149
|
end
|
@@ -372,20 +372,20 @@ module Pretentious
|
|
372
372
|
end
|
373
373
|
|
374
374
|
def self.restore_class(module_space, klass, last_part)
|
375
|
-
module_space.send(:remove_const, "#{last_part}Impostor".to_sym)
|
376
|
-
module_space.send(:remove_const, "#{last_part}".to_sym)
|
375
|
+
module_space.send(:remove_const, "#{last_part}Impostor".to_sym) if Object.const_defined?("#{last_part}Impostor")
|
376
|
+
module_space.send(:remove_const, "#{last_part}".to_sym) if Object.const_defined?(last_part)
|
377
377
|
module_space.const_set(last_part, klass)
|
378
|
-
module_space.send(:remove_const, "#{last_part}_ddt".to_sym)
|
378
|
+
module_space.send(:remove_const, "#{last_part}_ddt".to_sym) if Object.const_defined?("#{last_part}_ddt")
|
379
379
|
end
|
380
380
|
|
381
381
|
def self.generate_for(*klasses_or_instances, &block)
|
382
382
|
all_results = {}
|
383
383
|
klasses = []
|
384
384
|
mock_dict = {}
|
385
|
-
|
385
|
+
lazy_triggers = []
|
386
386
|
klasses_or_instances.each do |klass_or_instance|
|
387
387
|
if klass_or_instance.is_a?(String) || klass_or_instance.is_a?(Regexp)
|
388
|
-
Pretentious::LazyTrigger.new(klass_or_instance, stubs: klass_or_instance._get_stub_classes)
|
388
|
+
lazy_triggers << Pretentious::LazyTrigger.new(klass_or_instance, stubs: klass_or_instance._get_stub_classes)
|
389
389
|
else
|
390
390
|
klass = klass_or_instance.class == Class ? klass_or_instance : klass_or_instance.class
|
391
391
|
klasses << replace_class(klass)
|
@@ -400,16 +400,17 @@ module Pretentious
|
|
400
400
|
end
|
401
401
|
end
|
402
402
|
|
403
|
-
|
404
|
-
|
405
|
-
|
406
|
-
|
407
|
-
|
403
|
+
if !watched?
|
404
|
+
watch_new_instances
|
405
|
+
block.call
|
406
|
+
unwatch_new_instances
|
407
|
+
else
|
408
|
+
block.call
|
409
|
+
end
|
408
410
|
|
409
411
|
# check for lazy triggers, collect and then clean
|
410
412
|
klasses += Pretentious::LazyTrigger.collect_targets.map(&:to_a)
|
411
|
-
|
412
|
-
|
413
|
+
lazy_triggers.each(&:disable!)
|
413
414
|
klasses.each do |module_space, klass, last_part, new_standin_klass|
|
414
415
|
# restore the previous class
|
415
416
|
restore_class module_space, klass, last_part
|
@@ -536,8 +537,12 @@ module Pretentious
|
|
536
537
|
unwatch_new_instances
|
537
538
|
end
|
538
539
|
|
540
|
+
def self.watched?
|
541
|
+
Class.respond_to?(:_ddt_old_new)
|
542
|
+
end
|
543
|
+
|
539
544
|
def self.unwatch_new_instances
|
540
|
-
if
|
545
|
+
if watched?
|
541
546
|
Class.class_eval do
|
542
547
|
remove_method :new
|
543
548
|
alias_method :new, :_ddt_old_new
|
@@ -50,6 +50,27 @@ module Pretentious
|
|
50
50
|
end
|
51
51
|
|
52
52
|
class << self
|
53
|
+
def generate_for_class(generator_class)
|
54
|
+
all_results = {}
|
55
|
+
Pretentious::LazyTrigger.collect_targets.each do |target|
|
56
|
+
standin_klass = target.stand_in_klass
|
57
|
+
klass = target.original_klass
|
58
|
+
puts "generate for #{klass}"
|
59
|
+
generator = generator_class.new
|
60
|
+
|
61
|
+
generator.begin_spec(klass)
|
62
|
+
generator.body(standin_klass._instances) unless standin_klass._instances.nil?
|
63
|
+
generator.end_spec
|
64
|
+
|
65
|
+
result = all_results[klass]
|
66
|
+
all_results[klass] = [] if result.nil?
|
67
|
+
|
68
|
+
result_output = generator.output.is_a?(String) ? generator.output.chomp : generator.output
|
69
|
+
all_results[klass] = { output: result_output, generator: generator.class }
|
70
|
+
end
|
71
|
+
all_results
|
72
|
+
end
|
73
|
+
|
53
74
|
def lookup(class_name)
|
54
75
|
@instances ||= []
|
55
76
|
@instances.each do |instance|
|
data/lib/pretentious/version.rb
CHANGED
data/run_test.sh
CHANGED
@@ -54,7 +54,7 @@ RSpec.describe TestClass1 do
|
|
54
54
|
|
55
55
|
it 'should pass current expectations' do
|
56
56
|
another_object = TestClass1.new('test')
|
57
|
-
# TestClass1#return_self when passed message = #<TestClass1:
|
57
|
+
# TestClass1#return_self when passed message = #<TestClass1:0x000000035de5a0> should return another_object
|
58
58
|
expect(@fixture.return_self(another_object)).to eq(another_object)
|
59
59
|
end
|
60
60
|
end
|
@@ -59,7 +59,7 @@ class TestClass1Scenario3 < TestClass1Test
|
|
59
59
|
def test_current_expectation
|
60
60
|
another_object = TestClass1.new('test')
|
61
61
|
|
62
|
-
# TestClass1#return_self when passed message = #<TestClass1:
|
62
|
+
# TestClass1#return_self when passed message = #<TestClass1:0x00000003727830> should return another_object
|
63
63
|
assert_equal another_object, @fixture.return_self(another_object)
|
64
64
|
end
|
65
65
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: pretentious
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joseph Emmanuel Dayo
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2016-01-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: binding_of_caller
|