rspec-junklet 1.1.1 → 2.0.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.
- checksums.yaml +8 -8
- data/Gemfile.lock +1 -1
- data/lib/rspec/junklet/formatter.rb +16 -0
- data/lib/rspec/junklet/junk.rb +144 -0
- data/lib/rspec/junklet/junklet.rb +27 -0
- data/lib/rspec/junklet/version.rb +5 -0
- data/lib/rspec/junklet.rb +9 -0
- data/rspec-junklet.gemspec +4 -5
- data/spec/lib/{junklet_spec.rb → rspec/examples_spec.rb} +7 -2
- data/spec/lib/{junklet → rspec/junklet}/junk_spec.rb +3 -3
- data/spec/lib/{junklet → rspec/junklet}/junklet_spec.rb +2 -2
- data/spec/spec_helper.rb +8 -5
- metadata +18 -35
- data/lib/junklet/formatter.rb +0 -14
- data/lib/junklet/junk.rb +0 -142
- data/lib/junklet/junklet.rb +0 -25
- data/lib/junklet/version.rb +0 -3
- data/lib/junklet.rb +0 -9
- data/lib/line.rb +0 -44
- data/spec/lib/line_spec.rb +0 -76
checksums.yaml
CHANGED
@@ -1,15 +1,15 @@
|
|
1
1
|
---
|
2
2
|
!binary "U0hBMQ==":
|
3
3
|
metadata.gz: !binary |-
|
4
|
-
|
4
|
+
N2Q5N2M1NjhmZDQyMzcyM2ExODk5MGI3N2RlMTkwZmE2OGI4Yjc3OQ==
|
5
5
|
data.tar.gz: !binary |-
|
6
|
-
|
6
|
+
NjA0NGZhNmIxMTRmMDE4MzA5Y2M2YTk2NDkyODQ0ZTE4YWE1ZTAyNA==
|
7
7
|
SHA512:
|
8
8
|
metadata.gz: !binary |-
|
9
|
-
|
10
|
-
|
11
|
-
|
9
|
+
YjU1MDhkMjdmNWQ4Njg5M2ZmNGU5ZGI0ZjYxYjA3MDk1NTYwMTllNDYxMzMz
|
10
|
+
OWY3YjUyM2FmODIyMDA0YTJmMmMwMGMwM2Q4YzAyNTFkMzI0ZWE4YTZkM2Zi
|
11
|
+
MzE3ODlkODMyNGUyYzUzZWNiZWUzNGQ1NThhOTE2MDFkOTM2ODA=
|
12
12
|
data.tar.gz: !binary |-
|
13
|
-
|
14
|
-
|
15
|
-
|
13
|
+
YmFlM2FhYTFhN2Y0ZGY3YTg2NjcyMTNlYmE1NGFlOGUzZWE5YjQ4NjUwNzJj
|
14
|
+
MmY5NTQ1MjZjNDNhMzY5ZGRjZDc3NTdlODY2M2JlYjM2ZjU1MDc4MTUxZDNm
|
15
|
+
ZDk5Y2FhZTA1YTg1NzNiYmIyNmNmYWU0NzNlNjc2NmRjZDNkZTA=
|
data/Gemfile.lock
CHANGED
@@ -0,0 +1,144 @@
|
|
1
|
+
require_relative 'formatter'
|
2
|
+
|
3
|
+
module RSpec
|
4
|
+
module Junklet
|
5
|
+
module Junk
|
6
|
+
def junk(*args)
|
7
|
+
# TODO: It's long past time to extract this....
|
8
|
+
|
9
|
+
# args.first can be
|
10
|
+
# - an integer indicating the size of the hex string to return
|
11
|
+
# - a symbol denoting the base type, e.g. :int
|
12
|
+
# - an array to sample from
|
13
|
+
# - a range or Enumerable to sample from. WARNING: will call
|
14
|
+
# .to_a on it first, which might be expensive
|
15
|
+
# - a generator Proc which, when called, will generate the
|
16
|
+
# value to use.
|
17
|
+
#
|
18
|
+
# args.rest is a hash of options:
|
19
|
+
# - sequence: Proc or Array of values to choose from.
|
20
|
+
# - exclude: value, array of values, or proc to exclude. If a
|
21
|
+
# Proc is given, it takes the value generated and returns
|
22
|
+
# true if the value should be excluded.
|
23
|
+
#
|
24
|
+
# - for int:
|
25
|
+
# - min: minimum number to return. Default: 0
|
26
|
+
# - max: upper limit of range
|
27
|
+
# - exclude: number, array of numbers, or proc to
|
28
|
+
# exclude. If Proc is provided, tests the number against
|
29
|
+
# the Proc an excludes it if the Proc returns true. This
|
30
|
+
# is implemented except for the proc.
|
31
|
+
|
32
|
+
# FIXME: Would be nice to be able to say, e.g. `junk exclude: bob` but
|
33
|
+
# currently this breaks because {exclude: bob} is a Hash which is
|
34
|
+
# an Enumerable which means it's a valid generator. I don't want to
|
35
|
+
# just disallow hashes as generators here. What's a good workaround
|
36
|
+
# for when I really do just want junk with either a format or an
|
37
|
+
# exclusion? `junk :junk, exclude: bob` looks bad. `junk _,
|
38
|
+
# exclude: bob` is also pretty bad.
|
39
|
+
#
|
40
|
+
# Hmm, I'm tempted to say "the one enumerable you CAN'T have is a
|
41
|
+
# Hash, so it can be the options hash; if you DO want to pass in a
|
42
|
+
# hash, you must cast it to an array or yield it from a Proc
|
43
|
+
# instead". Given that the hash case is weird and rare enough, I
|
44
|
+
# think this is acceptable. Oh, if only I didn't have to maintain
|
45
|
+
# backwards compatibility with older Rubies, I could just make
|
46
|
+
# these keyword args. Sigh.
|
47
|
+
|
48
|
+
# FIXME: This whole darn method is outta control, and for the record none
|
49
|
+
# of the cool excluders and formatters work with the
|
50
|
+
# SecureRandom.hex default. Barf.
|
51
|
+
|
52
|
+
# FIXME: Raise Argument error unless *args.size is 0-2
|
53
|
+
# FIXME: If arg 1 is a hash, it's the options hash, raise
|
54
|
+
# ArgumentError unless args.size == 1
|
55
|
+
# FIXME: If arg 2 present, Raise Argument error unless it's a
|
56
|
+
# hash.
|
57
|
+
# FIXME: Figure out what our valid options are and parse them;
|
58
|
+
# raise errors if present.
|
59
|
+
|
60
|
+
junk_types = [Symbol, Array, Enumerable, Proc]
|
61
|
+
if args.size > 0 && junk_types.any? {|klass| args.first.is_a?(klass) }
|
62
|
+
type = args.shift
|
63
|
+
opts = args.last || {}
|
64
|
+
|
65
|
+
excluder = if opts[:exclude]
|
66
|
+
if opts[:exclude].is_a?(Proc)
|
67
|
+
opts[:exclude]
|
68
|
+
else
|
69
|
+
->(x) { Array(opts[:exclude]).include?(x) }
|
70
|
+
end
|
71
|
+
else
|
72
|
+
->(x) { false }
|
73
|
+
end
|
74
|
+
|
75
|
+
formatter = case opts[:format]
|
76
|
+
when :string
|
77
|
+
->(x) { x.to_s }
|
78
|
+
when :int
|
79
|
+
->(x) { x.to_i }
|
80
|
+
when Class
|
81
|
+
raise "Formatter class must implement #format method" unless
|
82
|
+
opts[:format].new(0).respond_to? :format
|
83
|
+
->(x) { opts[:format].new(x).format }
|
84
|
+
when String
|
85
|
+
->(x) { sprintf(opts[:format], x) }
|
86
|
+
when Proc
|
87
|
+
opts[:format]
|
88
|
+
else
|
89
|
+
->(x) { x }
|
90
|
+
end
|
91
|
+
|
92
|
+
# TODO: Refactor me. Seriously, this is a functional
|
93
|
+
# programming version of the strategy pattern. Wouldn't it
|
94
|
+
# be neat if we had some kind of object-oriented language
|
95
|
+
# available here?
|
96
|
+
case type
|
97
|
+
when :int
|
98
|
+
# min,max cooperate with size to further constrain it. So
|
99
|
+
# size: 2, min: 30 would be min 30, max 99.
|
100
|
+
if opts[:size]
|
101
|
+
sized_min = 10**(opts[:size]-1)
|
102
|
+
sized_max = 10**opts[:size]-1
|
103
|
+
end
|
104
|
+
explicit_min = opts[:min] || 0
|
105
|
+
explicit_max = (opts[:max] || 2**62-2) + 1
|
106
|
+
|
107
|
+
if sized_min
|
108
|
+
min = [sized_min, explicit_min].max
|
109
|
+
max = [sized_max, explicit_max].min
|
110
|
+
else
|
111
|
+
min = sized_min || explicit_min
|
112
|
+
max = sized_max || explicit_max
|
113
|
+
end
|
114
|
+
|
115
|
+
min,max = max,min if min>max
|
116
|
+
|
117
|
+
generator = -> { rand(max-min) + min }
|
118
|
+
when :bool
|
119
|
+
generator = -> { [true, false].sample }
|
120
|
+
when Array, Enumerable
|
121
|
+
generator = -> { type.to_a.sample }
|
122
|
+
when Proc
|
123
|
+
generator = type
|
124
|
+
else
|
125
|
+
raise "Unrecognized junk type: '#{type}'"
|
126
|
+
end
|
127
|
+
|
128
|
+
begin
|
129
|
+
val = formatter.call(generator.call)
|
130
|
+
end while excluder.call(val)
|
131
|
+
val
|
132
|
+
else
|
133
|
+
size = args.first.is_a?(Numeric) ? args.first : 32
|
134
|
+
# hex returns size*2 digits, because it returns a 0..255 byte
|
135
|
+
# as a hex pair. But when we want junt, we want *bytes* of
|
136
|
+
# junk. Get (size+1)/2 chars, which will be correct for even
|
137
|
+
# sizes and 1 char too many for odds, so trim off with
|
138
|
+
# [0...size] (note three .'s to trim off final char)
|
139
|
+
SecureRandom.hex((size+1)/2)[0...size]
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
module RSpec
|
2
|
+
module Junklet
|
3
|
+
module Junklet
|
4
|
+
def junklet(*args)
|
5
|
+
# TODO: figure out how to use this to wrap junk in junklet,
|
6
|
+
# so that junklet can basically have all the same options as
|
7
|
+
# junk does. E.g. junklet :ddid, :pcn, :group, type: :int,
|
8
|
+
# min: 100000, max: 999999, etc, and you'd get back 3
|
9
|
+
# junklets of 6-digit numbers.
|
10
|
+
opts = args.size > 1 && !args.last.is_a?(Symbol) && args.pop || {}
|
11
|
+
|
12
|
+
names = args.map(&:to_s)
|
13
|
+
|
14
|
+
separator = opts[:separator] || '_'
|
15
|
+
names = names.map {|name| name.gsub(/_/, separator)}
|
16
|
+
|
17
|
+
args.zip(names).each do |arg, name|
|
18
|
+
make_junklet arg, name, separator, junk
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def make_junklet(let_name, name, separator, junk_data)
|
23
|
+
let(let_name) { "#{name}#{separator}#{junk_data}" }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -0,0 +1,9 @@
|
|
1
|
+
require_relative "./junklet/version"
|
2
|
+
require_relative "./junklet/junk"
|
3
|
+
require_relative "./junklet/junklet"
|
4
|
+
|
5
|
+
RSpec.configure do |config|
|
6
|
+
config.extend(RSpec::Junklet::Junklet)
|
7
|
+
config.extend(RSpec::Junklet::Junk) # when metaprogramming cases, you may need junk in ExampleGroups
|
8
|
+
config.include(RSpec::Junklet::Junk)
|
9
|
+
end
|
data/rspec-junklet.gemspec
CHANGED
@@ -1,16 +1,16 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
lib = File.expand_path('../lib', __FILE__)
|
3
3
|
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
-
require 'junklet/version'
|
4
|
+
require 'rspec/junklet/version'
|
5
5
|
|
6
6
|
Gem::Specification.new do |spec|
|
7
7
|
spec.name = "rspec-junklet"
|
8
|
-
spec.version = Junklet::VERSION
|
8
|
+
spec.version = RSpec::Junklet::VERSION
|
9
9
|
spec.authors = ["David Brady"]
|
10
10
|
spec.email = ["dbrady@shinybit.com"]
|
11
11
|
spec.summary = "Easily create junk data for specs"
|
12
12
|
spec.description = "Works like let for rspec, but creates unique random junk data"
|
13
|
-
spec.homepage = ""
|
13
|
+
spec.homepage = "https://github.com/dbrady/rspec-junklet"
|
14
14
|
spec.license = "MIT"
|
15
15
|
|
16
16
|
spec.files = `git ls-files -z`.split("\x0")
|
@@ -21,6 +21,5 @@ Gem::Specification.new do |spec|
|
|
21
21
|
spec.add_development_dependency "bundler", "~> 1.7"
|
22
22
|
spec.add_development_dependency "rake", "~> 10.0"
|
23
23
|
spec.add_development_dependency "rspec", "~> 2.0"
|
24
|
-
spec.add_development_dependency "
|
25
|
-
spec.add_development_dependency "pry"
|
24
|
+
spec.add_development_dependency "pry", "~> 0.10"
|
26
25
|
end
|
@@ -1,7 +1,12 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
|
-
|
4
|
-
|
3
|
+
# This spec file is a documentation/example spec showing how various ways to use
|
4
|
+
# Junklet. It was the original spec before I extracted out the classes of
|
5
|
+
# Junklet, but still serves as a functional, high-level spec plus it's a good
|
6
|
+
# collection of examples so here you go.
|
7
|
+
|
8
|
+
describe RSpec::Junklet do
|
9
|
+
specify { expect(subject).to be }
|
5
10
|
|
6
11
|
let(:hex_regex) { /[\da-f]{32}/ }
|
7
12
|
|
@@ -1,10 +1,10 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
|
2
|
+
require PROJECT_ROOT + 'lib/rspec/junklet/junk'
|
3
3
|
|
4
4
|
class JunkSpy
|
5
5
|
attr_reader :lets
|
6
6
|
|
7
|
-
include ::Junklet::Junk
|
7
|
+
include ::RSpec::Junklet::Junk
|
8
8
|
end
|
9
9
|
|
10
10
|
describe JunkSpy do
|
@@ -114,7 +114,7 @@ describe JunkSpy do
|
|
114
114
|
end
|
115
115
|
|
116
116
|
context "when format is a Junklet::Formatter" do
|
117
|
-
class HexTripler < Junklet::Formatter
|
117
|
+
class HexTripler < RSpec::Junklet::Formatter
|
118
118
|
def value
|
119
119
|
input * 3
|
120
120
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
# spec_helper.rb
|
2
2
|
|
3
|
-
|
3
|
+
PROJECT_ROOT=Pathname.new(File.expand_path(File.join(File.dirname(__FILE__), '..')))
|
4
4
|
|
5
|
-
|
5
|
+
require_relative PROJECT_ROOT + "lib" + "rspec" + "junklet"
|
6
|
+
|
7
|
+
|
8
|
+
require "pry"
|
6
9
|
|
7
10
|
# Since we've kept rigidly to 80-columns, we can easily
|
8
11
|
# Do a pretty side-by-side diff here. This won't handle
|
@@ -14,11 +17,11 @@ RED = "%c[%sm" % [ESC, 31]
|
|
14
17
|
RESET = "%c[0m" % ESC
|
15
18
|
|
16
19
|
def dump_hline
|
17
|
-
puts((
|
20
|
+
puts(("-" * 80) + "-+-" + ("-" * 80))
|
18
21
|
end
|
19
22
|
|
20
23
|
def dump_captions
|
21
|
-
puts
|
24
|
+
puts "%-80s | %s" % ["EXPECTED", "GOT"]
|
22
25
|
end
|
23
26
|
|
24
27
|
def dump_header
|
@@ -31,7 +34,7 @@ def dump_footer
|
|
31
34
|
end
|
32
35
|
|
33
36
|
def line_pairs(expected_lines, got_lines)
|
34
|
-
expected_lines.zip(got_lines).map { |words| words.map {|w| w ? w.rstrip :
|
37
|
+
expected_lines.zip(got_lines).map { |words| words.map {|w| w ? w.rstrip : "" } }
|
35
38
|
end
|
36
39
|
|
37
40
|
def dump_diff(expected_lines, got_lines)
|
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:
|
4
|
+
version: 2.0.0
|
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-
|
11
|
+
date: 2015-03-03 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -52,34 +52,20 @@ dependencies:
|
|
52
52
|
- - ~>
|
53
53
|
- !ruby/object:Gem::Version
|
54
54
|
version: '2.0'
|
55
|
-
- !ruby/object:Gem::Dependency
|
56
|
-
name: cucumber
|
57
|
-
requirement: !ruby/object:Gem::Requirement
|
58
|
-
requirements:
|
59
|
-
- - ! '>='
|
60
|
-
- !ruby/object:Gem::Version
|
61
|
-
version: '0'
|
62
|
-
type: :development
|
63
|
-
prerelease: false
|
64
|
-
version_requirements: !ruby/object:Gem::Requirement
|
65
|
-
requirements:
|
66
|
-
- - ! '>='
|
67
|
-
- !ruby/object:Gem::Version
|
68
|
-
version: '0'
|
69
55
|
- !ruby/object:Gem::Dependency
|
70
56
|
name: pry
|
71
57
|
requirement: !ruby/object:Gem::Requirement
|
72
58
|
requirements:
|
73
|
-
- -
|
59
|
+
- - ~>
|
74
60
|
- !ruby/object:Gem::Version
|
75
|
-
version: '0'
|
61
|
+
version: '0.10'
|
76
62
|
type: :development
|
77
63
|
prerelease: false
|
78
64
|
version_requirements: !ruby/object:Gem::Requirement
|
79
65
|
requirements:
|
80
|
-
- -
|
66
|
+
- - ~>
|
81
67
|
- !ruby/object:Gem::Version
|
82
|
-
version: '0'
|
68
|
+
version: '0.10'
|
83
69
|
description: Works like let for rspec, but creates unique random junk data
|
84
70
|
email:
|
85
71
|
- dbrady@shinybit.com
|
@@ -94,12 +80,11 @@ files:
|
|
94
80
|
- Gemfile.lock
|
95
81
|
- LICENSE
|
96
82
|
- README.md
|
97
|
-
- lib/junklet.rb
|
98
|
-
- lib/junklet/formatter.rb
|
99
|
-
- lib/junklet/junk.rb
|
100
|
-
- lib/junklet/junklet.rb
|
101
|
-
- lib/junklet/version.rb
|
102
|
-
- lib/line.rb
|
83
|
+
- lib/rspec/junklet.rb
|
84
|
+
- lib/rspec/junklet/formatter.rb
|
85
|
+
- lib/rspec/junklet/junk.rb
|
86
|
+
- lib/rspec/junklet/junklet.rb
|
87
|
+
- lib/rspec/junklet/version.rb
|
103
88
|
- rspec-junklet.gemspec
|
104
89
|
- spec/fixtures/block1_after.txt
|
105
90
|
- spec/fixtures/block1_before.txt
|
@@ -111,12 +96,11 @@ files:
|
|
111
96
|
- spec/fixtures/mixed_code_before.txt
|
112
97
|
- spec/fixtures/old_skool_after.txt
|
113
98
|
- spec/fixtures/old_skool_before.txt
|
114
|
-
- spec/lib/
|
115
|
-
- spec/lib/junklet/
|
116
|
-
- spec/lib/junklet_spec.rb
|
117
|
-
- spec/lib/line_spec.rb
|
99
|
+
- spec/lib/rspec/examples_spec.rb
|
100
|
+
- spec/lib/rspec/junklet/junk_spec.rb
|
101
|
+
- spec/lib/rspec/junklet/junklet_spec.rb
|
118
102
|
- spec/spec_helper.rb
|
119
|
-
homepage:
|
103
|
+
homepage: https://github.com/dbrady/rspec-junklet
|
120
104
|
licenses:
|
121
105
|
- MIT
|
122
106
|
metadata: {}
|
@@ -151,8 +135,7 @@ test_files:
|
|
151
135
|
- spec/fixtures/mixed_code_before.txt
|
152
136
|
- spec/fixtures/old_skool_after.txt
|
153
137
|
- spec/fixtures/old_skool_before.txt
|
154
|
-
- spec/lib/
|
155
|
-
- spec/lib/junklet/
|
156
|
-
- spec/lib/junklet_spec.rb
|
157
|
-
- spec/lib/line_spec.rb
|
138
|
+
- spec/lib/rspec/examples_spec.rb
|
139
|
+
- spec/lib/rspec/junklet/junk_spec.rb
|
140
|
+
- spec/lib/rspec/junklet/junklet_spec.rb
|
158
141
|
- spec/spec_helper.rb
|
data/lib/junklet/formatter.rb
DELETED
data/lib/junklet/junk.rb
DELETED
@@ -1,142 +0,0 @@
|
|
1
|
-
require_relative 'formatter'
|
2
|
-
|
3
|
-
module Junklet
|
4
|
-
module Junk
|
5
|
-
def junk(*args)
|
6
|
-
# TODO: It's long past time to extract this....
|
7
|
-
|
8
|
-
# args.first can be
|
9
|
-
# - an integer indicating the size of the hex string to return
|
10
|
-
# - a symbol denoting the base type, e.g. :int
|
11
|
-
# - an array to sample from
|
12
|
-
# - a range or Enumerable to sample from. WARNING: will call
|
13
|
-
# .to_a on it first, which might be expensive
|
14
|
-
# - a generator Proc which, when called, will generate the
|
15
|
-
# value to use.
|
16
|
-
#
|
17
|
-
# args.rest is a hash of options:
|
18
|
-
# - sequence: Proc or Array of values to choose from.
|
19
|
-
# - exclude: value, array of values, or proc to exclude. If a
|
20
|
-
# Proc is given, it takes the value generated and returns
|
21
|
-
# true if the value should be excluded.
|
22
|
-
#
|
23
|
-
# - for int:
|
24
|
-
# - min: minimum number to return. Default: 0
|
25
|
-
# - max: upper limit of range
|
26
|
-
# - exclude: number, array of numbers, or proc to
|
27
|
-
# exclude. If Proc is provided, tests the number against
|
28
|
-
# the Proc an excludes it if the Proc returns true. This
|
29
|
-
# is implemented except for the proc.
|
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
|
-
|
51
|
-
# FIXME: Raise Argument error unless *args.size is 0-2
|
52
|
-
# FIXME: If arg 1 is a hash, it's the options hash, raise
|
53
|
-
# ArgumentError unless args.size == 1
|
54
|
-
# FIXME: If arg 2 present, Raise Argument error unless it's a
|
55
|
-
# hash.
|
56
|
-
# FIXME: Figure out what our valid options are and parse them;
|
57
|
-
# raise errors if present.
|
58
|
-
|
59
|
-
junk_types = [Symbol, Array, Enumerable, Proc]
|
60
|
-
if args.size > 0 && junk_types.any? {|klass| args.first.is_a?(klass) }
|
61
|
-
type = args.shift
|
62
|
-
opts = args.last || {}
|
63
|
-
|
64
|
-
excluder = if opts[:exclude]
|
65
|
-
if opts[:exclude].is_a?(Proc)
|
66
|
-
opts[:exclude]
|
67
|
-
else
|
68
|
-
->(x) { Array(opts[:exclude]).include?(x) }
|
69
|
-
end
|
70
|
-
else
|
71
|
-
->(x) { false }
|
72
|
-
end
|
73
|
-
|
74
|
-
formatter = case opts[:format]
|
75
|
-
when :string
|
76
|
-
->(x) { x.to_s }
|
77
|
-
when :int
|
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 }
|
83
|
-
when String
|
84
|
-
->(x) { sprintf(opts[:format], x) }
|
85
|
-
when Proc
|
86
|
-
opts[:format]
|
87
|
-
else
|
88
|
-
->(x) { x }
|
89
|
-
end
|
90
|
-
|
91
|
-
# TODO: Refactor me. Seriously, this is a functional
|
92
|
-
# programming version of the strategy pattern. Wouldn't it
|
93
|
-
# be neat if we had some kind of object-oriented language
|
94
|
-
# available here?
|
95
|
-
case type
|
96
|
-
when :int
|
97
|
-
# min,max cooperate with size to further constrain it. So
|
98
|
-
# size: 2, min: 30 would be min 30, max 99.
|
99
|
-
if opts[:size]
|
100
|
-
sized_min = 10**(opts[:size]-1)
|
101
|
-
sized_max = 10**opts[:size]-1
|
102
|
-
end
|
103
|
-
explicit_min = opts[:min] || 0
|
104
|
-
explicit_max = (opts[:max] || 2**62-2) + 1
|
105
|
-
|
106
|
-
if sized_min
|
107
|
-
min = [sized_min, explicit_min].max
|
108
|
-
max = [sized_max, explicit_max].min
|
109
|
-
else
|
110
|
-
min = sized_min || explicit_min
|
111
|
-
max = sized_max || explicit_max
|
112
|
-
end
|
113
|
-
|
114
|
-
min,max = max,min if min>max
|
115
|
-
|
116
|
-
generator = -> { rand(max-min) + min }
|
117
|
-
when :bool
|
118
|
-
generator = -> { [true, false].sample }
|
119
|
-
when Array, Enumerable
|
120
|
-
generator = -> { type.to_a.sample }
|
121
|
-
when Proc
|
122
|
-
generator = type
|
123
|
-
else
|
124
|
-
raise "Unrecognized junk type: '#{type}'"
|
125
|
-
end
|
126
|
-
|
127
|
-
begin
|
128
|
-
val = formatter.call(generator.call)
|
129
|
-
end while excluder.call(val)
|
130
|
-
val
|
131
|
-
else
|
132
|
-
size = args.first.is_a?(Numeric) ? args.first : 32
|
133
|
-
# hex returns size*2 digits, because it returns a 0..255 byte
|
134
|
-
# as a hex pair. But when we want junt, we want *bytes* of
|
135
|
-
# junk. Get (size+1)/2 chars, which will be correct for even
|
136
|
-
# sizes and 1 char too many for odds, so trim off with
|
137
|
-
# [0...size] (note three .'s to trim off final char)
|
138
|
-
SecureRandom.hex((size+1)/2)[0...size]
|
139
|
-
end
|
140
|
-
end
|
141
|
-
end
|
142
|
-
end
|
data/lib/junklet/junklet.rb
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
module Junklet
|
2
|
-
module Junklet
|
3
|
-
def junklet(*args)
|
4
|
-
# TODO: figure out how to use this to wrap junk in junklet,
|
5
|
-
# so that junklet can basically have all the same options as
|
6
|
-
# junk does. E.g. junklet :ddid, :pcn, :group, type: :int,
|
7
|
-
# min: 100000, max: 999999, etc, and you'd get back 3
|
8
|
-
# junklets of 6-digit numbers.
|
9
|
-
opts = args.size > 1 && !args.last.is_a?(Symbol) && args.pop || {}
|
10
|
-
|
11
|
-
names = args.map(&:to_s)
|
12
|
-
|
13
|
-
separator = opts[:separator] || '_'
|
14
|
-
names = names.map {|name| name.gsub(/_/, separator)}
|
15
|
-
|
16
|
-
args.zip(names).each do |arg, name|
|
17
|
-
make_junklet arg, name, separator, junk
|
18
|
-
end
|
19
|
-
end
|
20
|
-
|
21
|
-
def make_junklet(let_name, name, separator, junk_data)
|
22
|
-
let(let_name) { "#{name}#{separator}#{junk_data}" }
|
23
|
-
end
|
24
|
-
end
|
25
|
-
end
|
data/lib/junklet/version.rb
DELETED
data/lib/junklet.rb
DELETED
@@ -1,9 +0,0 @@
|
|
1
|
-
require "junklet/version"
|
2
|
-
require "junklet/junk"
|
3
|
-
require "junklet/junklet"
|
4
|
-
|
5
|
-
RSpec.configure do |config|
|
6
|
-
config.extend(Junklet::Junklet)
|
7
|
-
config.extend(Junklet::Junk) # when metaprogramming cases, you may need junk in ExampleGroups
|
8
|
-
config.include(Junklet::Junk)
|
9
|
-
end
|
data/lib/line.rb
DELETED
@@ -1,44 +0,0 @@
|
|
1
|
-
class Line < String
|
2
|
-
def initialize(line="")
|
3
|
-
super
|
4
|
-
end
|
5
|
-
|
6
|
-
def indent
|
7
|
-
' ' * (size - lstrip.size)
|
8
|
-
end
|
9
|
-
|
10
|
-
def let?
|
11
|
-
match(/^\s*let\s*\(/) && !junklet?
|
12
|
-
end
|
13
|
-
|
14
|
-
def junklet?
|
15
|
-
already_junklet? || secure_random?
|
16
|
-
end
|
17
|
-
|
18
|
-
def already_junklet?
|
19
|
-
match(/^\s*junklet\b/)
|
20
|
-
end
|
21
|
-
|
22
|
-
def secure_random?
|
23
|
-
match(/^\s*(let)\s*\(?([^)]*)\)\s*{\s*SecureRandom.(uuid|hex)\s*}/)
|
24
|
-
end
|
25
|
-
|
26
|
-
def code?
|
27
|
-
empty? || (!let? && !junklet?)
|
28
|
-
end
|
29
|
-
|
30
|
-
def names
|
31
|
-
return nil unless let? || junklet?
|
32
|
-
match(/^\s*(let|junklet)\s*\(?([^)]*)\)?/) \
|
33
|
-
.captures[1..-1] \
|
34
|
-
.join('') \
|
35
|
-
.split(/,/) \
|
36
|
-
.map(&:strip)
|
37
|
-
end
|
38
|
-
|
39
|
-
def convert
|
40
|
-
return nil unless junklet?
|
41
|
-
return self if already_junklet?
|
42
|
-
Line.new("#{indent}junklet #{names.first}")
|
43
|
-
end
|
44
|
-
end
|
data/spec/lib/line_spec.rb
DELETED
@@ -1,76 +0,0 @@
|
|
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
|