forgery 0.2.2

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.
Files changed (60) hide show
  1. data/README.markdown +99 -0
  2. data/VERSION.yml +4 -0
  3. data/generators/forgery/USAGE +6 -0
  4. data/generators/forgery/forgery_generator.rb +12 -0
  5. data/lib/dictionaries.rb +24 -0
  6. data/lib/dictionaries/cities +478 -0
  7. data/lib/dictionaries/colors +19 -0
  8. data/lib/dictionaries/company_names +400 -0
  9. data/lib/dictionaries/countries +249 -0
  10. data/lib/dictionaries/female_first_names +100 -0
  11. data/lib/dictionaries/frequencies +8 -0
  12. data/lib/dictionaries/genders +2 -0
  13. data/lib/dictionaries/languages +97 -0
  14. data/lib/dictionaries/last_names +250 -0
  15. data/lib/dictionaries/lorem_ipsum +151 -0
  16. data/lib/dictionaries/male_first_names +100 -0
  17. data/lib/dictionaries/name_suffixes +5 -0
  18. data/lib/dictionaries/name_titles +6 -0
  19. data/lib/dictionaries/province_abbrevs +13 -0
  20. data/lib/dictionaries/provinces +13 -0
  21. data/lib/dictionaries/races +93 -0
  22. data/lib/dictionaries/shirt_sizes +7 -0
  23. data/lib/dictionaries/state_abbrevs +50 -0
  24. data/lib/dictionaries/states +50 -0
  25. data/lib/dictionaries/street_suffixes +21 -0
  26. data/lib/dictionaries/streets +500 -0
  27. data/lib/dictionaries/top_level_domains +9 -0
  28. data/lib/extensions/array.rb +11 -0
  29. data/lib/extensions/hash.rb +12 -0
  30. data/lib/extensions/range.rb +9 -0
  31. data/lib/extensions/string.rb +48 -0
  32. data/lib/file_reader.rb +53 -0
  33. data/lib/forgeries/address_forgery.rb +136 -0
  34. data/lib/forgeries/basic_forgery.rb +71 -0
  35. data/lib/forgeries/internet_forgery.rb +17 -0
  36. data/lib/forgeries/lorem_ipsum_forgery.rb +112 -0
  37. data/lib/forgeries/monetary_forgery.rb +13 -0
  38. data/lib/forgeries/name_forgery.rb +34 -0
  39. data/lib/forgeries/personal_forgery.rb +22 -0
  40. data/lib/forgery.rb +47 -0
  41. data/lib/formats.rb +24 -0
  42. data/lib/formats/phone +1 -0
  43. data/lib/formats/street_number +5 -0
  44. data/lib/formats/zip +2 -0
  45. data/spec/dictionaries_spec.rb +35 -0
  46. data/spec/extensions/array_spec.rb +25 -0
  47. data/spec/extensions/range_spec.rb +26 -0
  48. data/spec/extensions/string_spec.rb +29 -0
  49. data/spec/file_reader_spec.rb +11 -0
  50. data/spec/forgeries/address_forgery_spec.rb +79 -0
  51. data/spec/forgeries/basic_forgery_spec.rb +175 -0
  52. data/spec/forgeries/internet_forgery_spec.rb +30 -0
  53. data/spec/forgeries/lorem_ipsum_forgery_spec.rb +128 -0
  54. data/spec/forgeries/monetary_forgery_spec.rb +4 -0
  55. data/spec/forgeries/name_forgery_spec.rb +4 -0
  56. data/spec/forgeries/personal_forgery_spec.rb +15 -0
  57. data/spec/forgery_spec.rb +42 -0
  58. data/spec/formats_spec.rb +35 -0
  59. data/spec/spec_helper.rb +32 -0
  60. metadata +114 -0
@@ -0,0 +1,13 @@
1
+ class MonetaryForgery < Forgery
2
+ def self.formatted_money(options={})
3
+ "$%1.2f" % money(options)
4
+ end
5
+
6
+ def self.money(options={})
7
+ options = {:max => 10,
8
+ :min => 0}.merge(options)
9
+
10
+ value = ((options[:min] * 100)..(options[:max] * 100)).random
11
+ "%1.2f" % (value.to_f / 100)
12
+ end
13
+ end
@@ -0,0 +1,34 @@
1
+ class NameForgery < Forgery
2
+
3
+ def self.last_name
4
+ dictionaries[:last_names].random
5
+ end
6
+
7
+ def self.first_name
8
+ [dictionaries[:male_first_names], dictionaries[:female_first_names]].random.random
9
+ end
10
+
11
+ def self.full_name
12
+ "#{self.first_name} #{self.last_name}"
13
+ end
14
+
15
+ def self.male_first_name
16
+ dictionaries[:male_first_names].random
17
+ end
18
+
19
+ def self.female_first_name
20
+ dictionaries[:female_first_names].random
21
+ end
22
+
23
+ def self.company_name
24
+ dictionaries[:company_names].random
25
+ end
26
+
27
+ def self.title
28
+ dictionaries[:name_titles].random
29
+ end
30
+
31
+ def self.suffix
32
+ dictionaries[:name_suffixes].random
33
+ end
34
+ end
@@ -0,0 +1,22 @@
1
+ class PersonalForgery < Forgery
2
+
3
+ def self.gender
4
+ dictionaries[:genders].random
5
+ end
6
+
7
+ def self.abbreviated_gender
8
+ gender[0,1]
9
+ end
10
+
11
+ def self.shirt_size
12
+ dictionaries[:shirt_sizes].random
13
+ end
14
+
15
+ def self.race
16
+ dictionaries[:races].random
17
+ end
18
+
19
+ def self.language
20
+ dictionaries[:languages].random
21
+ end
22
+ end
@@ -0,0 +1,47 @@
1
+ # Require forgeries at the bottom of the file so Forgery works as a gem both
2
+ # within rails and outside of it.
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
10
+ Dir[File.expand_path(File.dirname(__FILE__) + '/extensions/**/*.rb')].uniq.each do |file|
11
+ require file
12
+ end
13
+
14
+ class Forgery
15
+
16
+ def self.dictionaries
17
+ @@dictionaries ||= Dictionaries.new
18
+ end
19
+
20
+ def self.formats
21
+ @@formats ||= Formats.new
22
+ end
23
+
24
+ end
25
+
26
+ # Alternate Forgery api, see spec/forgery_spec.rb for examples.
27
+ def Forgery(forgery, method=nil, *args)
28
+ klass = "#{forgery.to_s.camelize}Forgery".constantize
29
+ if method
30
+ klass.send(method, *args)
31
+ else
32
+ klass
33
+ end
34
+ end
35
+
36
+ # Loading the other forgeries AFTER the initial Forgery class is defined.
37
+ Dir[File.expand_path(File.dirname(__FILE__) + '/forgeries/**/*.rb')].uniq.each do |file|
38
+ require file
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
@@ -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 @@
1
+ #-(###)###-####
@@ -0,0 +1,5 @@
1
+ #
2
+ ##
3
+ ###
4
+ ####
5
+ #####
@@ -0,0 +1,2 @@
1
+ #####
2
+ #####-####
@@ -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,25 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Array do
4
+ before do
5
+ @array = [0,1,2,3,4,5,6,7,8,9]
6
+ end
7
+
8
+ it "should get a random item out of the array" do
9
+ 10.times { @array.should include(@array.random) }
10
+ end
11
+
12
+ it "should return nil if the array is empty" do
13
+ [].random.should be_nil
14
+ end
15
+
16
+ it "should return a random subset of the array" do
17
+ @array.random_subset(5).each do |i|
18
+ @array.should include(i)
19
+ end
20
+ end
21
+
22
+ it "should return a random subset of the array that is 3 long" do
23
+ @array.random_subset(3).size.should == 3
24
+ end
25
+ end
@@ -0,0 +1,26 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+ require 'timeout'
3
+
4
+ describe Range do
5
+ it "should get a random number out of the range" do
6
+ range = (0..9)
7
+ 10.times { range.should include(range.random) }
8
+ end
9
+
10
+ it "should not take a long time when the range is huge" do
11
+ Timeout.timeout(1){(1234567890..12345678901234567890).random}.should_not raise_error(Timeout::Error)
12
+ end
13
+
14
+ it "should return nil for a random number from a reverse range" do
15
+ 10.times { (9..0).random.should be_nil }
16
+ end
17
+
18
+ it "should get a random string our of the range" do
19
+ range = ("a".."z")
20
+ 10.times { range.should include(range.random) }
21
+ end
22
+
23
+ it "should return nil if the maximum is less than the minimum" do
24
+ ("z".."a").random.should be_nil
25
+ end
26
+ end
@@ -0,0 +1,29 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe String do
4
+ it "should change a single # to a number 0-9" do
5
+ (0..9).should include(Integer("#".to_numbers))
6
+ end
7
+
8
+ it "should change two #'s to two numbers 0-9" do
9
+ "##".to_numbers.split("").each do |s|
10
+ (0..9).should include(Integer(s))
11
+ end
12
+ end
13
+
14
+ it "should only replace #'s in the string with numbers 0-9" do
15
+ s = '###-###-####'
16
+ n = s.to_numbers
17
+ 0.upto(s.size - 1) do |i|
18
+ if s[i, 1] == "#"
19
+ ('0'..'9').should include(n[i, 1])
20
+ else
21
+ ('0'..'9').should_not include(n[i, 1])
22
+ end
23
+ end
24
+ end
25
+
26
+ it "should allow the replacing of a different character" do
27
+ (0..9).should include(Integer("-".to_numbers("-")))
28
+ end
29
+ 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
@@ -0,0 +1,79 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe AddressForgery do
4
+ it "should return a random street" do
5
+ Forgery.dictionaries[:streets].should include(AddressForgery.street_name)
6
+ end
7
+
8
+ it "should return a random street number" do
9
+ original_format = AddressForgery.street_number.gsub(/\d/, '#')
10
+ Forgery.formats[:street_number].should include(original_format)
11
+ end
12
+
13
+ it "should return a random street suffix" do
14
+ Forgery.dictionaries[:street_suffixes].should include(AddressForgery.street_suffix)
15
+ end
16
+
17
+ describe ".street_address" do
18
+ before do
19
+ @split_address = AddressForgery.street_address.split
20
+ end
21
+
22
+ it "should return a random street suffix" do
23
+ street_suffix = @split_address.pop
24
+ Forgery.dictionaries[:street_suffixes].should include(street_suffix)
25
+ end
26
+
27
+ it "should return a random street number" do
28
+ street_number_format = @split_address.shift.gsub(/\d/, '#')
29
+ Forgery.formats[:street_number].should include(street_number_format)
30
+ end
31
+
32
+ it "should return a random street" do
33
+ @split_address.pop
34
+ @split_address.shift
35
+ street = @split_address.join(" ")
36
+ Forgery.dictionaries[:streets].should include(street)
37
+ end
38
+ end
39
+
40
+ it "should return a random city" do
41
+ city = AddressForgery.city
42
+ Forgery.dictionaries[:cities].should include(city)
43
+ end
44
+
45
+ it "should return a random state" do
46
+ state = AddressForgery.state
47
+ Forgery.dictionaries[:states].should include(state)
48
+ end
49
+
50
+ it "should return a random state abbreviation" do
51
+ state_abbrev = AddressForgery.state_abbrev
52
+ Forgery.dictionaries[:state_abbrevs].should include(state_abbrev)
53
+ end
54
+
55
+ it "should return a random Canadian province or territory" do
56
+ province = AddressForgery.province
57
+ Forgery.dictionaries[:provinces].should include(province)
58
+ end
59
+
60
+ it "should return a random Canadian province or territory abbreviation" do
61
+ province_abbrev = AddressForgery.province_abbrev
62
+ Forgery.dictionaries[:province_abbrevs].should include(province_abbrev)
63
+ end
64
+
65
+ it "should return a random country" do
66
+ country = AddressForgery.country
67
+ Forgery.dictionaries[:countries].should include(country)
68
+ end
69
+
70
+ it "should return a random zip code" do
71
+ zip_format = AddressForgery.zip.gsub(/\d/, '#')
72
+ Forgery.formats[:zip].should include(zip_format)
73
+ end
74
+
75
+ it "should return a random phone number" do
76
+ phone_format = AddressForgery.phone.gsub(/\d/, '#')
77
+ Forgery.formats[:phone].should include(phone_format)
78
+ end
79
+ end
@@ -0,0 +1,175 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe BasicForgery do
4
+ describe ".password" do
5
+ it "should only uppercase characters" do
6
+ BasicForgery.password(:allow_lower => false,
7
+ :allow_upper => true,
8
+ :allow_numeric => false,
9
+ :allow_special => false).should only_contain(BasicForgery::UPPER_ALPHA)
10
+ end
11
+
12
+ it "should only contain lowercase characters" do
13
+ BasicForgery.password(:allow_lower => true,
14
+ :allow_upper => false,
15
+ :allow_numeric => false,
16
+ :allow_special => false).should only_contain(BasicForgery::LOWER_ALPHA)
17
+ end
18
+
19
+ it "should only contain numeric characters" do
20
+ BasicForgery.password(:allow_lower => false,
21
+ :allow_upper => false,
22
+ :allow_numeric => true,
23
+ :allow_special => false).should only_contain(BasicForgery::NUMERIC)
24
+ end
25
+
26
+ it "should only contain special characters" do
27
+ BasicForgery.password(:allow_lower => false,
28
+ :allow_upper => false,
29
+ :allow_numeric => false,
30
+ :allow_special => true).should only_contain(BasicForgery::SPECIAL_CHARACTERS)
31
+ end
32
+
33
+ it "should only contain lower and uppercase characters" do
34
+ BasicForgery.password(:allow_lower => true,
35
+ :allow_upper => true,
36
+ :allow_numeric => false,
37
+ :allow_special => false).should only_contain(BasicForgery::LOWER_ALPHA,
38
+ BasicForgery::UPPER_ALPHA)
39
+ end
40
+
41
+ it "should only contain numeric and special characters" do
42
+ BasicForgery.password(:allow_lower => false,
43
+ :allow_upper => false,
44
+ :allow_numeric => true,
45
+ :allow_special => true).should only_contain(BasicForgery::NUMERIC,
46
+ BasicForgery::SPECIAL_CHARACTERS)
47
+ end
48
+
49
+ it "should contain any of the defined characters" do
50
+ BasicForgery.password(:allow_lower => true,
51
+ :allow_upper => true,
52
+ :allow_numeric => true,
53
+ :allow_special => true).should only_contain(BasicForgery::NUMERIC,
54
+ BasicForgery::SPECIAL_CHARACTERS,
55
+ BasicForgery::LOWER_ALPHA,
56
+ BasicForgery::UPPER_ALPHA)
57
+ end
58
+ end
59
+
60
+ describe ".encrypt" do
61
+ it "should encrypt to hex digits" do
62
+ BasicForgery.encrypt("something").should only_contain(BasicForgery::HEX_DIGITS)
63
+ end
64
+
65
+ it "should encrypt different words to different output" do
66
+ BasicForgery.encrypt("foo").should_not == BasicForgery.encrypt("bar")
67
+ end
68
+
69
+ it "should allow a salt that changes the output" do
70
+ BasicForgery.encrypt("foo", "baz").should_not == BasicForgery.encrypt("foo", "bar")
71
+ end
72
+
73
+ it "should have the same output when encrypting twice" do
74
+ BasicForgery.encrypt("foo", "bar").should == BasicForgery.encrypt("foo", "bar")
75
+ end
76
+ end
77
+
78
+ describe ".boolean" do
79
+ it "should return true or false" do
80
+ [true, false].should include(BasicForgery.boolean)
81
+ end
82
+ end
83
+
84
+ describe ".color" do
85
+ it "should return a random color" do
86
+ Forgery.dictionaries[:colors].should include(BasicForgery.color)
87
+ end
88
+ end
89
+
90
+ describe ".hex_color" do
91
+ it "should return a 6-character hex color" do
92
+ BasicForgery.hex_color.should match(/#(#{BasicForgery::HEX_DIGITS.join('|')}){6}/)
93
+ end
94
+ end
95
+
96
+ describe ".short_hex_color" do
97
+ it "should return a 3-character hex color" do
98
+ BasicForgery.short_hex_color.should match(/#(#{BasicForgery::HEX_DIGITS.join('|')}){3}/)
99
+ end
100
+ end
101
+
102
+ describe ".number" do
103
+ it "should return a number >= the at_least option" do
104
+ BasicForgery.number(:at_least => 2).should >= 2
105
+ end
106
+
107
+ it "should return a number <= the at_most option" do
108
+ BasicForgery.number(:at_most => 12).should <= 12
109
+ end
110
+ end
111
+
112
+ describe ".text" do
113
+ it "should return text whose length is >= the at_least option" do
114
+ BasicForgery.text(:at_least => 5).size.should >= 5
115
+ end
116
+
117
+ it "should return text whose length is <= the at_most option" do
118
+ BasicForgery.text(:at_least => 15).size.should <= 15
119
+ end
120
+
121
+ it "should only uppercase characters" do
122
+ BasicForgery.text(:allow_lower => false,
123
+ :allow_upper => true,
124
+ :allow_numeric => false,
125
+ :allow_special => false).should only_contain(BasicForgery::UPPER_ALPHA)
126
+ end
127
+
128
+ it "should only contain lowercase characters" do
129
+ BasicForgery.text(:allow_lower => true,
130
+ :allow_upper => false,
131
+ :allow_numeric => false,
132
+ :allow_special => false).should only_contain(BasicForgery::LOWER_ALPHA)
133
+ end
134
+
135
+ it "should only contain numeric characters" do
136
+ BasicForgery.text(:allow_lower => false,
137
+ :allow_upper => false,
138
+ :allow_numeric => true,
139
+ :allow_special => false).should only_contain(BasicForgery::NUMERIC)
140
+ end
141
+
142
+ it "should only contain special characters" do
143
+ BasicForgery.text(:allow_lower => false,
144
+ :allow_upper => false,
145
+ :allow_numeric => false,
146
+ :allow_special => true).should only_contain(BasicForgery::SPECIAL_CHARACTERS)
147
+ end
148
+
149
+ it "should only contain lower and uppercase characters" do
150
+ BasicForgery.text(:allow_lower => true,
151
+ :allow_upper => true,
152
+ :allow_numeric => false,
153
+ :allow_special => false).should only_contain(BasicForgery::LOWER_ALPHA,
154
+ BasicForgery::UPPER_ALPHA)
155
+ end
156
+
157
+ it "should only contain numeric and special characters" do
158
+ BasicForgery.text(:allow_lower => false,
159
+ :allow_upper => false,
160
+ :allow_numeric => true,
161
+ :allow_special => true).should only_contain(BasicForgery::NUMERIC,
162
+ BasicForgery::SPECIAL_CHARACTERS)
163
+ end
164
+
165
+ it "should contain any of the defined characters" do
166
+ BasicForgery.text(:allow_lower => true,
167
+ :allow_upper => true,
168
+ :allow_numeric => true,
169
+ :allow_special => true).should only_contain(BasicForgery::NUMERIC,
170
+ BasicForgery::SPECIAL_CHARACTERS,
171
+ BasicForgery::LOWER_ALPHA,
172
+ BasicForgery::UPPER_ALPHA)
173
+ end
174
+ end
175
+ end