string_pattern 2.3.0 → 2.5.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 +4 -4
- data/CHANGELOG.md +48 -0
- data/README.md +116 -6
- data/lib/string/pattern/add_to_ruby.rb +12 -6
- data/lib/string/pattern/analyze.rb +5 -5
- data/lib/string/pattern/checksum.rb +106 -0
- data/lib/string/pattern/email.rb +21 -0
- data/lib/string/pattern/generate.rb +135 -147
- data/lib/string/pattern/validate.rb +102 -27
- data/lib/string_pattern/version.rb +5 -0
- data/lib/string_pattern.rb +153 -1
- metadata +9 -7
|
@@ -64,6 +64,11 @@ class StringPattern
|
|
|
64
64
|
# the generated string
|
|
65
65
|
###############################################
|
|
66
66
|
def StringPattern.generate(pattern, expected_errors: [], **synonyms)
|
|
67
|
+
rng = synonyms.delete(:_rng)
|
|
68
|
+
if rng.nil?
|
|
69
|
+
base = synonyms.key?(:seed) ? Random.new(synonyms[:seed]) : Random.new
|
|
70
|
+
rng = StringPattern::RandomSource.new(base)
|
|
71
|
+
end
|
|
67
72
|
tries = 0
|
|
68
73
|
begin
|
|
69
74
|
good_result = true
|
|
@@ -79,30 +84,32 @@ class StringPattern
|
|
|
79
84
|
if pattern.kind_of?(Array)
|
|
80
85
|
pattern.each { |pat|
|
|
81
86
|
if pat.kind_of?(Array) # for the case it is one of the values
|
|
82
|
-
pat = pat.sample
|
|
87
|
+
pat = pat.sample(random: rng)
|
|
83
88
|
end
|
|
84
89
|
|
|
85
90
|
if pat.kind_of?(Symbol)
|
|
86
91
|
if pat.to_s.scan(/^!?\d+-?\d*:.+/).size > 0
|
|
87
|
-
string << StringPattern.generate(pat.to_s, expected_errors: expected_errors)
|
|
92
|
+
string << StringPattern.generate(pat.to_s, expected_errors: expected_errors, _rng: rng)
|
|
88
93
|
else
|
|
89
94
|
string << pat.to_s
|
|
90
95
|
end
|
|
91
96
|
elsif pat.kind_of?(String)
|
|
92
97
|
if @optimistic and pat.to_s.scan(/^!?\d+-?\d*:.+/).size > 0
|
|
93
|
-
string << StringPattern.generate(pat.to_s, expected_errors: expected_errors)
|
|
98
|
+
string << StringPattern.generate(pat.to_s, expected_errors: expected_errors, _rng: rng)
|
|
94
99
|
else
|
|
95
100
|
string << pat
|
|
96
101
|
end
|
|
97
102
|
else
|
|
98
|
-
|
|
99
|
-
return ""
|
|
103
|
+
return StringPattern.fail_generation("StringPattern.generate: it seems you supplied wrong array of patterns: #{pattern.inspect}, expected_errors: #{expected_errors.inspect}", StringPattern::InvalidPatternError)
|
|
100
104
|
end
|
|
101
105
|
}
|
|
102
106
|
return string
|
|
103
107
|
elsif pattern.kind_of?(String) or pattern.kind_of?(Symbol)
|
|
104
108
|
patt = StringPattern.analyze(pattern).clone
|
|
105
|
-
|
|
109
|
+
unless patt.kind_of?(Struct)
|
|
110
|
+
raise StringPattern::InvalidPatternError, "pattern argument not valid on StringPattern.generate: #{pattern.inspect}" if @raise_on_error
|
|
111
|
+
return ""
|
|
112
|
+
end
|
|
106
113
|
|
|
107
114
|
min_length = patt.min_length.clone
|
|
108
115
|
max_length = patt.max_length.clone
|
|
@@ -120,17 +127,18 @@ class StringPattern
|
|
|
120
127
|
}
|
|
121
128
|
unless excluded_data.size == 0
|
|
122
129
|
if (required_chars.flatten & excluded_data.flatten).size > 0
|
|
123
|
-
|
|
124
|
-
return ""
|
|
130
|
+
return StringPattern.fail_generation("pattern argument not valid on StringPattern.generate, a character cannot be required and excluded at the same time: #{pattern.inspect}, expected_errors: #{expected_errors.inspect}", StringPattern::InvalidPatternError)
|
|
125
131
|
end
|
|
126
132
|
end
|
|
127
133
|
end
|
|
128
134
|
|
|
129
135
|
string_set_not_allowed = Array.new
|
|
130
136
|
elsif pattern.kind_of?(Regexp)
|
|
131
|
-
return generate(pattern.to_sp, expected_errors: expected_errors)
|
|
137
|
+
return generate(pattern.to_sp, expected_errors: expected_errors, _rng: rng)
|
|
132
138
|
else
|
|
133
|
-
|
|
139
|
+
message = "pattern argument not valid on StringPattern.generate: #{pattern.inspect}, expected_errors: #{expected_errors.inspect}"
|
|
140
|
+
raise StringPattern::InvalidPatternError, message if @raise_on_error
|
|
141
|
+
StringPattern.log_message(message)
|
|
134
142
|
return pattern.to_s
|
|
135
143
|
end
|
|
136
144
|
|
|
@@ -139,8 +147,8 @@ class StringPattern
|
|
|
139
147
|
if symbol_type[0..0] == "!"
|
|
140
148
|
deny_pattern = true
|
|
141
149
|
possible_errors = [:length, :value, :string_set_not_allowed]
|
|
142
|
-
(rand(possible_errors.size) + 1).times {
|
|
143
|
-
expected_errors << possible_errors.sample
|
|
150
|
+
(rng.rand(possible_errors.size) + 1).times {
|
|
151
|
+
expected_errors << possible_errors.sample(random: rng)
|
|
144
152
|
}
|
|
145
153
|
expected_errors.uniq!
|
|
146
154
|
if symbol_type[1..1] == "0"
|
|
@@ -169,21 +177,18 @@ class StringPattern
|
|
|
169
177
|
|
|
170
178
|
unless deny_pattern
|
|
171
179
|
if required_data.size == 0 and expected_errors_left.include?(:required_data)
|
|
172
|
-
|
|
173
|
-
return ""
|
|
180
|
+
return StringPattern.fail_generation("required data not supplied on pattern so it won't be possible to generate a wrong string. StringPattern.generate: #{pattern.inspect}, expected_errors: #{expected_errors.inspect}", StringPattern::GenerationImpossibleError)
|
|
174
181
|
end
|
|
175
182
|
|
|
176
183
|
if excluded_data.size == 0 and expected_errors_left.include?(:excluded_data)
|
|
177
|
-
|
|
178
|
-
return ""
|
|
184
|
+
return StringPattern.fail_generation("excluded data not supplied on pattern so it won't be possible to generate a wrong string. StringPattern.generate: #{pattern.inspect}, expected_errors: #{expected_errors.inspect}", StringPattern::GenerationImpossibleError)
|
|
179
185
|
end
|
|
180
186
|
|
|
181
187
|
if expected_errors_left.include?(:string_set_not_allowed)
|
|
182
188
|
string_set_not_allowed = all_characters_set - string_set
|
|
183
189
|
|
|
184
190
|
if string_set_not_allowed.size == 0
|
|
185
|
-
|
|
186
|
-
return ""
|
|
191
|
+
return StringPattern.fail_generation("all characters are allowed so it won't be possible to generate a wrong string. StringPattern.generate: #{pattern.inspect}, expected_errors: #{expected_errors.inspect}", StringPattern::GenerationImpossibleError)
|
|
187
192
|
end
|
|
188
193
|
end
|
|
189
194
|
end
|
|
@@ -192,12 +197,12 @@ class StringPattern
|
|
|
192
197
|
expected_errors_left.include?(:max_length) or
|
|
193
198
|
expected_errors_left.include?(:length)
|
|
194
199
|
if expected_errors_left.include?(:min_length) or
|
|
195
|
-
(min_length > 0 and expected_errors_left.include?(:length) and rand(2) == 0)
|
|
200
|
+
(min_length > 0 and expected_errors_left.include?(:length) and rng.rand(2) == 0)
|
|
196
201
|
if min_length > 0
|
|
197
202
|
if allow_empty
|
|
198
|
-
length = rand(min_length).to_i
|
|
203
|
+
length = rng.rand(min_length).to_i
|
|
199
204
|
else
|
|
200
|
-
length = rand(min_length - 1).to_i + 1
|
|
205
|
+
length = rng.rand(min_length - 1).to_i + 1
|
|
201
206
|
end
|
|
202
207
|
if required_data.size > length and required_data.size < min_length
|
|
203
208
|
length = required_data.size
|
|
@@ -205,22 +210,21 @@ class StringPattern
|
|
|
205
210
|
expected_errors_left.delete(:length)
|
|
206
211
|
expected_errors_left.delete(:min_length)
|
|
207
212
|
else
|
|
208
|
-
|
|
209
|
-
return ""
|
|
213
|
+
return StringPattern.fail_generation("min_length is 0 so it won't be possible to generate a wrong string smaller than 0 characters. StringPattern.generate: #{pattern.inspect}, expected_errors: #{expected_errors.inspect}", StringPattern::GenerationImpossibleError)
|
|
210
214
|
end
|
|
211
215
|
elsif expected_errors_left.include?(:max_length) or expected_errors_left.include?(:length)
|
|
212
|
-
length = max_length + 1 + rand(max_length).to_i
|
|
216
|
+
length = max_length + 1 + rng.rand(max_length).to_i
|
|
213
217
|
expected_errors_left.delete(:length)
|
|
214
218
|
expected_errors_left.delete(:max_length)
|
|
215
219
|
end
|
|
216
220
|
else
|
|
217
|
-
if allow_empty and rand(7) == 1
|
|
221
|
+
if allow_empty and rng.rand(7) == 1
|
|
218
222
|
length = 0
|
|
219
223
|
else
|
|
220
224
|
if max_length == min_length
|
|
221
225
|
length = min_length
|
|
222
226
|
else
|
|
223
|
-
length = min_length + rand(max_length - min_length + 1)
|
|
227
|
+
length = min_length + rng.rand(max_length - min_length + 1)
|
|
224
228
|
end
|
|
225
229
|
end
|
|
226
230
|
end
|
|
@@ -251,28 +255,27 @@ class StringPattern
|
|
|
251
255
|
if symbol_type != "@" and symbol_type != "!@" and length != 0 and string_set.size != 0
|
|
252
256
|
if string_set.size != 0
|
|
253
257
|
1.upto(length) { |i|
|
|
254
|
-
string << string_set.sample.to_s
|
|
258
|
+
string << string_set.sample(random: rng).to_s
|
|
255
259
|
}
|
|
256
260
|
end
|
|
257
261
|
if required_data.size > 0
|
|
258
262
|
positions_to_set = (0..(string.size - 1)).to_a
|
|
259
263
|
required_data.each { |rd|
|
|
260
264
|
if (string.chars & rd).size > 0
|
|
261
|
-
rd_to_set = (string.chars & rd).sample
|
|
265
|
+
rd_to_set = (string.chars & rd).sample(random: rng)
|
|
262
266
|
else
|
|
263
|
-
rd_to_set = rd.sample
|
|
267
|
+
rd_to_set = rd.sample(random: rng)
|
|
264
268
|
end
|
|
265
269
|
if ((0...string.length).find_all { |i| string[i, 1] == rd_to_set }).size == 0
|
|
266
270
|
if positions_to_set.size == 0
|
|
267
|
-
|
|
268
|
-
return ""
|
|
271
|
+
return StringPattern.fail_generation("pattern not valid on StringPattern.generate, not possible to generate a valid string: #{pattern.inspect}, expected_errors: #{expected_errors.inspect}", StringPattern::GenerationImpossibleError)
|
|
269
272
|
else
|
|
270
|
-
k = positions_to_set.sample
|
|
273
|
+
k = positions_to_set.sample(random: rng)
|
|
271
274
|
string[k] = rd_to_set
|
|
272
275
|
positions_to_set.delete(k)
|
|
273
276
|
end
|
|
274
277
|
else
|
|
275
|
-
k = ((0...string.length).find_all { |i| string[i, 1] == rd_to_set }).sample
|
|
278
|
+
k = ((0...string.length).find_all { |i| string[i, 1] == rd_to_set }).sample(random: rng)
|
|
276
279
|
positions_to_set.delete(k)
|
|
277
280
|
end
|
|
278
281
|
}
|
|
@@ -280,7 +283,7 @@ class StringPattern
|
|
|
280
283
|
excluded_data.each { |ed|
|
|
281
284
|
if (string.chars & ed).size > 0
|
|
282
285
|
(string.chars & ed).each { |s|
|
|
283
|
-
string.gsub!(s, string_set.sample)
|
|
286
|
+
string.gsub!(s, string_set.sample(random: rng))
|
|
284
287
|
}
|
|
285
288
|
end
|
|
286
289
|
}
|
|
@@ -289,28 +292,27 @@ class StringPattern
|
|
|
289
292
|
string_set_not_allowed = all_characters_set - string_set if string_set_not_allowed.size == 0
|
|
290
293
|
|
|
291
294
|
if string_set_not_allowed.size == 0
|
|
292
|
-
|
|
293
|
-
return ""
|
|
295
|
+
return StringPattern.fail_generation("Not possible to generate a non valid string on StringPattern.generate: #{pattern.inspect}, expected_errors: #{expected_errors.inspect}", StringPattern::GenerationImpossibleError)
|
|
294
296
|
end
|
|
295
|
-
(rand(string.size) + 1).times {
|
|
296
|
-
string[rand(string.size)] = (all_characters_set - string_set).sample
|
|
297
|
+
(rng.rand(string.size) + 1).times {
|
|
298
|
+
string[rng.rand(string.size)] = (all_characters_set - string_set).sample(random: rng)
|
|
297
299
|
}
|
|
298
300
|
expected_errors_left.delete(:value)
|
|
299
301
|
end
|
|
300
302
|
|
|
301
303
|
if expected_errors_left.include?(:required_data) and required_data.size > 0
|
|
302
|
-
(rand(required_data.size) + 1).times {
|
|
303
|
-
chars_to_remove = required_data.sample
|
|
304
|
+
(rng.rand(required_data.size) + 1).times {
|
|
305
|
+
chars_to_remove = required_data.sample(random: rng)
|
|
304
306
|
chars_to_remove.each { |char_to_remove|
|
|
305
|
-
string.gsub!(char_to_remove, (string_set - chars_to_remove).sample)
|
|
307
|
+
string.gsub!(char_to_remove, (string_set - chars_to_remove).sample(random: rng))
|
|
306
308
|
}
|
|
307
309
|
}
|
|
308
310
|
expected_errors_left.delete(:required_data)
|
|
309
311
|
end
|
|
310
312
|
|
|
311
313
|
if expected_errors_left.include?(:excluded_data) and excluded_data.size > 0
|
|
312
|
-
(rand(string.size) + 1).times {
|
|
313
|
-
string[rand(string.size)] = excluded_data.sample.sample
|
|
314
|
+
(rng.rand(string.size) + 1).times {
|
|
315
|
+
string[rng.rand(string.size)] = excluded_data.sample(random: rng).sample(random: rng)
|
|
314
316
|
}
|
|
315
317
|
expected_errors_left.delete(:excluded_data)
|
|
316
318
|
end
|
|
@@ -318,67 +320,21 @@ class StringPattern
|
|
|
318
320
|
if expected_errors_left.include?(:string_set_not_allowed)
|
|
319
321
|
string_set_not_allowed = all_characters_set - string_set if string_set_not_allowed.size == 0
|
|
320
322
|
if string_set_not_allowed.size > 0
|
|
321
|
-
(rand(string.size) + 1).times {
|
|
322
|
-
string[rand(string.size)] = string_set_not_allowed.sample
|
|
323
|
+
(rng.rand(string.size) + 1).times {
|
|
324
|
+
string[rng.rand(string.size)] = string_set_not_allowed.sample(random: rng)
|
|
323
325
|
}
|
|
324
326
|
expected_errors_left.delete(:string_set_not_allowed)
|
|
325
327
|
end
|
|
326
328
|
end
|
|
327
329
|
elsif (symbol_type == "W" or symbol_type == "P" or symbol_type == "w" or symbol_type == "p") and length > 0
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
filename = File.join Pathname(File.dirname(__FILE__)), "../../../data", "english/nouns.json"
|
|
335
|
-
nouns = JSON.parse(File.read(filename))
|
|
336
|
-
filename = File.join Pathname(File.dirname(__FILE__)), "../../../data", "english/adjs.json"
|
|
337
|
-
adjs = JSON.parse(File.read(filename))
|
|
338
|
-
nouns = nouns.map(&:to_camel_case)
|
|
339
|
-
adjs = adjs.map(&:to_camel_case)
|
|
340
|
-
@words_camel = adjs + nouns
|
|
341
|
-
@words_camel_short = @words_camel.sample(2000)
|
|
342
|
-
end
|
|
343
|
-
words = @words_camel
|
|
344
|
-
words_short = @words_camel_short
|
|
345
|
-
elsif symbol_type == "w"
|
|
346
|
-
if @words.empty?
|
|
347
|
-
require "pathname"
|
|
348
|
-
require "json"
|
|
349
|
-
filename = File.join Pathname(File.dirname(__FILE__)), "../../../data", "english/nouns.json"
|
|
350
|
-
nouns = JSON.parse(File.read(filename))
|
|
351
|
-
filename = File.join Pathname(File.dirname(__FILE__)), "../../../data", "english/adjs.json"
|
|
352
|
-
adjs = JSON.parse(File.read(filename))
|
|
353
|
-
@words = adjs + nouns
|
|
354
|
-
@words_short = @words.sample(2000)
|
|
355
|
-
end
|
|
356
|
-
words = @words
|
|
357
|
-
words_short = @words_short
|
|
358
|
-
elsif symbol_type == "P"
|
|
359
|
-
if @palabras_camel.empty?
|
|
360
|
-
require "pathname"
|
|
361
|
-
require "json"
|
|
362
|
-
filename = File.join Pathname(File.dirname(__FILE__)), "../../../data", "spanish/palabras#{rand(12)}.json"
|
|
363
|
-
palabras = JSON.parse(File.read(filename))
|
|
364
|
-
palabras = palabras.map(&:to_camel_case)
|
|
365
|
-
@palabras_camel = palabras
|
|
366
|
-
@palabras_camel_short = @palabras_camel.sample(2000)
|
|
367
|
-
end
|
|
368
|
-
words = @palabras_camel
|
|
369
|
-
words_short = @palabras_camel_short
|
|
370
|
-
elsif symbol_type == "p"
|
|
371
|
-
if @palabras.empty?
|
|
372
|
-
require "pathname"
|
|
373
|
-
require "json"
|
|
374
|
-
filename = File.join Pathname(File.dirname(__FILE__)), "../../../data", "spanish/palabras#{rand(12)}.json"
|
|
375
|
-
palabras = JSON.parse(File.read(filename))
|
|
376
|
-
@palabras = palabras
|
|
377
|
-
@palabras_short = @palabras.sample(2000)
|
|
378
|
-
end
|
|
379
|
-
words = @palabras
|
|
380
|
-
words_short = @palabras_short
|
|
330
|
+
if symbol_type == "W" || symbol_type == "w"
|
|
331
|
+
load_english_words(camel: symbol_type == "W")
|
|
332
|
+
words = symbol_type == "W" ? @words_camel : @words
|
|
333
|
+
else
|
|
334
|
+
load_spanish_words(camel: symbol_type == "P")
|
|
335
|
+
words = symbol_type == "P" ? @palabras_camel : @palabras
|
|
381
336
|
end
|
|
337
|
+
words_short = words.sample(2000, random: rng)
|
|
382
338
|
|
|
383
339
|
wordr = ""
|
|
384
340
|
wordr_array = []
|
|
@@ -392,16 +348,16 @@ class StringPattern
|
|
|
392
348
|
end
|
|
393
349
|
if symbol_type == "w" or symbol_type == "p"
|
|
394
350
|
length = length - 1 if wordr_array.size > 0
|
|
395
|
-
res = (words_short.select { |word| word.length <= length && word.length != length - 1 && word.length != length - 2 && word.length != length - 3 }).sample.to_s
|
|
351
|
+
res = (words_short.select { |word| word.length <= length && word.length != length - 1 && word.length != length - 2 && word.length != length - 3 }).sample(random: rng).to_s
|
|
396
352
|
unless res.to_s == ""
|
|
397
353
|
wordr_array << res
|
|
398
354
|
wordr = wordr_array.join(@word_separator)
|
|
399
355
|
end
|
|
400
356
|
else
|
|
401
|
-
wordr += (words_short.select { |word| word.length <= length && word.length != length - 1 && word.length != length - 2 && word.length != length - 3 }).sample.to_s
|
|
357
|
+
wordr += (words_short.select { |word| word.length <= length && word.length != length - 1 && word.length != length - 2 && word.length != length - 3 }).sample(random: rng).to_s
|
|
402
358
|
end
|
|
403
359
|
if (tries % 100) == 0
|
|
404
|
-
words_short = words.sample(2000)
|
|
360
|
+
words_short = words.sample(2000, random: rng)
|
|
405
361
|
end
|
|
406
362
|
end
|
|
407
363
|
good_result = true
|
|
@@ -434,60 +390,60 @@ class StringPattern
|
|
|
434
390
|
at_sign = "@"
|
|
435
391
|
|
|
436
392
|
if expected_errors_left.include?(:value)
|
|
437
|
-
if rand(2) == 1
|
|
438
|
-
extension = (all_characters_set - ["."]).sample.dup
|
|
393
|
+
if rng.rand(2) == 1
|
|
394
|
+
extension = (all_characters_set - ["."]).sample(random: rng).dup
|
|
439
395
|
expected_errors_left.delete(:value)
|
|
440
396
|
expected_errors_left.delete(:required_data)
|
|
441
397
|
end
|
|
442
398
|
|
|
443
|
-
if rand(2) == 1
|
|
444
|
-
1.upto(rand(7)) { |i|
|
|
445
|
-
extension << alpha_set.sample.downcase
|
|
399
|
+
if rng.rand(2) == 1
|
|
400
|
+
1.upto(rng.rand(7)) { |i|
|
|
401
|
+
extension << alpha_set.sample(random: rng).downcase
|
|
446
402
|
}
|
|
447
403
|
|
|
448
|
-
(rand(extension.size) + 1).times {
|
|
449
|
-
extension[rand(extension.size)] = (string_set - alpha_set - ["."]).sample
|
|
404
|
+
(rng.rand(extension.size) + 1).times {
|
|
405
|
+
extension[rng.rand(extension.size)] = (string_set - alpha_set - ["."]).sample(random: rng)
|
|
450
406
|
}
|
|
451
407
|
|
|
452
408
|
expected_errors_left.delete(:value)
|
|
453
409
|
else
|
|
454
|
-
1.upto(rand(3) + 2) { |i|
|
|
455
|
-
extension << alpha_set.sample.downcase
|
|
410
|
+
1.upto(rng.rand(3) + 2) { |i|
|
|
411
|
+
extension << alpha_set.sample(random: rng).downcase
|
|
456
412
|
}
|
|
457
413
|
end
|
|
458
414
|
|
|
459
|
-
if rand(2) == 1
|
|
460
|
-
at_sign = (string_set - ["@"]).sample.dup
|
|
415
|
+
if rng.rand(2) == 1
|
|
416
|
+
at_sign = (string_set - ["@"]).sample(random: rng).dup
|
|
461
417
|
expected_errors_left.delete(:value)
|
|
462
418
|
expected_errors_left.delete(:required_data)
|
|
463
419
|
end
|
|
464
420
|
else
|
|
465
421
|
if length > 6
|
|
466
|
-
1.upto(rand(3) + 2) { |i|
|
|
467
|
-
extension << alpha_set.sample.downcase
|
|
422
|
+
1.upto(rng.rand(3) + 2) { |i|
|
|
423
|
+
extension << alpha_set.sample(random: rng).downcase
|
|
468
424
|
}
|
|
469
425
|
else
|
|
470
426
|
1.upto(2) { |i|
|
|
471
|
-
extension << alpha_set.sample.downcase
|
|
427
|
+
extension << alpha_set.sample(random: rng).downcase
|
|
472
428
|
}
|
|
473
429
|
end
|
|
474
430
|
end
|
|
475
431
|
length_e = length - extension.size - 1
|
|
476
|
-
length1 = rand(length_e - 1) + 1
|
|
432
|
+
length1 = rng.rand(length_e - 1) + 1
|
|
477
433
|
length2 = length_e - length1
|
|
478
|
-
1.upto(length1) { |i| string << string_set.sample }
|
|
434
|
+
1.upto(length1) { |i| string << string_set.sample(random: rng) }
|
|
479
435
|
|
|
480
436
|
string << at_sign
|
|
481
437
|
|
|
482
438
|
domain = ""
|
|
483
439
|
domain_set = alpha_set + NUMBER_SET.clone + ["."] + ["-"]
|
|
484
440
|
1.upto(length2) { |i|
|
|
485
|
-
domain << domain_set.sample.downcase
|
|
441
|
+
domain << domain_set.sample(random: rng).downcase
|
|
486
442
|
}
|
|
487
443
|
|
|
488
|
-
if expected_errors.include?(:value) and rand(2) == 1 and domain.size > 0
|
|
489
|
-
(rand(domain.size) + 1).times {
|
|
490
|
-
domain[rand(domain.size)] = (all_characters_set - domain_set).sample
|
|
444
|
+
if expected_errors.include?(:value) and rng.rand(2) == 1 and domain.size > 0
|
|
445
|
+
(rng.rand(domain.size) + 1).times {
|
|
446
|
+
domain[rng.rand(domain.size)] = (all_characters_set - domain_set).sample(random: rng)
|
|
491
447
|
}
|
|
492
448
|
expected_errors_left.delete(:value)
|
|
493
449
|
end
|
|
@@ -495,31 +451,18 @@ class StringPattern
|
|
|
495
451
|
string << domain << extension
|
|
496
452
|
|
|
497
453
|
if expected_errors_left.include?(:value) or expected_errors_left.include?(:string_set_not_allowed)
|
|
498
|
-
(rand(string.size) + 1).times {
|
|
499
|
-
string[rand(string.size)] = string_set_not_allowed.sample
|
|
454
|
+
(rng.rand(string.size) + 1).times {
|
|
455
|
+
string[rng.rand(string.size)] = string_set_not_allowed.sample(random: rng)
|
|
500
456
|
}
|
|
501
457
|
expected_errors_left.delete(:value)
|
|
502
458
|
expected_errors_left.delete(:string_set_not_allowed)
|
|
503
459
|
end
|
|
504
460
|
|
|
505
|
-
error_regular_expression =
|
|
461
|
+
error_regular_expression = !StringPattern.valid_email?(string)
|
|
506
462
|
|
|
507
463
|
if deny_pattern and expected_errors.include?(:length)
|
|
508
464
|
good_result = true #it is already with wrong length
|
|
509
465
|
else
|
|
510
|
-
# I'm doing this because many times the regular expression checking hangs with these characters
|
|
511
|
-
wrong = %w(.. __ -- ._ _. .- -. _- -_ @. @_ @- .@ _@ -@ @@)
|
|
512
|
-
if !(Regexp.union(*wrong) === string) #don't include any or the wrong strings
|
|
513
|
-
if string.index("@").to_i > 0 and
|
|
514
|
-
string[0..(string.index("@") - 1)].scan(/([a-z0-9]+([\+\._\-][a-z0-9]|)*)/i).join == string[0..(string.index("@") - 1)] and
|
|
515
|
-
string[(string.index("@") + 1)..-1].scan(/([0-9a-z]+([\.-][a-z0-9]|)*)/i).join == string[string[(string.index("@") + 1)..-1]]
|
|
516
|
-
error_regular_expression = false
|
|
517
|
-
else
|
|
518
|
-
error_regular_expression = true
|
|
519
|
-
end
|
|
520
|
-
else
|
|
521
|
-
error_regular_expression = true
|
|
522
|
-
end
|
|
523
466
|
|
|
524
467
|
if expected_errors.size == 0
|
|
525
468
|
if error_regular_expression
|
|
@@ -540,8 +483,7 @@ class StringPattern
|
|
|
540
483
|
end
|
|
541
484
|
end until good_result or tries > 100
|
|
542
485
|
unless good_result
|
|
543
|
-
|
|
544
|
-
return ""
|
|
486
|
+
return StringPattern.fail_generation("Not possible to generate an email on StringPattern.generate: #{pattern.inspect}, expected_errors: #{expected_errors.inspect}", StringPattern::GenerationImpossibleError)
|
|
545
487
|
end
|
|
546
488
|
end
|
|
547
489
|
if @dont_repeat
|
|
@@ -569,21 +511,67 @@ class StringPattern
|
|
|
569
511
|
end
|
|
570
512
|
end
|
|
571
513
|
if @block_list_enabled
|
|
572
|
-
if @block_list.
|
|
573
|
-
@block_list.
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
514
|
+
if @block_list.respond_to?(:call)
|
|
515
|
+
good_result = false if @block_list.call(string)
|
|
516
|
+
elsif @block_list.is_a?(Array)
|
|
517
|
+
if @block_list_regexp
|
|
518
|
+
@block_list.each do |bl|
|
|
519
|
+
if string.match?(/#{bl}/i)
|
|
520
|
+
good_result = false
|
|
521
|
+
break
|
|
522
|
+
end
|
|
523
|
+
end
|
|
524
|
+
else
|
|
525
|
+
downcased = string.downcase
|
|
526
|
+
@block_list.each do |bl|
|
|
527
|
+
if downcased.include?(bl.to_s.downcase)
|
|
528
|
+
good_result = false
|
|
529
|
+
break
|
|
530
|
+
end
|
|
577
531
|
end
|
|
578
532
|
end
|
|
579
533
|
end
|
|
580
534
|
end
|
|
581
535
|
end until good_result or tries > 10000
|
|
582
536
|
unless good_result
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
return
|
|
537
|
+
msg = "Not possible to generate the string on StringPattern.generate: #{pattern.inspect}, expected_errors: #{expected_errors.inspect}"
|
|
538
|
+
msg += "\nTake in consideration if you are using StringPattern.dont_repeat=true that you don't try to generate more strings that are possible to be generated"
|
|
539
|
+
return StringPattern.fail_generation(msg, StringPattern::GenerationImpossibleError)
|
|
586
540
|
end
|
|
587
541
|
return string
|
|
588
542
|
end
|
|
543
|
+
|
|
544
|
+
def self.fail_generation(message, error_class)
|
|
545
|
+
raise error_class, message if @raise_on_error
|
|
546
|
+
log_message(message)
|
|
547
|
+
""
|
|
548
|
+
end
|
|
549
|
+
|
|
550
|
+
def self.word_data_path(*parts)
|
|
551
|
+
File.join(__dir__, "..", "..", "..", "data", *parts)
|
|
552
|
+
end
|
|
553
|
+
|
|
554
|
+
def self.load_english_words(camel: false)
|
|
555
|
+
require "json"
|
|
556
|
+
if @words.nil? || @words.empty?
|
|
557
|
+
nouns = JSON.parse(File.read(word_data_path("english", "nouns.json")))
|
|
558
|
+
adjs = JSON.parse(File.read(word_data_path("english", "adjs.json")))
|
|
559
|
+
@words = adjs + nouns
|
|
560
|
+
end
|
|
561
|
+
if camel && (@words_camel.nil? || @words_camel.empty?)
|
|
562
|
+
@words_camel = @words.map(&:to_camel_case)
|
|
563
|
+
end
|
|
564
|
+
end
|
|
565
|
+
|
|
566
|
+
def self.load_spanish_words(camel: false)
|
|
567
|
+
require "json"
|
|
568
|
+
if @palabras.nil? || @palabras.empty?
|
|
569
|
+
@palabras = (0..11).flat_map do |i|
|
|
570
|
+
JSON.parse(File.read(word_data_path("spanish", "palabras#{i}.json")))
|
|
571
|
+
end
|
|
572
|
+
end
|
|
573
|
+
if camel && (@palabras_camel.nil? || @palabras_camel.empty?)
|
|
574
|
+
@palabras_camel = @palabras.map(&:to_camel_case)
|
|
575
|
+
end
|
|
576
|
+
end
|
|
589
577
|
end
|