pseudo_entity 0.0.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.
- data/.gitignore +20 -0
- data/Gemfile +3 -0
- data/LICENSE.txt +22 -0
- data/README.md +30 -0
- data/Rakefile +7 -0
- data/lib/pseudo_entity/randoms/constants.rb +603 -0
- data/lib/pseudo_entity/randoms/location.rb +112 -0
- data/lib/pseudo_entity/randoms/locations_hash.rb +38010 -0
- data/lib/pseudo_entity/randoms/zip_code_database.csv +42523 -0
- data/lib/pseudo_entity/randoms.rb +890 -0
- data/lib/pseudo_entity/version.rb +3 -0
- data/lib/pseudo_entity.rb +138 -0
- data/psuedo_entity.gemspec +30 -0
- data/spec/lib/pseudo_entity/randoms_spec.rb +276 -0
- data/spec/lib/pseudo_entity_spec.rb +157 -0
- data/spec/spec_helper.rb +1 -0
- metadata +184 -0
@@ -0,0 +1,890 @@
|
|
1
|
+
begin
|
2
|
+
require 'active_support/all'
|
3
|
+
rescue LoadError
|
4
|
+
require 'active_support'
|
5
|
+
end
|
6
|
+
|
7
|
+
require 'uuidtools'
|
8
|
+
require 'huge_enumerable'
|
9
|
+
|
10
|
+
module PseudoEntity::Randoms
|
11
|
+
|
12
|
+
require 'pseudo_entity/randoms/constants'
|
13
|
+
require 'pseudo_entity/randoms/location'
|
14
|
+
|
15
|
+
# These are the randoms values available and are neither composites nor subsets of anything else in this list.
|
16
|
+
RandomValues = [:apartment_number, :bank_routing_number, :bank_account_number, :bank_name, :birth_day,
|
17
|
+
:city, :company_name, :country_code, :credit_card_issuer, :credit_card_number,
|
18
|
+
:credit_union_name, :domain, :email_address, :federal_tax_id, :first_name,
|
19
|
+
:ip_address, :last_name, :latitude, :login, :longitude,
|
20
|
+
:password, :phone_number, :property_number, :sex, :time_shift,
|
21
|
+
:short_url, :slogan, :state, :street_name, :suite_number,
|
22
|
+
:website, :uuid, :time_zone,
|
23
|
+
:zip_code, :facebook_id, :review, :salt,
|
24
|
+
:iv, :google_analytics_account_id, :region, :subject,
|
25
|
+
:noun, :adjective
|
26
|
+
]
|
27
|
+
|
28
|
+
ArityValues = [/^numeric_\d+$/, /^alpha_\d+$/, /^alpha_numeric_\d+$/, /^token_\d+$/, /^rand_\d+$/]
|
29
|
+
ArityRandoms = [/^random_numeric_\d+$/, /^random_alpha_\d+$/, /^random_alpha_numeric_\d+$/, /^random_token_\d+$/]
|
30
|
+
|
31
|
+
|
32
|
+
include Constants
|
33
|
+
|
34
|
+
# Create the lazy loading accessors
|
35
|
+
RandomValues.each do |value_name|
|
36
|
+
class_eval %{
|
37
|
+
def #{value_name}
|
38
|
+
@#{value_name} ||= random_#{value_name}
|
39
|
+
end
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
# Im still not happy about this but at least it is out of PseudoEntity.
|
44
|
+
def shift_time(options={:distance => :days, :direction => :either, :base => nil, :min => nil, :max => nil})
|
45
|
+
random_time_shift options
|
46
|
+
end
|
47
|
+
|
48
|
+
def method_missing(name, *args, &block)
|
49
|
+
|
50
|
+
if arity_random?(name)
|
51
|
+
# Define random_X helpers on the fly
|
52
|
+
size = /.*_(\d+)$/.match(name)[1].to_i
|
53
|
+
base_name = (/(.*)_\d+$/.match(name.to_s)[1]).to_sym
|
54
|
+
self.class.send(:define_method, name) do
|
55
|
+
self.send(base_name, size)
|
56
|
+
end
|
57
|
+
self.class.send(:private, name)
|
58
|
+
send(name)
|
59
|
+
elsif arity_value?(name)
|
60
|
+
iv_name = "@#{name}".to_sym
|
61
|
+
command = "random_#{name}".to_sym
|
62
|
+
relay = arity_random?(command)
|
63
|
+
if !relay
|
64
|
+
size = /.*_(\d+)$/.match(name)[1].to_i
|
65
|
+
command = (/(.*)_\d+$/.match(name.to_s)[1]).to_sym
|
66
|
+
object = Kernel
|
67
|
+
end
|
68
|
+
self.class.send(:define_method, name) do
|
69
|
+
iv = instance_variable_get(iv_name)
|
70
|
+
if iv.nil?
|
71
|
+
iv = relay ? send(command) : object.send(command, size)
|
72
|
+
instance_variable_set(iv_name, iv)
|
73
|
+
end
|
74
|
+
iv
|
75
|
+
end
|
76
|
+
send(name)
|
77
|
+
else
|
78
|
+
super
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def respond_to?(method, include_all=false)
|
83
|
+
include_all && arity_random?(method) || arity_value?(method) || super
|
84
|
+
end if RUBY_VERSION < "1.9"
|
85
|
+
|
86
|
+
def respond_to_missing?(method, include_all=false)
|
87
|
+
include_all && arity_random?(method) || arity_value?(method) || super
|
88
|
+
end if RUBY_VERSION >= "1.9"
|
89
|
+
|
90
|
+
private
|
91
|
+
|
92
|
+
def parse_options(options={})
|
93
|
+
# Make an instance variable for each randoms value and set it to anything sent in for it via the options.
|
94
|
+
RandomValues.each { |value_name| instance_variable_set("@#{value_name}".to_sym,options[value_name]) }
|
95
|
+
end
|
96
|
+
|
97
|
+
def arity_random?(name)
|
98
|
+
name = name.to_s
|
99
|
+
ArityRandoms.any? { |x| x =~ name }
|
100
|
+
end
|
101
|
+
|
102
|
+
def arity_value?(name)
|
103
|
+
name = name.to_s
|
104
|
+
ArityValues.any? { |x| x =~ name }
|
105
|
+
end
|
106
|
+
|
107
|
+
def random_adjective
|
108
|
+
PseudoEntity::Randoms.adjectives.pop
|
109
|
+
end
|
110
|
+
|
111
|
+
def random_alpha(size)
|
112
|
+
chars = ('a'..'z').to_a + ('A'..'Z').to_a
|
113
|
+
(1..size).map { chars[rand(chars.size)] }.join
|
114
|
+
end
|
115
|
+
|
116
|
+
def random_alpha_numeric(size)
|
117
|
+
chars = ('a'..'z').to_a + ('A'..'Z').to_a + (0..9).to_a
|
118
|
+
(1..size).map { chars[rand(chars.size)] }.join
|
119
|
+
end
|
120
|
+
|
121
|
+
def random_apartment_number
|
122
|
+
rand(998) + 1
|
123
|
+
end
|
124
|
+
|
125
|
+
def random_bank_account_number
|
126
|
+
random_numeric(13)
|
127
|
+
end
|
128
|
+
|
129
|
+
def random_bank_name
|
130
|
+
PseudoEntity::Randoms.bank_names.pop
|
131
|
+
end
|
132
|
+
|
133
|
+
def random_bank_routing_number
|
134
|
+
random_numeric(9)
|
135
|
+
end
|
136
|
+
|
137
|
+
def random_birth_day
|
138
|
+
# Everyone will be between 21 and 101 years old.
|
139
|
+
Date.today - 21.years - rand(80 * 365).days
|
140
|
+
end
|
141
|
+
|
142
|
+
def random_city
|
143
|
+
PseudoEntity::Randoms.cities.pop
|
144
|
+
end
|
145
|
+
|
146
|
+
def random_class_a_ip_address
|
147
|
+
#10.0.0.0 - 10.255.255.255 16777216
|
148
|
+
"10.#{rand(255)}.#{rand(255)}.#{rand(255)}"
|
149
|
+
end
|
150
|
+
|
151
|
+
def random_class_b_ip_address
|
152
|
+
#172.16.0.0 - 172.31.255.255 1048576
|
153
|
+
"172.#{rand(15) + 16}.#{rand(255)}.#{rand(255)}"
|
154
|
+
end
|
155
|
+
|
156
|
+
def random_class_c_ip_address
|
157
|
+
#192.168.0.0 - 192.168.255.255 65536
|
158
|
+
"192.168.#{rand(255)}.#{rand(255)}"
|
159
|
+
end
|
160
|
+
|
161
|
+
def random_company_name
|
162
|
+
PseudoEntity::Randoms.company_names.pop
|
163
|
+
end
|
164
|
+
|
165
|
+
def random_country_code
|
166
|
+
location.country_code
|
167
|
+
end
|
168
|
+
|
169
|
+
def random_credit_card
|
170
|
+
PseudoEntity::Randoms.credit_cards.pop
|
171
|
+
end
|
172
|
+
|
173
|
+
def random_credit_card_issuer
|
174
|
+
credit_card.first
|
175
|
+
end
|
176
|
+
|
177
|
+
def random_credit_card_number
|
178
|
+
credit_card.last
|
179
|
+
end
|
180
|
+
|
181
|
+
def random_credit_union_name
|
182
|
+
PseudoEntity::Randoms.credit_union_names.pop
|
183
|
+
end
|
184
|
+
|
185
|
+
def random_domain
|
186
|
+
PseudoEntity::Randoms.domains.pop
|
187
|
+
end
|
188
|
+
|
189
|
+
def random_email_address
|
190
|
+
"#{first_name}.#{last_name}@#{domain}"
|
191
|
+
end
|
192
|
+
|
193
|
+
def random_facebook_id
|
194
|
+
"%.20i" % rand(2**64)
|
195
|
+
end
|
196
|
+
|
197
|
+
def random_federal_tax_id
|
198
|
+
random_numeric(9)
|
199
|
+
end
|
200
|
+
|
201
|
+
def random_first_name
|
202
|
+
PseudoEntity::Randoms.first_names.pop
|
203
|
+
end
|
204
|
+
|
205
|
+
def random_google_analytics_account_id
|
206
|
+
"UA-#{random_numeric(7)}-#{random_numeric(2)}"
|
207
|
+
end
|
208
|
+
|
209
|
+
def random_ip_address
|
210
|
+
class_a_size = 16777216
|
211
|
+
class_b_size = 1048576
|
212
|
+
class_c_size = 65536
|
213
|
+
|
214
|
+
subnet = rand(class_a_size + class_b_size + class_c_size)
|
215
|
+
if subnet < class_a_size
|
216
|
+
random_class_a_ip_address
|
217
|
+
elsif subnet < class_a_size + class_b_size
|
218
|
+
random_class_b_ip_address
|
219
|
+
else
|
220
|
+
random_class_c_ip_address
|
221
|
+
end
|
222
|
+
|
223
|
+
end
|
224
|
+
|
225
|
+
def random_iv
|
226
|
+
OpenSSL::Cipher::Cipher.new('aes-256-cbc').random_iv
|
227
|
+
end
|
228
|
+
|
229
|
+
def random_last_name
|
230
|
+
PseudoEntity::Randoms.last_names.pop
|
231
|
+
end
|
232
|
+
|
233
|
+
def random_latitude
|
234
|
+
location.latitude
|
235
|
+
end
|
236
|
+
|
237
|
+
def random_login
|
238
|
+
"#{last_name.downcase}_#{first_name.downcase}"
|
239
|
+
end
|
240
|
+
|
241
|
+
def random_longitude
|
242
|
+
location.longitude
|
243
|
+
end
|
244
|
+
|
245
|
+
def random_noun
|
246
|
+
PseudoEntity::Randoms.nouns.pop
|
247
|
+
end
|
248
|
+
|
249
|
+
def random_password
|
250
|
+
# Bet they will never guess this one! :P
|
251
|
+
"#{first_name.downcase}_#{last_name.downcase}"
|
252
|
+
end
|
253
|
+
|
254
|
+
def random_phone_number
|
255
|
+
"#{location.area_code}-#{random_numeric(3)}-#{random_numeric(4)}"
|
256
|
+
end
|
257
|
+
|
258
|
+
def random_property_number
|
259
|
+
rand(9989) + 10
|
260
|
+
end
|
261
|
+
|
262
|
+
def random_region
|
263
|
+
PseudoEntity::Randoms.regions.pop
|
264
|
+
end
|
265
|
+
|
266
|
+
def random_review
|
267
|
+
PseudoEntity::Randoms.reviews.pop
|
268
|
+
end
|
269
|
+
|
270
|
+
def random_salt
|
271
|
+
Time.now.to_i.to_s
|
272
|
+
end
|
273
|
+
|
274
|
+
def random_sex
|
275
|
+
PseudoEntity::Randoms.sex_of(first_name) || ['Female', 'Male'].sample
|
276
|
+
end
|
277
|
+
|
278
|
+
def random_short_url
|
279
|
+
"http://ti.ny/#{domain.hash}"
|
280
|
+
end
|
281
|
+
|
282
|
+
def random_slogan
|
283
|
+
PseudoEntity::Randoms.slogans.pop
|
284
|
+
end
|
285
|
+
|
286
|
+
def random_state
|
287
|
+
location.state
|
288
|
+
end
|
289
|
+
|
290
|
+
def random_street_modifier_needed
|
291
|
+
# One out of ten addresses gets something.
|
292
|
+
if rand(10) == 0
|
293
|
+
# 70% of the time it is a suite.
|
294
|
+
if rand(10) < 7
|
295
|
+
:suite
|
296
|
+
else
|
297
|
+
:apartment
|
298
|
+
end
|
299
|
+
else
|
300
|
+
# The rest of the time we do not need to generate one.
|
301
|
+
false
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
def random_street_name
|
306
|
+
PseudoEntity::Randoms.street_names.pop
|
307
|
+
end
|
308
|
+
|
309
|
+
def random_numeric(size)
|
310
|
+
"%.#{size}i" % rand(10**size)
|
311
|
+
end
|
312
|
+
|
313
|
+
def random_subject
|
314
|
+
PseudoEntity::Randoms.subjects.pop
|
315
|
+
end
|
316
|
+
|
317
|
+
def random_suite_number
|
318
|
+
rand(498) + 1
|
319
|
+
end
|
320
|
+
|
321
|
+
def random_time_between(min, max)
|
322
|
+
PseudoEntity::Randoms.time_between min, max
|
323
|
+
end
|
324
|
+
|
325
|
+
def random_time_shift(options={:distance => :days, :direction => :either, :base => nil, :min => nil, :max => nil})
|
326
|
+
distance = options[:distance] || :days
|
327
|
+
direction = options[:direction] || :either
|
328
|
+
base = options[:base]
|
329
|
+
min = options[:min]
|
330
|
+
max = options[:max]
|
331
|
+
|
332
|
+
shift = PseudoEntity::Randoms.time_shift distance, direction
|
333
|
+
|
334
|
+
if base
|
335
|
+
conversion = case base
|
336
|
+
when DateTime
|
337
|
+
:to_datetime
|
338
|
+
when Date
|
339
|
+
:to_date
|
340
|
+
when Time
|
341
|
+
:to_time
|
342
|
+
else
|
343
|
+
nil
|
344
|
+
end
|
345
|
+
|
346
|
+
new_time = base.to_datetime + shift
|
347
|
+
if max && new_time > max.to_datetime
|
348
|
+
new_time = max
|
349
|
+
elsif min && new_time < min.to_datetime
|
350
|
+
new_time = min
|
351
|
+
end
|
352
|
+
conversion ? new_time.send(conversion) : new_time
|
353
|
+
else
|
354
|
+
shift
|
355
|
+
end
|
356
|
+
|
357
|
+
end
|
358
|
+
|
359
|
+
def random_time_zone
|
360
|
+
location.time_zone
|
361
|
+
end
|
362
|
+
|
363
|
+
def random_token(size)
|
364
|
+
PseudoEntity::Randoms.token(size)
|
365
|
+
end
|
366
|
+
|
367
|
+
def random_token_8
|
368
|
+
PseudoEntity::Randoms.token_8
|
369
|
+
end
|
370
|
+
|
371
|
+
def random_token_16
|
372
|
+
PseudoEntity::Randoms.token_16
|
373
|
+
end
|
374
|
+
|
375
|
+
def random_token_32
|
376
|
+
PseudoEntity::Randoms.token_32
|
377
|
+
end
|
378
|
+
|
379
|
+
def random_token_64
|
380
|
+
PseudoEntity::Randoms.token_64
|
381
|
+
end
|
382
|
+
|
383
|
+
def random_uuid
|
384
|
+
PseudoEntity::Randoms.uuid
|
385
|
+
end
|
386
|
+
|
387
|
+
def random_website
|
388
|
+
"http://#{domain}"
|
389
|
+
end
|
390
|
+
|
391
|
+
def random_zip_code
|
392
|
+
location.zip_code
|
393
|
+
end
|
394
|
+
|
395
|
+
|
396
|
+
##### Helpers for above #####
|
397
|
+
|
398
|
+
def credit_card
|
399
|
+
@credit_card ||= random_credit_card
|
400
|
+
end
|
401
|
+
|
402
|
+
def determine_street_modifier_needed
|
403
|
+
# If a property number has already been set then we assume that any required apartment or suite number has also been set.
|
404
|
+
if @property_number
|
405
|
+
if @apartment_number
|
406
|
+
:apartment
|
407
|
+
elsif @suite_number
|
408
|
+
:suite
|
409
|
+
else
|
410
|
+
false
|
411
|
+
end
|
412
|
+
else
|
413
|
+
random_street_modifier_needed
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
def location
|
418
|
+
@location ||= PseudoEntity::Randoms.locations.pop
|
419
|
+
end
|
420
|
+
|
421
|
+
def street_modifier_needed
|
422
|
+
@street_modifier_needed ||= determine_street_modifier_needed
|
423
|
+
end
|
424
|
+
alias street_modifier_needed? street_modifier_needed
|
425
|
+
|
426
|
+
def street_position
|
427
|
+
"#{property_number} #{street_name}"
|
428
|
+
end
|
429
|
+
|
430
|
+
|
431
|
+
|
432
|
+
# This method allows us to build data sets that will refresh automatically when they are blanked.
|
433
|
+
# The initial set of data comes from the supplied block. That block will only be run once and the results will be cached.
|
434
|
+
# Each time the data set is blanked, it will be reloaded from cache and shuffled (if the data set supports the operation).
|
435
|
+
# By removing the values out of the data set, instead of using sample, you are guaranteed to not have repeats until the data set is refreshed and shuffled again.
|
436
|
+
def self.data_for(name, &block)
|
437
|
+
# Grab the data set
|
438
|
+
data = data_get(name)
|
439
|
+
# If it is out of data or has never been initialized in the first place
|
440
|
+
if data.blank?
|
441
|
+
# Grab the internal cache of all the generated data
|
442
|
+
original_data = original_data_get(name)
|
443
|
+
# If it also has never been initialized
|
444
|
+
if original_data.nil?
|
445
|
+
# Call the block and get the full set of data
|
446
|
+
original_data = yield
|
447
|
+
# Store the data so we never have to call that block again
|
448
|
+
original_data_set(name, original_data)
|
449
|
+
end
|
450
|
+
# Reset the data set that will be given to callers. They can do whatever with it. If the data set is cleared it will just be refreshed from cache.
|
451
|
+
data = data_set(name, original_data.respond_to?(:shuffle) ? original_data.shuffle : original_data.dup)
|
452
|
+
end
|
453
|
+
# Give them what they asked for
|
454
|
+
data
|
455
|
+
end
|
456
|
+
|
457
|
+
# Now generate the infinite arrays/enumerables.
|
458
|
+
def self.adjectives
|
459
|
+
data_for_adjectives_is { HugeCollection.new(ADJECTIVES) }
|
460
|
+
end
|
461
|
+
|
462
|
+
def self.subjects
|
463
|
+
data_for_subjects_is { RandomSubjects.new(ADJECTIVES, NOUNS) }
|
464
|
+
end
|
465
|
+
|
466
|
+
def self.bank_names
|
467
|
+
data_for_bank_names_is { RandomBankNames.new(BANK_PREFIXES) }
|
468
|
+
end
|
469
|
+
|
470
|
+
def self.cities
|
471
|
+
data_for_cities_is { HugeCollection.new(CITIES) }
|
472
|
+
end
|
473
|
+
|
474
|
+
def self.company_names
|
475
|
+
data_for_company_names_is { RandomCompanyNames.new(ADJECTIVES, NOUNS, COMPANY_TYPES) }
|
476
|
+
end
|
477
|
+
|
478
|
+
def self.company_types
|
479
|
+
data_for_company_types_is { HugeCollection.new(COMPANY_TYPES) }
|
480
|
+
end
|
481
|
+
|
482
|
+
def self.credit_cards
|
483
|
+
data_for_credit_cards_is { HugeCollection.new(CREDIT_CARDS) }
|
484
|
+
end
|
485
|
+
|
486
|
+
def self.credit_union_names
|
487
|
+
data_for_bank_names_is { RandomCreditUnionNames.new(CREDIT_UNION_PREFIXES) }
|
488
|
+
end
|
489
|
+
|
490
|
+
def self.domains
|
491
|
+
data_for_domains_is { RandomDomains.new(NOUNS, DOMAINS) }
|
492
|
+
end
|
493
|
+
|
494
|
+
def self.female_first_names
|
495
|
+
data_for_female_first_names_is { HugeCollection.new(FEMALE_FIRST_NAMES) }
|
496
|
+
end
|
497
|
+
|
498
|
+
def self.first_names
|
499
|
+
data_for_first_names_is { HugeCollection.new(FEMALE_FIRST_NAMES + MALE_FIRST_NAMES) }
|
500
|
+
end
|
501
|
+
|
502
|
+
def self.last_names
|
503
|
+
data_for_last_names_is { HugeCollection.new(SURNAMES) }
|
504
|
+
end
|
505
|
+
|
506
|
+
def self.locations
|
507
|
+
data_for_locations_is { RandomLocations.new(LOCATIONS_HASH) }
|
508
|
+
end
|
509
|
+
|
510
|
+
def self.female_names
|
511
|
+
data_for_female_names_is { HugeProduct.new(FEMALE_FIRST_NAMES, SURNAMES) }
|
512
|
+
end
|
513
|
+
|
514
|
+
def self.female_full_names
|
515
|
+
data_for_female_full_names_is { RandomNames.new(FEMALE_FIRST_NAMES, SURNAMES) }
|
516
|
+
end
|
517
|
+
|
518
|
+
def self.full_names
|
519
|
+
data_for_full_names_is { RandomNames.new(FEMALE_FIRST_NAMES + MALE_FIRST_NAMES, SURNAMES) }
|
520
|
+
end
|
521
|
+
|
522
|
+
def self.male_names
|
523
|
+
data_for_male_names_is { HugeProduct.new(MALE_FIRST_NAMES, SURNAMES) }
|
524
|
+
end
|
525
|
+
|
526
|
+
def self.male_first_names
|
527
|
+
data_for_male_first_names_is { HugeCollection.new(MALE_FIRST_NAMES) }
|
528
|
+
end
|
529
|
+
|
530
|
+
def self.male_full_names
|
531
|
+
data_for_male_full_names_is { RandomNames.new(MALE_FIRST_NAMES, SURNAMES) }
|
532
|
+
end
|
533
|
+
|
534
|
+
def self.names
|
535
|
+
data_for_names_is { HugeProduct.new(FEMALE_FIRST_NAMES + MALE_FIRST_NAMES, SURNAMES) }
|
536
|
+
end
|
537
|
+
|
538
|
+
def self.nouns
|
539
|
+
data_for_nouns_is { HugeCollection.new(NOUNS) }
|
540
|
+
end
|
541
|
+
|
542
|
+
def self.time_between(min, max)
|
543
|
+
conversion = case min
|
544
|
+
when DateTime
|
545
|
+
:to_datetime
|
546
|
+
when Date
|
547
|
+
:to_date
|
548
|
+
when Time
|
549
|
+
:to_time
|
550
|
+
else
|
551
|
+
nil
|
552
|
+
end
|
553
|
+
min = min.to_datetime
|
554
|
+
max = max.to_datetime
|
555
|
+
new_time = min + (max - min) * rand
|
556
|
+
new_time = new_time.send(conversion) if conversion
|
557
|
+
new_time
|
558
|
+
end
|
559
|
+
|
560
|
+
|
561
|
+
def self.regions
|
562
|
+
data_for_regions_is { HugeCollection.new(REGIONS) }
|
563
|
+
end
|
564
|
+
|
565
|
+
|
566
|
+
def self.reviews
|
567
|
+
data_for_reviews_is { RandomReviews.new(review_patterns, ADJECTIVES, NOUNS) }
|
568
|
+
end
|
569
|
+
|
570
|
+
def self.review_patterns
|
571
|
+
data_for_review_patterns_is { HugeCollection.new(REVIEW_PATTERNS) }
|
572
|
+
end
|
573
|
+
|
574
|
+
|
575
|
+
def self.sex_of(first_name)
|
576
|
+
if FEMALE_FIRST_NAMES.include?(first_name)
|
577
|
+
'Female'
|
578
|
+
elsif MALE_FIRST_NAMES.include?(first_name)
|
579
|
+
'Male'
|
580
|
+
else
|
581
|
+
nil
|
582
|
+
end
|
583
|
+
end
|
584
|
+
|
585
|
+
def self.slogans
|
586
|
+
data_for_slogans_is { RandomSlogans.new(SLOGAN_PATTERNS, ADJECTIVES, NOUNS) }
|
587
|
+
end
|
588
|
+
|
589
|
+
def self.slogan_patterns
|
590
|
+
data_for_slogan_patterns_is { HugeCollection.new(SLOGAN_PATTERNS) }
|
591
|
+
end
|
592
|
+
|
593
|
+
def self.street_names
|
594
|
+
data_for_street_names_is { RandomStreetNames.new(STREET_POSITIONS, STREET_NAMES) }
|
595
|
+
end
|
596
|
+
|
597
|
+
def self.time_shift(distance = :days, direction = nil)
|
598
|
+
shift =
|
599
|
+
case distance
|
600
|
+
when :centuries
|
601
|
+
1000.years
|
602
|
+
when :decades
|
603
|
+
100.years
|
604
|
+
when :years
|
605
|
+
10.years
|
606
|
+
when :months
|
607
|
+
12.months
|
608
|
+
when :days
|
609
|
+
30.days
|
610
|
+
when :hours
|
611
|
+
24.hours
|
612
|
+
when :minutes
|
613
|
+
60.minutes
|
614
|
+
when :seconds
|
615
|
+
60.seconds
|
616
|
+
else
|
617
|
+
distance
|
618
|
+
end.to_f * rand
|
619
|
+
|
620
|
+
direction = direction.to_s if direction
|
621
|
+
shift *= -1 if direction.starts_with?('backward') || (!direction || direction == 'either') && rand(2) == 1
|
622
|
+
shift
|
623
|
+
end
|
624
|
+
|
625
|
+
def self.token(size)
|
626
|
+
(1..(size + 31) / 32).map { UUIDTools::UUID.random_create.hexdigest }.join('')[0..size-1]
|
627
|
+
end
|
628
|
+
|
629
|
+
def self.uuid
|
630
|
+
UUIDTools::UUID.random_create.to_s
|
631
|
+
end
|
632
|
+
|
633
|
+
def self.zip_code_state_hash
|
634
|
+
data_for_zip_code_state_hash_is do
|
635
|
+
with_fresh_locations do
|
636
|
+
locations.inject({}) do |hsh, location|
|
637
|
+
hsh[location.zip_code] = location.state
|
638
|
+
hsh
|
639
|
+
end
|
640
|
+
end
|
641
|
+
end
|
642
|
+
end
|
643
|
+
|
644
|
+
def self.zip_code_states
|
645
|
+
data_for_zip_code_states_is { zip_code_state_hash.to_a }
|
646
|
+
end
|
647
|
+
|
648
|
+
# Convert the string, name, into a symbol representing the instance variable. :@name
|
649
|
+
def self.data_iv_sym(name)
|
650
|
+
"@#{name.to_s}".to_sym
|
651
|
+
end
|
652
|
+
|
653
|
+
# Using the string, name, return the value from the instance variable, @name
|
654
|
+
def self.data_get(name)
|
655
|
+
instance_variable_get(data_iv_sym(name))
|
656
|
+
end
|
657
|
+
|
658
|
+
def self.data_set(name, array)
|
659
|
+
instance_variable_set(data_iv_sym(name), array)
|
660
|
+
end
|
661
|
+
|
662
|
+
# Convert the string, name, into a symbol representing the cached instance variable. :@original_name
|
663
|
+
def self.original_data_iv_sym(name)
|
664
|
+
"@original_#{name.to_s}".to_sym
|
665
|
+
end
|
666
|
+
|
667
|
+
# Using the string, name, return the value from the instance variable, @original_name
|
668
|
+
def self.original_data_get(name)
|
669
|
+
instance_variable_get(original_data_iv_sym(name))
|
670
|
+
end
|
671
|
+
|
672
|
+
def self.original_data_set(name, array)
|
673
|
+
instance_variable_set(original_data_iv_sym(name), array)
|
674
|
+
end
|
675
|
+
|
676
|
+
|
677
|
+
# Clear out one of the data sets being used, returning back what was in it.
|
678
|
+
def self.clear_data(name)
|
679
|
+
remaining_data = data_get(name)
|
680
|
+
data_set(name, nil)
|
681
|
+
remaining_data
|
682
|
+
end
|
683
|
+
|
684
|
+
|
685
|
+
# Save what is currently in the cached array, reload the cache, run a block, and then restore the cached array with what was originally there.
|
686
|
+
def self.with_fresh(name, *other_names, &block)
|
687
|
+
old_values = clear_data(name)
|
688
|
+
next_name = other_names.shift
|
689
|
+
results = next_name ? with_fresh(next_name, *other_names, &block) : yield
|
690
|
+
data_set(name, old_values)
|
691
|
+
results
|
692
|
+
end
|
693
|
+
|
694
|
+
def self.preload
|
695
|
+
%w{
|
696
|
+
adjectives
|
697
|
+
subjects
|
698
|
+
bank_names
|
699
|
+
cities
|
700
|
+
company_names
|
701
|
+
company_types
|
702
|
+
credit_cards
|
703
|
+
credit_union_names
|
704
|
+
domains
|
705
|
+
female_first_names
|
706
|
+
first_names
|
707
|
+
last_names
|
708
|
+
locations
|
709
|
+
female_names
|
710
|
+
female_full_names
|
711
|
+
full_names
|
712
|
+
male_names
|
713
|
+
male_first_names
|
714
|
+
male_full_names
|
715
|
+
names
|
716
|
+
nouns
|
717
|
+
regions
|
718
|
+
slogans
|
719
|
+
slogan_patterns
|
720
|
+
street_names
|
721
|
+
zip_code_state_hash
|
722
|
+
zip_code_states
|
723
|
+
}.each do |name|
|
724
|
+
puts "Preloading #{name}"
|
725
|
+
puts "#{self.send(name).size} #{name} loaded."
|
726
|
+
end
|
727
|
+
puts "Done"
|
728
|
+
end
|
729
|
+
|
730
|
+
|
731
|
+
def self.method_missing(name, *args, &block)
|
732
|
+
name_s = name.to_s
|
733
|
+
if name_s[0..10] == "with_fresh_"
|
734
|
+
with_fresh(name_s[11..-1], &block)
|
735
|
+
elsif name_s[0..8] == "data_for_" && name_s[-3..-1] == "_is"
|
736
|
+
data_for(name_s[9..-4], &block)
|
737
|
+
else super
|
738
|
+
super
|
739
|
+
end
|
740
|
+
end
|
741
|
+
|
742
|
+
|
743
|
+
|
744
|
+
class RandomBankNames < HugeCombination
|
745
|
+
# BANK_PREFIXES.combination(2).map { |x| (x << "Bank").join(' ') }}
|
746
|
+
|
747
|
+
def initialize(bank_prefixes)
|
748
|
+
super(bank_prefixes, 2)
|
749
|
+
end
|
750
|
+
|
751
|
+
def fetch(x)
|
752
|
+
(super(x) << "Bank").join(' ')
|
753
|
+
end
|
754
|
+
|
755
|
+
end
|
756
|
+
|
757
|
+
class RandomCompanyNames < HugeProduct
|
758
|
+
#adjectives.product(nouns).product(company_types).map { |x| x.flatten.join(' ') }
|
759
|
+
|
760
|
+
def initialize(adjectives, nouns, company_types)
|
761
|
+
adjective_nouns = HugeProduct.new(adjectives.map(&:titleize), nouns.map(&:titleize))
|
762
|
+
super(adjective_nouns, company_types.map(&:titleize))
|
763
|
+
end
|
764
|
+
|
765
|
+
def fetch(x)
|
766
|
+
super(x).flatten.join(' ')
|
767
|
+
end
|
768
|
+
|
769
|
+
end
|
770
|
+
|
771
|
+
class RandomCreditUnionNames < HugeCombination
|
772
|
+
# CREDIT_UNION_PREFIXES.combination(2).map { |x| (x << "Credit Union").join(' ') }
|
773
|
+
|
774
|
+
def initialize(credit_union_prefixes)
|
775
|
+
super(credit_union_prefixes, 2)
|
776
|
+
end
|
777
|
+
|
778
|
+
def fetch(x)
|
779
|
+
(super(x) << "Credit Union").join(' ')
|
780
|
+
end
|
781
|
+
|
782
|
+
end
|
783
|
+
|
784
|
+
class RandomDomains < HugeProduct
|
785
|
+
#nouns.permutation(2).map(&:to_s).product(DOMAINS).map { |x| x.join('.') }
|
786
|
+
|
787
|
+
def initialize(nouns, top_level_domains)
|
788
|
+
@nouns = HugePermutation.new(nouns, 2)
|
789
|
+
super(@nouns, top_level_domains)
|
790
|
+
end
|
791
|
+
|
792
|
+
def fetch(x)
|
793
|
+
product = super(x)
|
794
|
+
nouns = product.first
|
795
|
+
"#{nouns.join}.#{product.last}"
|
796
|
+
end
|
797
|
+
|
798
|
+
end
|
799
|
+
|
800
|
+
class RandomNames < HugeProduct
|
801
|
+
|
802
|
+
def initialize(first_names, last_names)
|
803
|
+
super(first_names, last_names)
|
804
|
+
end
|
805
|
+
|
806
|
+
def fetch(x)
|
807
|
+
super(x).join(' ')
|
808
|
+
end
|
809
|
+
|
810
|
+
end
|
811
|
+
|
812
|
+
class RandomLocations < HugeCollection
|
813
|
+
|
814
|
+
def initialize(locations)
|
815
|
+
super(locations.dup)
|
816
|
+
end
|
817
|
+
|
818
|
+
def fetch(x)
|
819
|
+
location = super(x)
|
820
|
+
if location.is_a?(Hash)
|
821
|
+
location = Location.new(location)
|
822
|
+
enum[x] = location
|
823
|
+
end
|
824
|
+
location
|
825
|
+
end
|
826
|
+
|
827
|
+
end
|
828
|
+
|
829
|
+
class RandomReviews < HugeProduct
|
830
|
+
#review_patterns.product(adjectives.product(nouns).permutation(2))
|
831
|
+
|
832
|
+
def initialize(review_patterns, adjectives, nouns)
|
833
|
+
subjects = HugeProduct.new(adjectives, nouns)
|
834
|
+
combined_subjects = HugePermutation.new(subjects, 2)
|
835
|
+
super(review_patterns, combined_subjects)
|
836
|
+
end
|
837
|
+
|
838
|
+
def fetch(x)
|
839
|
+
review = super(x)
|
840
|
+
review.first % review.last.flatten
|
841
|
+
end
|
842
|
+
|
843
|
+
end
|
844
|
+
|
845
|
+
class RandomSlogans < HugeProduct
|
846
|
+
#slogan_patterns.product(adjectives).product(nouns).map { |x| x[0][0] % [x[0][1], x[1]] }
|
847
|
+
def initialize(slogan_patterns, adjectives, nouns)
|
848
|
+
subjects = HugeProduct.new(adjectives, nouns)
|
849
|
+
super(slogan_patterns, subjects)
|
850
|
+
end
|
851
|
+
|
852
|
+
def fetch(x)
|
853
|
+
slogan = super(x)
|
854
|
+
slogan.first % slogan.last
|
855
|
+
end
|
856
|
+
|
857
|
+
end
|
858
|
+
|
859
|
+
class RandomStreetNames < HugeProduct
|
860
|
+
|
861
|
+
def initialize(street_positions, street_names)
|
862
|
+
super(street_positions, street_names)
|
863
|
+
end
|
864
|
+
|
865
|
+
def fetch(x)
|
866
|
+
street = super(x)
|
867
|
+
# Slightly increase the likelihood of a repetition by preventing silly names like "SE Main Street North"
|
868
|
+
if ["North", "South", "East", "West"].any? { |x| street.last.include?(x) }
|
869
|
+
street.last
|
870
|
+
else
|
871
|
+
street.join(' ')
|
872
|
+
end
|
873
|
+
end
|
874
|
+
|
875
|
+
end
|
876
|
+
|
877
|
+
class RandomSubjects < HugeProduct
|
878
|
+
#adjectives.product(nouns).map { |x| x.join(' ') }
|
879
|
+
def initialize(adjectives, nouns)
|
880
|
+
super(adjectives, nouns)
|
881
|
+
end
|
882
|
+
|
883
|
+
def fetch(x)
|
884
|
+
super(x).join(' ')
|
885
|
+
end
|
886
|
+
|
887
|
+
end
|
888
|
+
|
889
|
+
end
|
890
|
+
|