sevenwire-forgery 0.1.0 → 0.2.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.
- data/README.markdown +17 -8
- data/VERSION.yml +1 -1
- data/lib/dictionaries.rb +24 -0
- data/lib/file_reader.rb +53 -0
- data/lib/forgeries/address_forgery.rb +9 -12
- data/lib/forgeries/basic_forgery.rb +2 -4
- data/lib/forgeries/internet_forgery.rb +3 -5
- data/lib/forgeries/lorem_ipsum_forgery.rb +17 -12
- data/lib/forgeries/name_forgery.rb +7 -9
- data/lib/forgeries/personal_forgery.rb +4 -5
- data/lib/forgery.rb +22 -57
- data/lib/formats.rb +24 -0
- data/spec/dictionaries_spec.rb +35 -0
- data/spec/file_reader_spec.rb +11 -0
- data/spec/forgeries/address_forgery_spec.rb +12 -12
- data/spec/forgeries/basic_forgery_spec.rb +1 -1
- data/spec/forgeries/internet_forgery_spec.rb +4 -4
- data/spec/forgeries/personal_forgery_spec.rb +2 -2
- data/spec/forgery_spec.rb +16 -10
- data/spec/formats_spec.rb +35 -0
- data/spec/spec_helper.rb +1 -0
- metadata +8 -2
data/README.markdown
CHANGED
|
@@ -21,11 +21,11 @@ Generator
|
|
|
21
21
|
|
|
22
22
|
In a rails project this generator creates:
|
|
23
23
|
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
*
|
|
28
|
-
*
|
|
24
|
+
* RAILS\_ROOT/lib/forgery
|
|
25
|
+
* RAILS\_ROOT/lib/forgery/dictionaries
|
|
26
|
+
* RAILS\_ROOT/lib/forgery/extensions
|
|
27
|
+
* RAILS\_ROOT/lib/forgery/forgeries
|
|
28
|
+
* RAILS\_ROOT/lib/forgery/formats
|
|
29
29
|
|
|
30
30
|
You can then use these directories to write your own dictionaries, class
|
|
31
31
|
extensions, forgeries, and formats.
|
|
@@ -45,6 +45,7 @@ Here I'll supply a few examples of how it works, in general. See each forgery
|
|
|
45
45
|
for individual examples.
|
|
46
46
|
|
|
47
47
|
<pre><code>
|
|
48
|
+
# Traditional syntax
|
|
48
49
|
BasicForgery.password # => "wYMYvq"
|
|
49
50
|
BasicForgery.password :allow_special => true # => ";Qo^N[T"
|
|
50
51
|
BasicForgery.hex_color # => "#f4d841"
|
|
@@ -52,20 +53,28 @@ BasicForgery.hex_color # => "#f4d841"
|
|
|
52
53
|
MonetaryForgery.money # => "8.21"
|
|
53
54
|
MonetaryForgery.formatted_money # => "$3.25"
|
|
54
55
|
MonetaryForgery.money :min => 100, :max => 1000 # => "848.97"
|
|
56
|
+
|
|
57
|
+
# Alternate syntax
|
|
58
|
+
Forgery(:basic).password # => "b6qZTQEH"
|
|
59
|
+
Forgery(:basic).password :allow_special => true # => "XlrhV%An"
|
|
60
|
+
Forgery(:basic).hex_color # => "#46b73f"
|
|
61
|
+
|
|
62
|
+
Forgery(:monetary).money # => "1.58"
|
|
63
|
+
Forgery(:monetary).formatted_money # => "$3.48"
|
|
64
|
+
Forgery(:monetary).money :min => 100, :max => 1000 # => "923.36"
|
|
55
65
|
</code></pre>
|
|
56
66
|
|
|
57
67
|
TODO
|
|
58
68
|
====
|
|
59
69
|
|
|
60
|
-
*
|
|
61
|
-
* Add secondary syntax similar to Factory Girl (or better?)
|
|
70
|
+
* Add instanced forgeries for more relative information generation.
|
|
62
71
|
|
|
63
72
|
Thanks
|
|
64
73
|
======
|
|
65
74
|
|
|
66
75
|
Thanks to the authors and contributors:
|
|
67
76
|
|
|
68
|
-
*
|
|
77
|
+
* Nate Sutton (nate aka fowlduck)
|
|
69
78
|
* Brandon Arbini (brandonarbini)
|
|
70
79
|
* Josh Nichols (technicalpickles)
|
|
71
80
|
* Jeremy Stephens (viking aka crookshanks)
|
data/VERSION.yml
CHANGED
data/lib/dictionaries.rb
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class Dictionaries
|
|
2
|
+
|
|
3
|
+
def initialize
|
|
4
|
+
@dictionaries = {}
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def [](key)
|
|
8
|
+
symbolized_key = key.to_sym
|
|
9
|
+
if loaded?(symbolized_key)
|
|
10
|
+
@dictionaries[symbolized_key]
|
|
11
|
+
else
|
|
12
|
+
@dictionaries[symbolized_key] = FileReader.read_dictionary(symbolized_key)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def loaded?(key)
|
|
17
|
+
@dictionaries.has_key?(key.to_sym)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def reset!
|
|
21
|
+
@dictionaries = {}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
data/lib/file_reader.rb
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
class FileReader
|
|
2
|
+
|
|
3
|
+
def self.read_dictionary(dictionary)
|
|
4
|
+
read_file(path_to_dictionary(dictionary))
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def self.read_format(format)
|
|
8
|
+
read_file(path_to_format(format))
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
protected
|
|
12
|
+
|
|
13
|
+
def self.read_file(file)
|
|
14
|
+
lines = []
|
|
15
|
+
IO.foreach(file) do |line|
|
|
16
|
+
lines << line.chomp unless line.chomp == ''
|
|
17
|
+
end
|
|
18
|
+
lines
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
def self.path_to_format(format)
|
|
22
|
+
if external_path_to_format(format) && File.exists?(external_path_to_format(format))
|
|
23
|
+
external_path_to_format(format)
|
|
24
|
+
else
|
|
25
|
+
internal_path_to_format(format)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.external_path_to_format(format)
|
|
30
|
+
RAILS_ROOT + '/lib/forgery/formats/' + format.to_s if defined?(RAILS_ROOT)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def self.internal_path_to_format(format)
|
|
34
|
+
File.dirname(__FILE__) + '/formats/' + format.to_s
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def self.path_to_dictionary(dictionary)
|
|
38
|
+
if external_path_to_dictionary(dictionary) && File.exists?(external_path_to_dictionary(dictionary))
|
|
39
|
+
external_path_to_dictionary(dictionary)
|
|
40
|
+
else
|
|
41
|
+
internal_path_to_dictionary(dictionary)
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def self.external_path_to_dictionary(dictionary)
|
|
46
|
+
RAILS_ROOT + '/lib/forgery/dictionaries/' + dictionary.to_s if defined?(RAILS_ROOT)
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def self.internal_path_to_dictionary(dictionary)
|
|
50
|
+
File.dirname(__FILE__) + '/dictionaries/' + dictionary.to_s
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
end
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
# Generates random address information.
|
|
2
2
|
class AddressForgery < Forgery
|
|
3
|
-
dictionaries :streets, :street_suffixes, :cities, :states, :state_abbrevs, :countries
|
|
4
|
-
formats :zip, :phone, :street_number
|
|
5
|
-
|
|
6
3
|
# Gets a random street name out of the 'streets' dictionary.
|
|
7
4
|
#
|
|
8
5
|
# AddressForgery.street_name
|
|
@@ -11,7 +8,7 @@ class AddressForgery < Forgery
|
|
|
11
8
|
# AddressForgery.street_name
|
|
12
9
|
# # => "Fordem"
|
|
13
10
|
def self.street_name
|
|
14
|
-
|
|
11
|
+
dictionaries[:streets].random
|
|
15
12
|
end
|
|
16
13
|
|
|
17
14
|
# Gets one of the formats from 'street_number_formats' and converts it to
|
|
@@ -23,7 +20,7 @@ class AddressForgery < Forgery
|
|
|
23
20
|
# AddressForgery.street_number
|
|
24
21
|
# # => 1234
|
|
25
22
|
def self.street_number
|
|
26
|
-
|
|
23
|
+
formats[:street_number].random.to_numbers
|
|
27
24
|
end
|
|
28
25
|
|
|
29
26
|
# Gets a random street suffix out of the 'street_suffixes' dictionary.
|
|
@@ -34,7 +31,7 @@ class AddressForgery < Forgery
|
|
|
34
31
|
# AddressForgery.street_suffix
|
|
35
32
|
# # => "Parkway"
|
|
36
33
|
def self.street_suffix
|
|
37
|
-
|
|
34
|
+
dictionaries[:street_suffixes].random
|
|
38
35
|
end
|
|
39
36
|
|
|
40
37
|
# Gets a full street address, including street number, street name, and
|
|
@@ -57,7 +54,7 @@ class AddressForgery < Forgery
|
|
|
57
54
|
# AddressForgery.city
|
|
58
55
|
# # => "Sacramento"
|
|
59
56
|
def self.city
|
|
60
|
-
|
|
57
|
+
dictionaries[:cities].random
|
|
61
58
|
end
|
|
62
59
|
|
|
63
60
|
# Gets a random state out of the 'states' dictionary.
|
|
@@ -68,7 +65,7 @@ class AddressForgery < Forgery
|
|
|
68
65
|
# AddressForgery.state
|
|
69
66
|
# # => "Minnesota"
|
|
70
67
|
def self.state
|
|
71
|
-
|
|
68
|
+
dictionaries[:states].random
|
|
72
69
|
end
|
|
73
70
|
|
|
74
71
|
# Gets a random state abbreviation out of the 'state_abbrev' dictionary.
|
|
@@ -79,7 +76,7 @@ class AddressForgery < Forgery
|
|
|
79
76
|
# AddressForgery.state_abbrev
|
|
80
77
|
# # => "TX"
|
|
81
78
|
def self.state_abbrev
|
|
82
|
-
|
|
79
|
+
dictionaries[:state_abbrevs].random
|
|
83
80
|
end
|
|
84
81
|
|
|
85
82
|
# Gets one of the formats from 'zip_formats' and converts it to numbers.
|
|
@@ -90,7 +87,7 @@ class AddressForgery < Forgery
|
|
|
90
87
|
# AddressForgery.zip
|
|
91
88
|
# # => "66702-4349"
|
|
92
89
|
def self.zip
|
|
93
|
-
|
|
90
|
+
formats[:zip].random.to_numbers
|
|
94
91
|
end
|
|
95
92
|
|
|
96
93
|
# Gets one of the formats from 'phone_formats' and converts it to numbers.
|
|
@@ -101,7 +98,7 @@ class AddressForgery < Forgery
|
|
|
101
98
|
# AddressForgery.phone
|
|
102
99
|
# # => "1-(589)248-0418"
|
|
103
100
|
def self.phone
|
|
104
|
-
|
|
101
|
+
formats[:phone].random.to_numbers
|
|
105
102
|
end
|
|
106
103
|
|
|
107
104
|
# Gets a random country out of the 'countries' dictionary.
|
|
@@ -112,6 +109,6 @@ class AddressForgery < Forgery
|
|
|
112
109
|
# AddressForgery.country
|
|
113
110
|
# # => "Romania"
|
|
114
111
|
def self.country
|
|
115
|
-
|
|
112
|
+
dictionaries[:countries].random
|
|
116
113
|
end
|
|
117
114
|
end
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
require 'digest/sha1'
|
|
2
2
|
|
|
3
3
|
class BasicForgery < Forgery
|
|
4
|
-
dictionaries :colors, :frequencies
|
|
5
|
-
|
|
6
4
|
HEX_DIGITS = %w{0 1 2 3 4 5 6 7 8 9 a b c d e f}
|
|
7
5
|
UPPER_ALPHA = ('A'..'Z').to_a
|
|
8
6
|
LOWER_ALPHA = ('a'..'z').to_a
|
|
@@ -29,7 +27,7 @@ class BasicForgery < Forgery
|
|
|
29
27
|
end
|
|
30
28
|
|
|
31
29
|
def self.color
|
|
32
|
-
|
|
30
|
+
dictionaries[:colors].random
|
|
33
31
|
end
|
|
34
32
|
|
|
35
33
|
def self.hex_color
|
|
@@ -68,6 +66,6 @@ class BasicForgery < Forgery
|
|
|
68
66
|
end
|
|
69
67
|
|
|
70
68
|
def self.frequency
|
|
71
|
-
|
|
69
|
+
dictionaries[:frequencies].random
|
|
72
70
|
end
|
|
73
71
|
end
|
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
class InternetForgery < Forgery
|
|
2
|
-
dictionaries :male_first_names, :female_first_names, :last_names, :top_level_domains, :company_names
|
|
3
|
-
|
|
4
2
|
def self.user_name
|
|
5
|
-
(
|
|
3
|
+
(dictionaries[:male_first_names].random[0,1] + dictionaries[:last_names].random).downcase
|
|
6
4
|
end
|
|
7
5
|
|
|
8
6
|
def self.top_level_domain
|
|
9
|
-
|
|
7
|
+
dictionaries[:top_level_domains].random
|
|
10
8
|
end
|
|
11
9
|
|
|
12
10
|
def self.domain_name
|
|
13
|
-
|
|
11
|
+
dictionaries[:company_names].random.downcase + '.' + self.top_level_domain
|
|
14
12
|
end
|
|
15
13
|
|
|
16
14
|
def self.email_address
|
|
@@ -1,7 +1,4 @@
|
|
|
1
1
|
class LoremIpsumForgery < Forgery
|
|
2
|
-
dictionaries :lorem_ipsum
|
|
3
|
-
LOREM_IPSUM_WORDS = LOREM_IPSUM.join(" ").downcase.gsub(/\.|,|;/, '').split(" ")
|
|
4
|
-
LOREM_IPSUM_CHARACTERS = LOREM_IPSUM.join("").downcase.gsub(/[^a-z\s]/,'')
|
|
5
2
|
|
|
6
3
|
def self.text(what=:sentence, quantity=2, options={})
|
|
7
4
|
case what
|
|
@@ -30,9 +27,9 @@ class LoremIpsumForgery < Forgery
|
|
|
30
27
|
end
|
|
31
28
|
|
|
32
29
|
def self.characters(quantity=10, options={})
|
|
33
|
-
options.merge!(:random_limit =>
|
|
30
|
+
options.merge!(:random_limit => lorem_ipsum_characters.length-quantity) if quantity.is_a?(Fixnum)
|
|
34
31
|
|
|
35
|
-
|
|
32
|
+
lorem_ipsum_characters[range_from_quantity(quantity, options)]
|
|
36
33
|
end
|
|
37
34
|
|
|
38
35
|
def self.word(options={})
|
|
@@ -40,9 +37,9 @@ class LoremIpsumForgery < Forgery
|
|
|
40
37
|
end
|
|
41
38
|
|
|
42
39
|
def self.words(quantity=10, options={})
|
|
43
|
-
options.merge!(:random_limit =>
|
|
40
|
+
options.merge!(:random_limit => lorem_ipsum_words.length-quantity) if quantity.is_a?(Fixnum)
|
|
44
41
|
|
|
45
|
-
|
|
42
|
+
lorem_ipsum_words[range_from_quantity(quantity, options)].join(" ")
|
|
46
43
|
end
|
|
47
44
|
|
|
48
45
|
def self.sentence(options={})
|
|
@@ -50,9 +47,9 @@ class LoremIpsumForgery < Forgery
|
|
|
50
47
|
end
|
|
51
48
|
|
|
52
49
|
def self.sentences(quantity=2, options={})
|
|
53
|
-
options.merge!(:random_limit => (
|
|
50
|
+
options.merge!(:random_limit => (dictionaries[:lorem_ipsum].length-quantity)) if quantity.is_a?(Fixnum)
|
|
54
51
|
|
|
55
|
-
|
|
52
|
+
dictionaries[:lorem_ipsum][range_from_quantity(quantity, options)].join(" ")
|
|
56
53
|
end
|
|
57
54
|
|
|
58
55
|
def self.paragraph(options={})
|
|
@@ -66,7 +63,7 @@ class LoremIpsumForgery < Forgery
|
|
|
66
63
|
:end => "" },
|
|
67
64
|
:html => false,
|
|
68
65
|
:sentences => 3)
|
|
69
|
-
options.merge!(:random_limit => (
|
|
66
|
+
options.merge!(:random_limit => (dictionaries[:lorem_ipsum].length/options[:sentences])-quantity) if quantity.is_a?(Fixnum)
|
|
70
67
|
|
|
71
68
|
if options[:html]
|
|
72
69
|
options[:wrap] = { :start => "<p>",
|
|
@@ -81,7 +78,7 @@ class LoremIpsumForgery < Forgery
|
|
|
81
78
|
range.to_a.length.times do |i|
|
|
82
79
|
paragraphs << (
|
|
83
80
|
options[:wrap][:start] +
|
|
84
|
-
|
|
81
|
+
dictionaries[:lorem_ipsum][start..(start+options[:sentences]-1)].join(" ") +
|
|
85
82
|
options[:wrap][:end]
|
|
86
83
|
)
|
|
87
84
|
start += options[:sentences]
|
|
@@ -103,5 +100,13 @@ protected
|
|
|
103
100
|
0..(quantity-1)
|
|
104
101
|
end
|
|
105
102
|
end
|
|
106
|
-
|
|
103
|
+
|
|
104
|
+
def self.lorem_ipsum_words
|
|
105
|
+
@@lorem_ipsum_words ||= dictionaries[:lorem_ipsum].join(" ").downcase.gsub(/\.|,|;/, '').split(" ")
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def self.lorem_ipsum_characters
|
|
109
|
+
@@lorem_ipsum_characters ||= dictionaries[:lorem_ipsum].join("").downcase.gsub(/[^a-z\s]/,'')
|
|
110
|
+
end
|
|
111
|
+
|
|
107
112
|
end
|
|
@@ -1,13 +1,11 @@
|
|
|
1
1
|
class NameForgery < Forgery
|
|
2
|
-
dictionaries :last_names, :male_first_names, :female_first_names, :company_names,
|
|
3
|
-
:name_suffixes, :name_titles
|
|
4
2
|
|
|
5
3
|
def self.last_name
|
|
6
|
-
|
|
4
|
+
dictionaries[:last_names].random
|
|
7
5
|
end
|
|
8
6
|
|
|
9
7
|
def self.first_name
|
|
10
|
-
[
|
|
8
|
+
[dictionaries[:male_first_names], dictionaries[:female_first_names]].random.random
|
|
11
9
|
end
|
|
12
10
|
|
|
13
11
|
def self.full_name
|
|
@@ -15,22 +13,22 @@ class NameForgery < Forgery
|
|
|
15
13
|
end
|
|
16
14
|
|
|
17
15
|
def self.male_first_name
|
|
18
|
-
|
|
16
|
+
dictionaries[:male_first_names].random
|
|
19
17
|
end
|
|
20
18
|
|
|
21
19
|
def self.female_first_name
|
|
22
|
-
|
|
20
|
+
dictionaries[:female_first_names].random
|
|
23
21
|
end
|
|
24
22
|
|
|
25
23
|
def self.company_name
|
|
26
|
-
|
|
24
|
+
dictionaries[:company_names].random
|
|
27
25
|
end
|
|
28
26
|
|
|
29
27
|
def self.title
|
|
30
|
-
|
|
28
|
+
dictionaries[:name_titles].random
|
|
31
29
|
end
|
|
32
30
|
|
|
33
31
|
def self.suffix
|
|
34
|
-
|
|
32
|
+
dictionaries[:name_suffixes].random
|
|
35
33
|
end
|
|
36
34
|
end
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
class PersonalForgery < Forgery
|
|
2
|
-
dictionaries :races, :languages, :shirt_sizes, :genders
|
|
3
2
|
|
|
4
3
|
def self.gender
|
|
5
|
-
|
|
4
|
+
dictionaries[:genders].random
|
|
6
5
|
end
|
|
7
6
|
|
|
8
7
|
def self.abbreviated_gender
|
|
@@ -10,14 +9,14 @@ class PersonalForgery < Forgery
|
|
|
10
9
|
end
|
|
11
10
|
|
|
12
11
|
def self.shirt_size
|
|
13
|
-
|
|
12
|
+
dictionaries[:shirt_sizes].random
|
|
14
13
|
end
|
|
15
14
|
|
|
16
15
|
def self.race
|
|
17
|
-
|
|
16
|
+
dictionaries[:races].random
|
|
18
17
|
end
|
|
19
18
|
|
|
20
19
|
def self.language
|
|
21
|
-
|
|
20
|
+
dictionaries[:languages].random
|
|
22
21
|
end
|
|
23
22
|
end
|
data/lib/forgery.rb
CHANGED
|
@@ -1,73 +1,29 @@
|
|
|
1
|
-
# Require forgeries at the bottom of the file so Forgery works as a gem
|
|
1
|
+
# Require forgeries at the bottom of the file so Forgery works as a gem both
|
|
2
|
+
# within rails and outside of it.
|
|
2
3
|
|
|
4
|
+
# Loading forgery helpers.
|
|
5
|
+
require File.expand_path(File.dirname(__FILE__) + '/file_reader')
|
|
6
|
+
require File.expand_path(File.dirname(__FILE__) + '/dictionaries')
|
|
7
|
+
require File.expand_path(File.dirname(__FILE__) + '/formats')
|
|
8
|
+
|
|
9
|
+
# Loading class extensions
|
|
3
10
|
Dir[File.expand_path(File.dirname(__FILE__) + '/extensions/**/*.rb')].uniq.each do |file|
|
|
4
11
|
require file
|
|
5
12
|
end
|
|
6
13
|
|
|
7
14
|
class Forgery
|
|
8
|
-
def self.dictionaries(*dictionaries)
|
|
9
|
-
dictionaries.each do |dictionary|
|
|
10
|
-
const_set(dictionary.to_s.upcase, read_dictionary(dictionary))
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
def self.formats(*formats)
|
|
15
|
-
formats.each do |format|
|
|
16
|
-
const_set(format.to_s.upcase + "_FORMATS", read_format(format))
|
|
17
|
-
end
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
protected
|
|
21
|
-
|
|
22
|
-
def self.read_file(file)
|
|
23
|
-
lines = []
|
|
24
|
-
IO.foreach(file) do |line|
|
|
25
|
-
lines << line.chomp unless line.chomp == ''
|
|
26
|
-
end
|
|
27
|
-
lines
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
def self.read_dictionary(dictionary)
|
|
31
|
-
read_file(path_to_dictionary(dictionary))
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
def self.read_format(format)
|
|
35
|
-
read_file(path_to_format(format))
|
|
36
|
-
end
|
|
37
15
|
|
|
38
|
-
def self.
|
|
39
|
-
|
|
40
|
-
external_path_to_format(format)
|
|
41
|
-
else
|
|
42
|
-
internal_path_to_format(format)
|
|
43
|
-
end
|
|
16
|
+
def self.dictionaries
|
|
17
|
+
@@dictionaries ||= Dictionaries.new
|
|
44
18
|
end
|
|
45
19
|
|
|
46
|
-
def self.
|
|
47
|
-
|
|
20
|
+
def self.formats
|
|
21
|
+
@@formats ||= Formats.new
|
|
48
22
|
end
|
|
49
23
|
|
|
50
|
-
def self.internal_path_to_format(format)
|
|
51
|
-
File.dirname(__FILE__) + '/formats/' + format.to_s
|
|
52
|
-
end
|
|
53
|
-
|
|
54
|
-
def self.path_to_dictionary(dictionary)
|
|
55
|
-
if external_path_to_dictionary(dictionary) && File.exists?(external_path_to_dictionary(dictionary))
|
|
56
|
-
external_path_to_dictionary(dictionary)
|
|
57
|
-
else
|
|
58
|
-
internal_path_to_dictionary(dictionary)
|
|
59
|
-
end
|
|
60
|
-
end
|
|
61
|
-
|
|
62
|
-
def self.external_path_to_dictionary(dictionary)
|
|
63
|
-
RAILS_ROOT + '/lib/forgery/dictionaries/' + dictionary.to_s if defined?(RAILS_ROOT)
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
def self.internal_path_to_dictionary(dictionary)
|
|
67
|
-
File.dirname(__FILE__) + '/dictionaries/' + dictionary.to_s
|
|
68
|
-
end
|
|
69
24
|
end
|
|
70
25
|
|
|
26
|
+
# Alternate Forgery api, see spec/forgery_spec.rb for examples.
|
|
71
27
|
def Forgery(forgery, method=nil, *args)
|
|
72
28
|
klass = "#{forgery.to_s.camelize}Forgery".constantize
|
|
73
29
|
if method
|
|
@@ -77,6 +33,15 @@ def Forgery(forgery, method=nil, *args)
|
|
|
77
33
|
end
|
|
78
34
|
end
|
|
79
35
|
|
|
36
|
+
# Loading the other forgeries AFTER the initial Forgery class is defined.
|
|
80
37
|
Dir[File.expand_path(File.dirname(__FILE__) + '/forgeries/**/*.rb')].uniq.each do |file|
|
|
81
38
|
require file
|
|
82
39
|
end
|
|
40
|
+
|
|
41
|
+
# Loading rails forgeries to override current forgery methods and add new
|
|
42
|
+
# forgeries
|
|
43
|
+
if defined?(RAILS_ROOT)
|
|
44
|
+
Dir[File.expand_path(RAILS_ROOT + '/lib/forgery/**/*.rb')].uniq.each do |file|
|
|
45
|
+
require file
|
|
46
|
+
end
|
|
47
|
+
end
|
data/lib/formats.rb
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
class Formats
|
|
2
|
+
|
|
3
|
+
def initialize
|
|
4
|
+
@formats = {}
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def [](key)
|
|
8
|
+
symbolized_key = key.to_sym
|
|
9
|
+
if @formats.has_key?(symbolized_key)
|
|
10
|
+
@formats[symbolized_key]
|
|
11
|
+
else
|
|
12
|
+
@formats[symbolized_key] = FileReader.read_format(symbolized_key)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def loaded?(key)
|
|
17
|
+
@formats.has_key?(key.to_sym)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def reset!
|
|
21
|
+
@formats = {}
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Dictionaries do
|
|
4
|
+
it "should check if the dictionary is loaded" do
|
|
5
|
+
dictionaries = Dictionaries.new
|
|
6
|
+
|
|
7
|
+
dictionaries[:colors]
|
|
8
|
+
|
|
9
|
+
dictionaries.should be_loaded(:colors)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "should load a dictionary when called by the key" do
|
|
13
|
+
dictionaries = Dictionaries.new
|
|
14
|
+
|
|
15
|
+
dictionaries.reset!
|
|
16
|
+
|
|
17
|
+
dictionaries.should_not be_loaded(:colors)
|
|
18
|
+
|
|
19
|
+
dictionaries[:colors]
|
|
20
|
+
|
|
21
|
+
dictionaries.should be_loaded(:colors)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "should clear the loaded dictionaries when calling reset!" do
|
|
25
|
+
dictionaries = Dictionaries.new
|
|
26
|
+
|
|
27
|
+
dictionaries[:colors]
|
|
28
|
+
|
|
29
|
+
dictionaries.should be_loaded(:colors)
|
|
30
|
+
|
|
31
|
+
dictionaries.reset!
|
|
32
|
+
|
|
33
|
+
dictionaries.should_not be_loaded(:colors)
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe FileReader do
|
|
4
|
+
it "should return an array when calling read_dictionary" do
|
|
5
|
+
FileReader.read_dictionary(:colors).should be_is_a(Array)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
it "should return an array when calling read_format" do
|
|
9
|
+
FileReader.read_format(:phone).should be_is_a(Array)
|
|
10
|
+
end
|
|
11
|
+
end
|
|
@@ -2,16 +2,16 @@ require File.dirname(__FILE__) + '/../spec_helper'
|
|
|
2
2
|
|
|
3
3
|
describe AddressForgery do
|
|
4
4
|
it "should return a random street" do
|
|
5
|
-
|
|
5
|
+
Forgery.dictionaries[:streets].should include(AddressForgery.street_name)
|
|
6
6
|
end
|
|
7
7
|
|
|
8
8
|
it "should return a random street number" do
|
|
9
9
|
original_format = AddressForgery.street_number.gsub(/\d/, '#')
|
|
10
|
-
|
|
10
|
+
Forgery.formats[:street_number].should include(original_format)
|
|
11
11
|
end
|
|
12
12
|
|
|
13
13
|
it "should return a random street suffix" do
|
|
14
|
-
|
|
14
|
+
Forgery.dictionaries[:street_suffixes].should include(AddressForgery.street_suffix)
|
|
15
15
|
end
|
|
16
16
|
|
|
17
17
|
describe ".street_address" do
|
|
@@ -21,49 +21,49 @@ describe AddressForgery do
|
|
|
21
21
|
|
|
22
22
|
it "should return a random street suffix" do
|
|
23
23
|
street_suffix = @split_address.pop
|
|
24
|
-
|
|
24
|
+
Forgery.dictionaries[:street_suffixes].should include(street_suffix)
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
it "should return a random street number" do
|
|
28
28
|
street_number_format = @split_address.shift.gsub(/\d/, '#')
|
|
29
|
-
|
|
29
|
+
Forgery.formats[:street_number].should include(street_number_format)
|
|
30
30
|
end
|
|
31
31
|
|
|
32
32
|
it "should return a random street" do
|
|
33
33
|
@split_address.pop
|
|
34
34
|
@split_address.shift
|
|
35
35
|
street = @split_address.join(" ")
|
|
36
|
-
|
|
36
|
+
Forgery.dictionaries[:streets].should include(street)
|
|
37
37
|
end
|
|
38
38
|
end
|
|
39
39
|
|
|
40
40
|
it "should return a random city" do
|
|
41
41
|
city = AddressForgery.city
|
|
42
|
-
|
|
42
|
+
Forgery.dictionaries[:cities].should include(city)
|
|
43
43
|
end
|
|
44
44
|
|
|
45
45
|
it "should return a random state" do
|
|
46
46
|
state = AddressForgery.state
|
|
47
|
-
|
|
47
|
+
Forgery.dictionaries[:states].should include(state)
|
|
48
48
|
end
|
|
49
49
|
|
|
50
50
|
it "should return a random state abbreviation" do
|
|
51
51
|
state_abbrev = AddressForgery.state_abbrev
|
|
52
|
-
|
|
52
|
+
Forgery.dictionaries[:state_abbrevs].should include(state_abbrev)
|
|
53
53
|
end
|
|
54
54
|
|
|
55
55
|
it "should return a random country" do
|
|
56
56
|
country = AddressForgery.country
|
|
57
|
-
|
|
57
|
+
Forgery.dictionaries[:countries].should include(country)
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
it "should return a random zip code" do
|
|
61
61
|
zip_format = AddressForgery.zip.gsub(/\d/, '#')
|
|
62
|
-
|
|
62
|
+
Forgery.formats[:zip].should include(zip_format)
|
|
63
63
|
end
|
|
64
64
|
|
|
65
65
|
it "should return a random phone number" do
|
|
66
66
|
phone_format = AddressForgery.phone.gsub(/\d/, '#')
|
|
67
|
-
|
|
67
|
+
Forgery.formats[:phone].should include(phone_format)
|
|
68
68
|
end
|
|
69
69
|
end
|
|
@@ -8,23 +8,23 @@ describe InternetForgery do
|
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
it "should return a top level domain" do
|
|
11
|
-
|
|
11
|
+
Forgery.dictionaries[:top_level_domains].should include(InternetForgery.top_level_domain)
|
|
12
12
|
end
|
|
13
13
|
|
|
14
14
|
describe ".domain_name" do
|
|
15
15
|
it "should return a domain name that contains a lowercase company name" do
|
|
16
16
|
downcase_company_name = InternetForgery.domain_name.split('.').first
|
|
17
|
-
|
|
17
|
+
Forgery.dictionaries[:company_names].any?{ |cn| cn =~ /#{downcase_company_name}/i }
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
it "should return a domain name that contains a top level domain" do
|
|
21
|
-
|
|
21
|
+
Forgery.dictionaries[:top_level_domains].should include(InternetForgery.domain_name.split('.').last)
|
|
22
22
|
end
|
|
23
23
|
end
|
|
24
24
|
|
|
25
25
|
describe ".email_address" do
|
|
26
26
|
it "should match the email format" do
|
|
27
|
-
InternetForgery.email_address.should match(/.+@.+\.(#{
|
|
27
|
+
InternetForgery.email_address.should match(/.+@.+\.(#{Forgery.dictionaries[:top_level_domains].join("|")})/)
|
|
28
28
|
end
|
|
29
29
|
end
|
|
30
30
|
end
|
|
@@ -3,13 +3,13 @@ require File.dirname(__FILE__) + '/../spec_helper'
|
|
|
3
3
|
describe PersonalForgery do
|
|
4
4
|
describe '.gender' do
|
|
5
5
|
it 'should return male or female' do
|
|
6
|
-
|
|
6
|
+
Forgery.dictionaries[:genders].should include(PersonalForgery.gender)
|
|
7
7
|
end
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
describe '.shirt_size' do
|
|
11
11
|
it 'should return a sane size' do
|
|
12
|
-
|
|
12
|
+
Forgery.dictionaries[:shirt_sizes].should include(PersonalForgery.shirt_size)
|
|
13
13
|
end
|
|
14
14
|
end
|
|
15
15
|
end
|
data/spec/forgery_spec.rb
CHANGED
|
@@ -1,18 +1,24 @@
|
|
|
1
1
|
require File.dirname(__FILE__) + '/spec_helper'
|
|
2
2
|
|
|
3
3
|
describe Forgery do
|
|
4
|
-
it "should
|
|
5
|
-
Forgery.dictionaries
|
|
6
|
-
|
|
7
|
-
Forgery
|
|
8
|
-
|
|
4
|
+
it "should load a dictionary when it is requested" do
|
|
5
|
+
Forgery.dictionaries.reset!
|
|
6
|
+
|
|
7
|
+
Forgery.dictionaries.should_not be_loaded(:colors)
|
|
8
|
+
|
|
9
|
+
Forgery.dictionaries[:colors]
|
|
10
|
+
|
|
11
|
+
Forgery.dictionaries.should be_loaded(:colors)
|
|
9
12
|
end
|
|
10
13
|
|
|
11
|
-
it "should
|
|
12
|
-
Forgery.formats
|
|
13
|
-
|
|
14
|
-
Forgery
|
|
15
|
-
|
|
14
|
+
it "should load formats when it is requested" do
|
|
15
|
+
Forgery.formats.reset!
|
|
16
|
+
|
|
17
|
+
Forgery.formats.should_not be_loaded(:phone)
|
|
18
|
+
|
|
19
|
+
Forgery.formats[:phone]
|
|
20
|
+
|
|
21
|
+
Forgery.formats.should be_loaded(:phone)
|
|
16
22
|
end
|
|
17
23
|
|
|
18
24
|
it "should accept a symbol and return the appropriate forgery class" do
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
require File.dirname(__FILE__) + '/spec_helper'
|
|
2
|
+
|
|
3
|
+
describe Formats do
|
|
4
|
+
it "should check if the dictionary is loaded" do
|
|
5
|
+
formats = Formats.new
|
|
6
|
+
|
|
7
|
+
formats[:phone]
|
|
8
|
+
|
|
9
|
+
formats.should be_loaded(:phone)
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
it "should load a dictionary when called by the key" do
|
|
13
|
+
formats = Formats.new
|
|
14
|
+
|
|
15
|
+
formats.reset!
|
|
16
|
+
|
|
17
|
+
formats.should_not be_loaded(:phone)
|
|
18
|
+
|
|
19
|
+
formats[:phone]
|
|
20
|
+
|
|
21
|
+
formats.should be_loaded(:phone)
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
it "should clear the loaded formats when calling reset!" do
|
|
25
|
+
formats = Formats.new
|
|
26
|
+
|
|
27
|
+
formats[:phone]
|
|
28
|
+
|
|
29
|
+
formats.should be_loaded(:phone)
|
|
30
|
+
|
|
31
|
+
formats.reset!
|
|
32
|
+
|
|
33
|
+
formats.should_not be_loaded(:phone)
|
|
34
|
+
end
|
|
35
|
+
end
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: sevenwire-forgery
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Nathan Sutton
|
|
@@ -9,7 +9,7 @@ autorequire:
|
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
11
|
|
|
12
|
-
date: 2008-11-
|
|
12
|
+
date: 2008-11-30 00:00:00 -08:00
|
|
13
13
|
default_executable:
|
|
14
14
|
dependencies: []
|
|
15
15
|
|
|
@@ -48,11 +48,13 @@ files:
|
|
|
48
48
|
- lib/dictionaries/street_suffixes
|
|
49
49
|
- lib/dictionaries/streets
|
|
50
50
|
- lib/dictionaries/top_level_domains
|
|
51
|
+
- lib/dictionaries.rb
|
|
51
52
|
- lib/extensions
|
|
52
53
|
- lib/extensions/array.rb
|
|
53
54
|
- lib/extensions/hash.rb
|
|
54
55
|
- lib/extensions/range.rb
|
|
55
56
|
- lib/extensions/string.rb
|
|
57
|
+
- lib/file_reader.rb
|
|
56
58
|
- lib/forgeries
|
|
57
59
|
- lib/forgeries/address_forgery.rb
|
|
58
60
|
- lib/forgeries/basic_forgery.rb
|
|
@@ -66,10 +68,13 @@ files:
|
|
|
66
68
|
- lib/formats/phone
|
|
67
69
|
- lib/formats/street_number
|
|
68
70
|
- lib/formats/zip
|
|
71
|
+
- lib/formats.rb
|
|
72
|
+
- spec/dictionaries_spec.rb
|
|
69
73
|
- spec/extensions
|
|
70
74
|
- spec/extensions/array_spec.rb
|
|
71
75
|
- spec/extensions/range_spec.rb
|
|
72
76
|
- spec/extensions/string_spec.rb
|
|
77
|
+
- spec/file_reader_spec.rb
|
|
73
78
|
- spec/forgeries
|
|
74
79
|
- spec/forgeries/address_forgery_spec.rb
|
|
75
80
|
- spec/forgeries/basic_forgery_spec.rb
|
|
@@ -79,6 +84,7 @@ files:
|
|
|
79
84
|
- spec/forgeries/name_forgery_spec.rb
|
|
80
85
|
- spec/forgeries/personal_forgery_spec.rb
|
|
81
86
|
- spec/forgery_spec.rb
|
|
87
|
+
- spec/formats_spec.rb
|
|
82
88
|
- spec/spec_helper.rb
|
|
83
89
|
has_rdoc: false
|
|
84
90
|
homepage: http://github.com/sevenwire/forgery
|