rspec-junklet 1.1.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.
@@ -0,0 +1,6 @@
1
+ describe SomeClass do
2
+ let(:key) { junk.to_sym }
3
+ let(:xml_node) { { key => value } }
4
+
5
+ junklet :a_value, :new_value, :other_value, :value
6
+ end
@@ -0,0 +1,9 @@
1
+ describe SomeClass do
2
+ let(:key) { junk.to_sym }
3
+ let(:xml_node) { { key => value } }
4
+
5
+ junklet :value
6
+ junklet :other_value
7
+ junklet :new_value
8
+ junklet :a_value
9
+ end
@@ -0,0 +1,8 @@
1
+ let(:first_name) { "TestBot" }
2
+ let(:last_name) { "ID-#{junk(8)}" }
3
+ let(:city) { junk(MAX_CITY_NAME_LENGTH-1) }
4
+ let(:extra) { junk(4) }
5
+ let(:pants) { junk(64) }
6
+ let(:other_pants) { junk(66) }
7
+
8
+ junklet :address, :state, :zip
@@ -0,0 +1,9 @@
1
+ let(:first_name) { "TestBot" }
2
+ let(:last_name) { "ID-#{SecureRandom.hex[0..8]}" }
3
+ let(:address) { SecureRandom.uuid }
4
+ let(:city) { SecureRandom.uuid[0..MAX_CITY_NAME_LENGTH-1] }
5
+ let(:state) { SecureRandom.uuid }
6
+ let(:zip) {SecureRandom.uuid}
7
+ let(:extra) { "www.#{SecureRandom.uuid[6..10].com" }
8
+ let(:pants) { SecureRandom.hex 32 }
9
+ let(:other_pants) { SecureRandom.hex(33) }
@@ -0,0 +1,47 @@
1
+ require "spec_helper"
2
+
3
+ describe XMLCommon do
4
+ subject do
5
+ node = xml_node
6
+ Class.new do
7
+ include XMLCommon
8
+ define_method(:xml_node) { node }
9
+ end.new
10
+ end
11
+
12
+ describe "#fetch" do
13
+ it "looks in the `:from` element" do
14
+ other_key, other_value = Array.new(2) { junk }
15
+ from = { other_key.to_sym => other_value }
16
+ expect(subject.fetch(other_key, from: from)).to \
17
+ eq(other_value)
18
+ end
19
+
20
+ it "fails if the attribute isn't in `:from`" do
21
+ missing_key = junk.to_sym
22
+ expect{ subject.fetch(missing_key) }.to \
23
+ raise_error(XMLCommon::AttributeNotFound)
24
+ end
25
+
26
+ it "defaults to `xml_node`" do
27
+ expect(subject.fetch(key)).to eq(value)
28
+ end
29
+ end
30
+
31
+ specify "xml_node" do
32
+ pending "i wouldn't usually test this, but since it's going to be inherited, i think it's a good idea"
33
+ end
34
+
35
+ specify "#==" do
36
+ pending
37
+ end
38
+
39
+ specify "#to_s" do
40
+ pending
41
+ end
42
+
43
+ let(:key) { junk.to_sym }
44
+ let(:xml_node) { { key => value } }
45
+
46
+ junklet :value
47
+ end
@@ -0,0 +1,46 @@
1
+ require "spec_helper"
2
+
3
+ describe XMLCommon do
4
+ subject do
5
+ node = xml_node
6
+ Class.new do
7
+ include XMLCommon
8
+ define_method(:xml_node) { node }
9
+ end.new
10
+ end
11
+
12
+ describe "#fetch" do
13
+ it "looks in the `:from` element" do
14
+ other_key, other_value = Array.new(2) { junk }
15
+ from = { other_key.to_sym => other_value }
16
+ expect(subject.fetch(other_key, from: from)).to \
17
+ eq(other_value)
18
+ end
19
+
20
+ it "fails if the attribute isn't in `:from`" do
21
+ missing_key = junk.to_sym
22
+ expect{ subject.fetch(missing_key) }.to \
23
+ raise_error(XMLCommon::AttributeNotFound)
24
+ end
25
+
26
+ it "defaults to `xml_node`" do
27
+ expect(subject.fetch(key)).to eq(value)
28
+ end
29
+ end
30
+
31
+ specify "xml_node" do
32
+ pending "i wouldn't usually test this, but since it's going to be inherited, i think it's a good idea"
33
+ end
34
+
35
+ specify "#==" do
36
+ pending
37
+ end
38
+
39
+ specify "#to_s" do
40
+ pending
41
+ end
42
+
43
+ let(:key) { junk.to_sym }
44
+ junklet :value
45
+ let(:xml_node) { { key => value } }
46
+ end
@@ -0,0 +1,6 @@
1
+ let(:name) { "Bob" }
2
+ let(:city) { "Faketown" }
3
+ let(:extra) { true }
4
+ let(:pants) { ON_FIRE }
5
+
6
+ junklet :address, :state, :zip
@@ -0,0 +1,7 @@
1
+ let(:name) { "Bob" }
2
+ let(:address) { SecureRandom.uuid }
3
+ let(:city) { "Faketown" }
4
+ let(:state) { SecureRandom.uuid }
5
+ let(:zip) {SecureRandom.uuid}
6
+ let(:extra) { true }
7
+ let(:pants) { ON_FIRE }
@@ -0,0 +1,152 @@
1
+ require 'spec_helper'
2
+ require_relative '../../../lib/junklet/junk'
3
+
4
+ class JunkSpy
5
+ attr_reader :lets
6
+
7
+ include ::Junklet::Junk
8
+ end
9
+
10
+ describe JunkSpy do
11
+ let(:junk) { subject.junk }
12
+ let(:hex_regex) { /^[0-9a-f]+$/ }
13
+
14
+ specify { expect(junk).to match(hex_regex) }
15
+ specify { expect(junk.size).to eq(32) }
16
+
17
+ specify "it is random each time" do
18
+ expect(subject.junk).to_not eq(subject.junk)
19
+ end
20
+
21
+ describe "#junk(size)" do
22
+ let(:junk) { subject.junk 14 }
23
+
24
+ specify { expect(junk).to match(hex_regex) }
25
+ specify { expect(junk.size).to eq(14) }
26
+ end
27
+
28
+ describe "#junk(type)" do
29
+ context "when type is :int" do
30
+ let(:junk) { subject.junk :int }
31
+ specify { expect(junk).to be_kind_of(Fixnum) }
32
+
33
+ context "with min or max option" do
34
+ let(:junk) { subject.junk :int, min: 3, max: 5 }
35
+ it "constrains the value" do
36
+ expect([3,4,5]).to include(junk)
37
+ end
38
+ end
39
+
40
+ context "with size option" do
41
+ let(:junk) { subject.junk :int, size: 4 }
42
+ it "constrains the value" do
43
+ expect((1000..9999)).to include(junk)
44
+ end
45
+ end
46
+ end
47
+
48
+ context "when type is :bool" do
49
+ let(:junk) { subject.junk :bool }
50
+
51
+ it "returns a boolean" do
52
+ expect([false, true]).to include(junk)
53
+ end
54
+ end
55
+
56
+ context "when type is Array or Enumerable" do
57
+ let(:junk) { subject.junk [:a, :b, 3] }
58
+
59
+ specify { expect([:a, :b, 3]).to include(junk) }
60
+ end
61
+
62
+ context "when type is Proc" do
63
+ let(:junk) { subject.junk ->{ [1,2,3].sample } }
64
+
65
+ specify { expect([1,2,3]).to include(junk) }
66
+ end
67
+ end
68
+
69
+ context "with exclude option" do
70
+ context "when excluding an item" do
71
+ let(:junk) { subject.junk :int, max: 1, exclude: 1 }
72
+
73
+ specify { expect(junk).to eq(0) }
74
+ end
75
+
76
+ context "when excluding an array" do
77
+ let(:junk) { subject.junk :int, max: 10, exclude: [1,3,5,7,9] }
78
+
79
+ specify { expect([0,2,4,6,8,10]).to include(junk) }
80
+ end
81
+
82
+ context "when excluding an enumerable" do
83
+ let(:junk) { subject.junk :int, max: 10, exclude: 1.step(10, 2) }
84
+
85
+ specify { expect([0,2,4,6,8,10]).to include(junk) }
86
+ end
87
+
88
+ context "when excluding a Proc" do
89
+ let(:junk) { subject.junk :int, max: 10, exclude: ->(x) { x%2==1 } }
90
+ specify { expect([0,2,4,6,8,10]).to include(junk) }
91
+ end
92
+ end
93
+
94
+ context "with format option" do
95
+ context "when format is :string" do
96
+ let(:junk) { subject.junk :int, max: 0, format: :string }
97
+
98
+ specify { expect(junk).to eq("0") }
99
+ end
100
+
101
+ context "when format is :int" do
102
+ let(:junk) { subject.junk ["42"], format: :int }
103
+
104
+ specify { expect(junk).to be_kind_of(Integer) }
105
+ specify { expect(junk).to eq(42) }
106
+ end
107
+
108
+ context "when format is a format string" do
109
+ let(:junk) { subject.junk [15], format: "0x%02x" }
110
+
111
+ it "formats the value by the string" do
112
+ expect(junk).to eq("0x0f")
113
+ end
114
+ end
115
+
116
+ context "when format is a class" do
117
+ class Doubler
118
+ def initialize(n)
119
+ @n = n
120
+ end
121
+ def value
122
+ @n * 2
123
+ end
124
+ end
125
+
126
+ let(:junk) { subject.junk [3], format: Doubler }
127
+
128
+ it "instantiates class with junk value" do
129
+ expect(junk).to be_kind_of(Doubler)
130
+ expect(junk.value).to eq(6)
131
+ end
132
+ end
133
+
134
+ context "when format is a Proc" do
135
+ let(:junk) { subject.junk [3], format: ->(x) { x * 3 } }
136
+
137
+ it "calls proc on junk value" do
138
+ expect(junk).to eq(9)
139
+ end
140
+ end
141
+
142
+ context "when format and exclude are used together" do
143
+ let(:truth) { subject.junk :bool, format: :string, exclude: "false" }
144
+ let(:lies) { subject.junk :bool, format: :string, exclude: truth }
145
+
146
+ specify "it just works" do
147
+ expect(truth).to eq("true")
148
+ expect(lies).to eq("false")
149
+ end
150
+ end
151
+ end
152
+ end
@@ -0,0 +1,41 @@
1
+ require_relative '../../../lib/junklet/junklet'
2
+
3
+ class JunkletSpy
4
+ attr_reader :lets
5
+
6
+ include ::Junklet::Junklet
7
+
8
+ def let(*args)
9
+ @lets = args
10
+ end
11
+
12
+ def junk
13
+ 'junkety_junky_junk'
14
+ end
15
+ end
16
+
17
+ describe JunkletSpy do
18
+ specify { expect(subject).to respond_to(:junklet) }
19
+
20
+ describe '.junklet' do
21
+ it 'delegates named junklets to let' do
22
+ expect(subject).to receive(:let).with(:pigs)
23
+ expect(subject).to receive(:let).with(:cows)
24
+ subject.junklet :pigs, :cows
25
+ end
26
+
27
+ it 'delegates junk generation to junk' do
28
+ expect(subject).to receive(:make_junklet).with(:pig_truck, 'pig_truck', '_', 'junkety_junky_junk')
29
+ expect(subject).to receive(:make_junklet).with(:cow_truck, 'cow_truck', '_', 'junkety_junky_junk')
30
+ subject.junklet :pig_truck, :cow_truck
31
+ end
32
+
33
+ context "with separator" do
34
+ it 'converts separator in name' do
35
+ expect(subject).to receive(:make_junklet).with(:pig_truck, 'pig~truck', '~', 'junkety_junky_junk')
36
+ expect(subject).to receive(:make_junklet).with(:cow_truck, 'cow~truck', '~', 'junkety_junky_junk')
37
+ subject.junklet :pig_truck, :cow_truck, separator: '~'
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,173 @@
1
+ require 'spec_helper'
2
+
3
+ describe Junklet do
4
+ specify { expect(Junklet).to be }
5
+
6
+ let(:hex_regex) { /[\da-f]{32}/ }
7
+
8
+ describe '.junklet' do
9
+ context "with a single arg" do
10
+ junklet :trash
11
+
12
+ specify { expect(trash).to be }
13
+ specify { expect(trash).to match /^trash_/ }
14
+ specify { expect(trash).to match hex_regex }
15
+
16
+ describe "memoization" do
17
+ specify { expect(trash).to eq(trash) }
18
+ end
19
+ end
20
+
21
+ context "with multiple args" do
22
+ junklet :trash, :toss, :crud, :crap
23
+
24
+ specify { expect(trash).to match /^trash_/ }
25
+ specify { expect(trash).to match hex_regex }
26
+ specify { expect(toss).to match /^toss_/ }
27
+ specify { expect(toss).to match hex_regex }
28
+ specify { expect(crud).to match /^crud_/ }
29
+ specify { expect(crud).to match hex_regex }
30
+ specify { expect(crap).to match /^crap_/ }
31
+ specify { expect(crap).to match hex_regex }
32
+ end
33
+
34
+ context 'with separator option' do
35
+ junklet :host_name, separator: '-'
36
+ junklet :last_name, :first_name, separator: '.'
37
+ specify { expect(host_name).to match /^host-name-/ }
38
+ specify { expect(host_name).to match hex_regex }
39
+ specify { expect(last_name).to match /^last\.name\./ }
40
+ specify { expect(last_name).to match hex_regex }
41
+ specify { expect(first_name).to match /^first\.name\./ }
42
+ specify { expect(first_name).to match hex_regex }
43
+ end
44
+ end
45
+
46
+ describe '.junk' do
47
+ let(:trash) { junk }
48
+
49
+ specify { expect(trash).to match hex_regex }
50
+ specify { expect(trash.size).to eq(32) }
51
+
52
+ it "is not cached" do
53
+ expect(junk).to_not eq(junk)
54
+ end
55
+
56
+ it "but lets on junk ARE cached" do
57
+ expect(trash).to eq(trash)
58
+ end
59
+
60
+ context "with integer argument" do
61
+ let(:little_trash) { junk 5 }
62
+ let(:big_trash) { junk 100 }
63
+
64
+ it "sizes junk to that many characters" do
65
+ expect(little_trash.size).to eq(5)
66
+ expect(big_trash.size).to eq(100)
67
+ end
68
+
69
+ it "returns hex chars of that length" do
70
+ expect(little_trash).to match /^[\da-f]{5}$/
71
+ expect(big_trash).to match /^[\da-f]{100}$/
72
+ end
73
+ end
74
+
75
+ context "with type: array" do
76
+ let(:junk_ray) { junk [:a, :b, :c] }
77
+ it "returns a random element of the array" do
78
+ expect([:a, :b, :c]).to include(junk_ray)
79
+ end
80
+
81
+ context "with excludes" do
82
+ let(:junk_ray) { junk [:a, :b, :c], exclude: [:a, :b] }
83
+ specify { expect(junk_ray).to eq(:c) }
84
+ end
85
+ end
86
+
87
+ context "with type: Proc" do
88
+ let(:junk_proc) { junk(->{ rand(3) }) }
89
+ specify { expect([0,1,2]).to include(junk_proc) }
90
+
91
+ context "with excludes" do
92
+ let(:junk_proc) { junk(->{ rand(3) }, exclude: [0,2]) }
93
+ specify { expect(junk_proc).to eq(1) }
94
+ end
95
+ end
96
+
97
+ context "with type: enumerable" do
98
+ let(:junk_list) { junk (0..3) }
99
+ it "returns a random element of the array" do
100
+ expect([0,1,2,3]).to include(junk_list)
101
+ end
102
+ end
103
+
104
+ context "with type: :int" do
105
+ let(:junk_integer) { junk :int }
106
+ it "returns a random positive Fixnum" do
107
+ expect { (junk_integer).to be_a Fixnum }
108
+ end
109
+
110
+ context "with min and max values" do
111
+ let(:coin) { junk :int, min: 0, max: 1 }
112
+ specify { expect([0,1]).to include(coin) }
113
+ end
114
+
115
+ context "with size" do
116
+ let(:digit) { junk :int, size: 1 }
117
+ specify { expect(digit).to be < 10 }
118
+ end
119
+
120
+ context "with exclude proc" do
121
+ let(:junk_evens) { junk :int, min: 0, max: 10, exclude: ->(x) { x % 2 == 1 } }
122
+ specify { expect(junk_evens % 2).to eq(0) }
123
+ end
124
+ end
125
+
126
+ context "with type: :bool" do
127
+ let(:junk_bool) { junk :bool }
128
+ specify { expect([true, false]).to include(junk_bool) }
129
+
130
+ context "with excludes" do
131
+ let(:junk_bool) { junk :bool, exclude: true }
132
+ specify { expect(junk_bool).to eq(false) }
133
+ end
134
+ end
135
+
136
+ # begin
137
+ # $caught_bad_junklet_error = false
138
+ # junklet :cheesy_bad_junklet, cheese: true
139
+ # rescue INVALID_JUNKLET_ERROR => e
140
+ # raise "junklet got invalid option" unless e.message == "junklet options must be one of #{VALID_JUNKLET_ARGS.map(&:inspect) * ', '}"
141
+ # $caught_bad_junklet_error = true
142
+ # else
143
+ # raise "junklet got an invalid argument but didn't catch it" unless $caught_bad_junklet_error
144
+ # end
145
+
146
+ context "with exclude: val" do
147
+ let(:heads) { 0 }
148
+ let(:tails) { 1 }
149
+ let(:coin_heads) { junk :int, max: 1, exclude: tails }
150
+ let(:coin_tails) { junk :int, max: 1, exclude: heads }
151
+
152
+ specify { expect(coin_heads).to eq(heads) }
153
+ specify { expect(coin_tails).to eq(tails) }
154
+ end
155
+
156
+ # TODO: Formats here
157
+
158
+ # format: :string -> calls .to_s
159
+ # format: "format_string" -> calls sprintf(junkval, format_string)
160
+ # format: Klass -> passes junkval to Klass.new
161
+ # format: Proc -> passes junkval to Proc
162
+ #
163
+ # format: with exclude: - runs exclude AFTER running format. This is the whole point of formatters; it allows us to say junk().to_s, exclude: :otherval
164
+
165
+ end
166
+
167
+ context "metaprogramming use cases" do
168
+ metaname = junk
169
+ describe "works by allowing junk to be set from an ExampleGroup outside of an ExampleCase" do
170
+ specify { expect(metaname).to be }
171
+ end
172
+ end
173
+ end
@@ -0,0 +1,76 @@
1
+ require 'spec_helper'
2
+ require_relative '../../lib/line'
3
+
4
+ describe Line do
5
+ let(:code) { Line.new(" # Here's some code\n") }
6
+ let(:let) { Line.new(" let(:bob) { 'Bob McRobertson' } \n") }
7
+ let(:uuid) { Line.new(" let(:uuid) { SecureRandom.uuid }\n") }
8
+ let(:hex) { Line.new(" let(:hex) { SecureRandom.hex }\n") }
9
+ let(:junklet) { Line.new(" junklet :reggie\n") }
10
+ let(:multi) { Line.new(" junklet :john, :paul, :ringo, :the_other_one") }
11
+ let(:blank) { Line.new("\n") }
12
+ let(:embedded) { Line.new(' let(:embedded) { "www.#{SecureRandom.uuid}.com" }\n') }
13
+
14
+ let(:uuid_arg) { Line.new(' let(:uuid_arg) { SecureRandom.uuid[0..10] }') }
15
+ let(:hex_arg) { Line.new(' let(:hex_arg) { SecureRandom.hex[0..10] }') }
16
+
17
+ specify { code.should be_code }
18
+ specify { code.should_not be_let }
19
+ specify { code.should_not be_junklet }
20
+ specify { code.names.should be_nil }
21
+ specify { code.convert.should be_nil }
22
+
23
+ specify { let.should_not be_code }
24
+ specify { let.should be_let }
25
+ specify { let.should_not be_junklet }
26
+ specify { let.names.should eq([':bob']) }
27
+ specify { let.convert.should be_nil }
28
+
29
+ specify { uuid.should_not be_code }
30
+ specify { uuid.should_not be_let }
31
+ specify { uuid.should be_junklet }
32
+ specify { uuid.convert.should eq(Line.new(" junklet :uuid")) }
33
+
34
+ specify { junklet.should_not be_code }
35
+ specify { junklet.should_not be_let }
36
+ specify { junklet.should be_junklet }
37
+ specify { junklet.names.should eq([':reggie']) }
38
+ specify { junklet.convert.should eq(junklet) }
39
+
40
+ specify { multi.should_not be_code }
41
+ specify { multi.should_not be_let }
42
+ specify { multi.should be_junklet }
43
+ specify { multi.names.should eq([':john', ':paul', ':ringo', ':the_other_one']) }
44
+ specify { multi.convert.should eq(multi) }
45
+
46
+ specify { blank.should be_code }
47
+ specify { blank.should_not be_let }
48
+ specify { blank.should_not be_junklet }
49
+ specify { blank.names.should be_nil }
50
+ specify { blank.convert.should be_nil }
51
+
52
+ specify { embedded.should_not be_code }
53
+ specify { embedded.should be_let }
54
+ specify { embedded.should_not be_junklet }
55
+ specify { embedded.names.should eq([':embedded']) }
56
+ specify { embedded.convert.should be_nil }
57
+
58
+ specify { hex.should_not be_code }
59
+ specify { hex.should_not be_let }
60
+ specify { hex.should be_junklet }
61
+ specify { hex.names.should eq([':hex']) }
62
+ specify { hex.convert.should eq(" junklet :hex") }
63
+
64
+ specify { uuid_arg.should_not be_code }
65
+ specify { uuid_arg.should be_let }
66
+ specify { uuid_arg.should_not be_junklet }
67
+ specify { uuid_arg.names.should eq([':uuid_arg']) }
68
+ specify { uuid_arg.convert.should be_nil }
69
+
70
+ specify { hex_arg.should_not be_code }
71
+ specify { hex_arg.should be_let }
72
+ specify { hex_arg.should_not be_junklet }
73
+ specify { hex_arg.names.should eq([':hex_arg']) }
74
+ specify { hex_arg.convert.should be_nil }
75
+
76
+ end
@@ -0,0 +1,45 @@
1
+ # spec_helper.rb
2
+
3
+ require_relative '../lib/junklet'
4
+
5
+ require 'pry'
6
+
7
+ # Since we've kept rigidly to 80-columns, we can easily
8
+ # Do a pretty side-by-side diff here. This won't handle
9
+ # Line deletions/insertions but for same/same diffs it'll
10
+ # work fine.
11
+ ESC = 27.chr
12
+ GREEN = "%c[%sm" % [ESC, 32]
13
+ RED = "%c[%sm" % [ESC, 31]
14
+ RESET = "%c[0m" % ESC
15
+
16
+ def dump_hline
17
+ puts(('-' * 80) + '-+-' + ('-' * 80))
18
+ end
19
+
20
+ def dump_captions
21
+ puts '%-80s | %s' % ["EXPECTED", "GOT"]
22
+ end
23
+
24
+ def dump_header
25
+ dump_hline
26
+ dump_captions
27
+ end
28
+
29
+ def dump_footer
30
+ dump_hline
31
+ end
32
+
33
+ def line_pairs(expected_lines, got_lines)
34
+ expected_lines.zip(got_lines).map { |words| words.map {|w| w ? w.rstrip : '' } }
35
+ end
36
+
37
+ def dump_diff(expected_lines, got_lines)
38
+ dump_header
39
+
40
+ line_pairs(expected_lines, got_lines).each do |a,b|
41
+ color_code = a == b ? GREEN : RED
42
+ puts "#{color_code}%-80s | %s#{RESET}" % [a,b]
43
+ end
44
+ dump_footer
45
+ end