rspec-junklet 1.1.0 → 1.1.1

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 CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZWQwYjZkZmNlNjlkNmM0MTE2YTMyNzBmYTEwMjU0MThjMjNlYzUzMA==
4
+ ZGY1MjM2NDliN2U1MWUxYTc0ZWQzYmM1YzgwY2EwOWZmYTI0NmIyMg==
5
5
  data.tar.gz: !binary |-
6
- MjQwNmUwNzQxYTljYWQ1NjhiMTgxNzU0NTk0NzNjNTk4MDhkYjdkNg==
6
+ ZTRmMGFmMWM3MzVkNjQ4N2Q2MmQ1M2U1OTg5ZThhODgyMDQxMGI0MQ==
7
7
  SHA512:
8
8
  metadata.gz: !binary |-
9
- ZTFlNmUzYTRhNzgzNjQyNjViZjA4YWNmYzI5Mjk4NWQ3N2VmNDhkYjZmNzIx
10
- NmM5MWE5MDkzNzk1Y2E2YmM2MTEyM2U2YWI0YTU4NjVkOTA1MTdiYjNhZGFj
11
- MThhZjU2MWY2ZDRhYTI2ODQ4MTI2YzJkZmM1NTM0ODJiM2Q1YmQ=
9
+ ZDU5OTYxZGQwMmY3NWQ1MDM2NDU5MTU3ODA2NzE3OTJhMWMzNTM4OGM2YWVj
10
+ MTE5NTE2MTY4OTZjYTcxMDQ2ZDQ2YTdlOTdjZWUwNmI0ZTRiMDQ2N2M1MjY5
11
+ MjBlYmUxMGJiNmY5ZjlmOGNkYzMxZjE3NjIwMjdiNzJhY2FjNDg=
12
12
  data.tar.gz: !binary |-
13
- OWY2NjNiNmY2ZDM1NTVlNWNmODNmZDIxMGNjODI1N2Y2M2MzMmJkOWY4Nzc4
14
- NDY1NTFjZmFjZjU1NjA2YmJiZWI3NzUyYzQ0ZjZmZjYxNjIxYmJlMThkM2Y5
15
- OTYyMjA0ZjEwMTk5MGU1ZmQ2N2UxYWZjMmVlYjQyZWEyZWM4NDQ=
13
+ MWNlM2E0NzAyNWVhODBkMDBmMjljZDc0MDNkZjViMTZkMTc3ZjRkOWJlYmIw
14
+ ZGJiZWJhZGNjZGQ1MjdiMzBlMjRhZmI4YmJjNDhlZmFhYzEzOWE3YjZiMTcw
15
+ OGYwY2IzYzkwNDE5YTMwZGUwMDdjYTYzNTExNDBmMzM5YTI3NmE=
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rspec-junklet (1.0.4)
4
+ rspec-junklet (1.1.0)
5
5
 
6
6
  GEM
7
7
  remote: https://rubygems.org/
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
- Formats are here, but need documentating! For now: `format: :int` will cast your
236
- junk to an integer by calling `.to_i` on it. Other formats include:
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`. *Note:* If you plan on combining this with `exclude`, make
244
- sure your class implements the `==` operator.
245
- * `format: ->(x) { ... }` passes the junk to your Proc
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
 
@@ -0,0 +1,14 @@
1
+ module Junklet
2
+ class Formatter
3
+ attr_reader :input
4
+
5
+ def initialize(input)
6
+ @input = input
7
+ end
8
+
9
+ # You probably want to override this
10
+ def format
11
+ input
12
+ end
13
+ end
14
+ end
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
@@ -1,3 +1,3 @@
1
1
  module Junklet
2
- VERSION = "1.1.0"
2
+ VERSION = "1.1.1"
3
3
  end
@@ -113,24 +113,63 @@ describe JunkSpy do
113
113
  end
114
114
  end
115
115
 
116
- context "when format is a class" do
117
- class Doubler
118
- def initialize(n)
119
- @n = n
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 [3], format: Doubler }
150
+ let(:junk) { subject.junk [12], format: HexDoubler }
127
151
 
128
- it "instantiates class with junk value" do
129
- expect(junk).to be_kind_of(Doubler)
130
- expect(junk.value).to eq(6)
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.0
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-20 00:00:00.000000000 Z
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