rspec-junklet 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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