rspec-junklet 1.1.0 → 1.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +8 -8
- data/Gemfile.lock +1 -1
- data/README.md +75 -5
- data/lib/junklet/formatter.rb +14 -0
- data/lib/junklet/junk.rb +26 -2
- data/lib/junklet/version.rb +1 -1
- data/spec/lib/junklet/junk_spec.rb +47 -8
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
ZGY1MjM2NDliN2U1MWUxYTc0ZWQzYmM1YzgwY2EwOWZmYTI0NmIyMg==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
ZTRmMGFmMWM3MzVkNjQ4N2Q2MmQ1M2U1OTg5ZThhODgyMDQxMGI0MQ==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
ZDU5OTYxZGQwMmY3NWQ1MDM2NDU5MTU3ODA2NzE3OTJhMWMzNTM4OGM2YWVj
|
10
|
+
MTE5NTE2MTY4OTZjYTcxMDQ2ZDQ2YTdlOTdjZWUwNmI0ZTRiMDQ2N2M1MjY5
|
11
|
+
MjBlYmUxMGJiNmY5ZjlmOGNkYzMxZjE3NjIwMjdiNzJhY2FjNDg=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
MWNlM2E0NzAyNWVhODBkMDBmMjljZDc0MDNkZjViMTZkMTc3ZjRkOWJlYmIw
|
14
|
+
ZGJiZWJhZGNjZGQ1MjdiMzBlMjRhZmI4YmJjNDhlZmFhYzEzOWE3YjZiMTcw
|
15
|
+
OGYwY2IzYzkwNDE5YTMwZGUwMDdjYTYzNTExNDBmMzM5YTI3NmE=
|
data/Gemfile.lock
CHANGED
data/README.md
CHANGED
@@ -232,17 +232,87 @@ key space, junk will cheerfully go into an infinite loop.
|
|
232
232
|
|
233
233
|
### Format
|
234
234
|
|
235
|
-
|
236
|
-
|
235
|
+
A format can be applied to junk data after generation. This lets you change the
|
236
|
+
class or representation of the junk. For example, this feature was added because
|
237
|
+
we needed 6-digit decimal ids... represented as strings. Originally I wrote
|
238
|
+
|
239
|
+
```ruby
|
240
|
+
let(:drug_id) { junk( ->{ junk(:int, size: 6).to_s } ) }
|
241
|
+
```
|
242
|
+
|
243
|
+
But now I can just say
|
244
|
+
|
245
|
+
```ruby
|
246
|
+
let(:drug_id) { junk(:int, size: 6, format: :string) }
|
247
|
+
```
|
248
|
+
Here are the available formats:
|
237
249
|
|
238
250
|
* `format: :int` calls `.to_i` on the junk before returning it
|
239
251
|
* `format: :string` calls `.to_s` on the junk
|
240
252
|
* `format: "%s"` (or any other string) calls sprintf on the junk with the
|
241
253
|
string as the format string
|
242
254
|
* `format: SomeClass` passes the junk to `SomeClass.new`, returning an instance
|
243
|
-
of `SomeClass`. *
|
244
|
-
|
245
|
-
|
255
|
+
of `SomeClass`. *Important:* This class must implement a `#format` method
|
256
|
+
which returns the formatted junk. See the `::Junklet::Formatter` class for an
|
257
|
+
example class that simply returns the unmodified junk.
|
258
|
+
* `format: ->(x) { ... }` passes the junk to your Proc; whatever you return is
|
259
|
+
the value of the junk. This is obviously the most powerful transform as it can
|
260
|
+
return anything at all; there's nothing stopping you from using the format
|
261
|
+
proc as the generator itself aside from the constraints of good taste. ;-) If
|
262
|
+
you _were_ to exhibit poor taste, one conceivable (yet still very strained)
|
263
|
+
example might be `junk :int, format: ->(x) { srand(x); rand }` but it's not
|
264
|
+
really a very far stretch to generate, say, a random index in the generator
|
265
|
+
and use the formatter to map it to a dictionary word or some other very wild
|
266
|
+
transformation.
|
267
|
+
|
268
|
+
### Formatter Classes
|
269
|
+
|
270
|
+
The careful reader will have noted by now that you can pass a class name as a
|
271
|
+
format. This is intended to be a Formatter class. A Formatter class takes the
|
272
|
+
generated junk in its initialize method. If the class implements `#format`, this
|
273
|
+
method will be called and the return value of this method will be the junk
|
274
|
+
data. If the class does not implement `#format`, the Formatter object itself
|
275
|
+
will be returned and you can use it how you see fit. It's probably a good idea
|
276
|
+
to implement `#to_s` if your formatter is going to wind up in a string
|
277
|
+
somewhere.
|
278
|
+
|
279
|
+
So for example, let's say you want to generate a ZIP+4 code. That's a 5-digit
|
280
|
+
decimal number, a hyphen, and a 4-digit decimal. This whole mess is then
|
281
|
+
represented as a string. You could do this with a simple lambda:
|
282
|
+
|
283
|
+
```ruby
|
284
|
+
let(:zip) { junk :int, size: 9, format: ->(x) { '%d-%d' % [x/10000, x%10000] } }
|
285
|
+
```
|
286
|
+
|
287
|
+
...but if you're going to be generating ZIP codes regularly, a formatter class
|
288
|
+
is probably in order:
|
289
|
+
|
290
|
+
```ruby
|
291
|
+
class Format::ZipCode
|
292
|
+
attr_reader :code
|
293
|
+
def initialize(code)
|
294
|
+
@code = code
|
295
|
+
end
|
296
|
+
|
297
|
+
def format
|
298
|
+
'%d-%d' % [x/10000, x%10000]
|
299
|
+
end
|
300
|
+
end
|
301
|
+
```
|
302
|
+
|
303
|
+
Now your junk uses the class as designed:
|
304
|
+
|
305
|
+
```ruby
|
306
|
+
let(:zip) { junk :int, size: 9, format: Format::ZipCode }
|
307
|
+
```
|
308
|
+
|
309
|
+
TODO: Hrm, if I'm going to do to that much trouble, why not have an entire junk
|
310
|
+
generation class? E.g. include the generator with the formatter, so that we can
|
311
|
+
just say
|
312
|
+
|
313
|
+
```ruby
|
314
|
+
let(:zip) { junk ZipCode }
|
315
|
+
```
|
246
316
|
|
247
317
|
# TODO
|
248
318
|
|
data/lib/junklet/junk.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require_relative 'formatter'
|
2
|
+
|
1
3
|
module Junklet
|
2
4
|
module Junk
|
3
5
|
def junk(*args)
|
@@ -26,6 +28,26 @@ module Junklet
|
|
26
28
|
# the Proc an excludes it if the Proc returns true. This
|
27
29
|
# is implemented except for the proc.
|
28
30
|
|
31
|
+
# FIXME: Would be nice to be able to say, e.g. `junk exclude: bob` but
|
32
|
+
# currently this breaks because {exclude: bob} is a Hash which is
|
33
|
+
# an Enumerable which means it's a valid generator. I don't want to
|
34
|
+
# just disallow hashes as generators here. What's a good workaround
|
35
|
+
# for when I really do just want junk with either a format or an
|
36
|
+
# exclusion? `junk :junk, exclude: bob` looks bad. `junk _,
|
37
|
+
# exclude: bob` is also pretty bad.
|
38
|
+
#
|
39
|
+
# Hmm, I'm tempted to say "the one enumerable you CAN'T have is a
|
40
|
+
# Hash, so it can be the options hash; if you DO want to pass in a
|
41
|
+
# hash, you must cast it to an array or yield it from a Proc
|
42
|
+
# instead". Given that the hash case is weird and rare enough, I
|
43
|
+
# think this is acceptable. Oh, if only I didn't have to maintain
|
44
|
+
# backwards compatibility with older Rubies, I could just make
|
45
|
+
# these keyword args. Sigh.
|
46
|
+
|
47
|
+
# FIXME: This whole darn method is outta control, and for the record none
|
48
|
+
# of the cool excluders and formatters work with the
|
49
|
+
# SecureRandom.hex default. Barf.
|
50
|
+
|
29
51
|
# FIXME: Raise Argument error unless *args.size is 0-2
|
30
52
|
# FIXME: If arg 1 is a hash, it's the options hash, raise
|
31
53
|
# ArgumentError unless args.size == 1
|
@@ -54,10 +76,12 @@ module Junklet
|
|
54
76
|
->(x) { x.to_s }
|
55
77
|
when :int
|
56
78
|
->(x) { x.to_i }
|
79
|
+
when Class
|
80
|
+
raise "Formatter class must implement #format method" unless
|
81
|
+
opts[:format].new(0).respond_to? :format
|
82
|
+
->(x) { opts[:format].new(x).format }
|
57
83
|
when String
|
58
84
|
->(x) { sprintf(opts[:format], x) }
|
59
|
-
when Class
|
60
|
-
->(x) { opts[:format].new(x) }
|
61
85
|
when Proc
|
62
86
|
opts[:format]
|
63
87
|
else
|
data/lib/junklet/version.rb
CHANGED
@@ -113,24 +113,63 @@ describe JunkSpy do
|
|
113
113
|
end
|
114
114
|
end
|
115
115
|
|
116
|
-
context "when format is a
|
117
|
-
class
|
118
|
-
def
|
119
|
-
|
116
|
+
context "when format is a Junklet::Formatter" do
|
117
|
+
class HexTripler < Junklet::Formatter
|
118
|
+
def value
|
119
|
+
input * 3
|
120
|
+
end
|
121
|
+
|
122
|
+
def format
|
123
|
+
"0x%02x" % value
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
let(:junk) { subject.junk [4], format: HexTripler }
|
128
|
+
|
129
|
+
it "delegates to #format" do
|
130
|
+
expect(junk).to be_kind_of(String)
|
131
|
+
expect(junk).to eq("0x0c")
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
135
|
+
context "when format is a class that quacks like Junklet::Formatter" do
|
136
|
+
class HexDoubler
|
137
|
+
def initialize(input)
|
138
|
+
@n = input
|
120
139
|
end
|
140
|
+
|
121
141
|
def value
|
122
142
|
@n * 2
|
123
143
|
end
|
144
|
+
|
145
|
+
def format
|
146
|
+
"0x%04x" % value
|
147
|
+
end
|
124
148
|
end
|
125
149
|
|
126
|
-
let(:junk) { subject.junk [
|
150
|
+
let(:junk) { subject.junk [12], format: HexDoubler }
|
127
151
|
|
128
|
-
it "
|
129
|
-
expect(junk).to be_kind_of(
|
130
|
-
expect(junk
|
152
|
+
it "works as expected" do
|
153
|
+
expect(junk).to be_kind_of(String)
|
154
|
+
expect(junk).to eq("0x0018")
|
131
155
|
end
|
132
156
|
end
|
133
157
|
|
158
|
+
context "but does not implement #value" do
|
159
|
+
class BadDoublerNoFormat
|
160
|
+
def initialize(input)
|
161
|
+
end
|
162
|
+
|
163
|
+
def value
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
let(:junk) { subject.junk [2], format: BadDoublerNoFormat }
|
168
|
+
|
169
|
+
specify { expect { junk }.to raise_error("Formatter class must implement #format method") }
|
170
|
+
end
|
171
|
+
|
172
|
+
|
134
173
|
context "when format is a Proc" do
|
135
174
|
let(:junk) { subject.junk [3], format: ->(x) { x * 3 } }
|
136
175
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: rspec-junklet
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.1.
|
4
|
+
version: 1.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- David Brady
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-02-
|
11
|
+
date: 2015-02-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -95,6 +95,7 @@ files:
|
|
95
95
|
- LICENSE
|
96
96
|
- README.md
|
97
97
|
- lib/junklet.rb
|
98
|
+
- lib/junklet/formatter.rb
|
98
99
|
- lib/junklet/junk.rb
|
99
100
|
- lib/junklet/junklet.rb
|
100
101
|
- lib/junklet/version.rb
|