pretentious 0.2.1 → 0.2.2
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.
- 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
|