sevenwire-forgery 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. data/README.markdown +81 -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/cities +478 -0
  6. data/lib/dictionaries/colors +19 -0
  7. data/lib/dictionaries/company_names +400 -0
  8. data/lib/dictionaries/countries +249 -0
  9. data/lib/dictionaries/female_first_names +100 -0
  10. data/lib/dictionaries/frequencies +8 -0
  11. data/lib/dictionaries/genders +2 -0
  12. data/lib/dictionaries/languages +97 -0
  13. data/lib/dictionaries/last_names +250 -0
  14. data/lib/dictionaries/lorem_ipsum +151 -0
  15. data/lib/dictionaries/male_first_names +100 -0
  16. data/lib/dictionaries/name_suffixes +5 -0
  17. data/lib/dictionaries/name_titles +6 -0
  18. data/lib/dictionaries/races +93 -0
  19. data/lib/dictionaries/shirt_sizes +7 -0
  20. data/lib/dictionaries/state_abbrevs +50 -0
  21. data/lib/dictionaries/states +50 -0
  22. data/lib/dictionaries/street_suffixes +21 -0
  23. data/lib/dictionaries/streets +500 -0
  24. data/lib/dictionaries/top_level_domains +9 -0
  25. data/lib/extensions/array.rb +11 -0
  26. data/lib/extensions/hash.rb +12 -0
  27. data/lib/extensions/range.rb +9 -0
  28. data/lib/extensions/string.rb +48 -0
  29. data/lib/forgeries/address_forgery.rb +117 -0
  30. data/lib/forgeries/basic_forgery.rb +73 -0
  31. data/lib/forgeries/internet_forgery.rb +19 -0
  32. data/lib/forgeries/lorem_ipsum_forgery.rb +107 -0
  33. data/lib/forgeries/monetary_forgery.rb +13 -0
  34. data/lib/forgeries/name_forgery.rb +36 -0
  35. data/lib/forgeries/personal_forgery.rb +23 -0
  36. data/lib/forgery.rb +82 -0
  37. data/lib/formats/phone +1 -0
  38. data/lib/formats/street_number +5 -0
  39. data/lib/formats/zip +2 -0
  40. data/spec/extensions/array_spec.rb +25 -0
  41. data/spec/extensions/range_spec.rb +17 -0
  42. data/spec/extensions/string_spec.rb +29 -0
  43. data/spec/forgeries/address_forgery_spec.rb +69 -0
  44. data/spec/forgeries/basic_forgery_spec.rb +175 -0
  45. data/spec/forgeries/internet_forgery_spec.rb +30 -0
  46. data/spec/forgeries/lorem_ipsum_forgery_spec.rb +128 -0
  47. data/spec/forgeries/monetary_forgery_spec.rb +4 -0
  48. data/spec/forgeries/name_forgery_spec.rb +4 -0
  49. data/spec/forgeries/personal_forgery_spec.rb +15 -0
  50. data/spec/forgery_spec.rb +36 -0
  51. data/spec/spec_helper.rb +31 -0
  52. metadata +110 -0
@@ -0,0 +1,117 @@
1
+ # Generates random address information.
2
+ class AddressForgery < Forgery
3
+ dictionaries :streets, :street_suffixes, :cities, :states, :state_abbrevs, :countries
4
+ formats :zip, :phone, :street_number
5
+
6
+ # Gets a random street name out of the 'streets' dictionary.
7
+ #
8
+ # AddressForgery.street_name
9
+ # # => "Atwood"
10
+ #
11
+ # AddressForgery.street_name
12
+ # # => "Fordem"
13
+ def self.street_name
14
+ STREETS.random
15
+ end
16
+
17
+ # Gets one of the formats from 'street_number_formats' and converts it to
18
+ # numbers.
19
+ #
20
+ # AddressForgery.street_number
21
+ # # => 1
22
+ #
23
+ # AddressForgery.street_number
24
+ # # => 1234
25
+ def self.street_number
26
+ STREET_NUMBER_FORMATS.random.to_numbers
27
+ end
28
+
29
+ # Gets a random street suffix out of the 'street_suffixes' dictionary.
30
+ #
31
+ # AddressForgery.street_suffix
32
+ # # => "Street"
33
+ #
34
+ # AddressForgery.street_suffix
35
+ # # => "Parkway"
36
+ def self.street_suffix
37
+ STREET_SUFFIXES.random
38
+ end
39
+
40
+ # Gets a full street address, including street number, street name, and
41
+ # street suffix.
42
+ #
43
+ # AddressForgery.street_address
44
+ # # => "92 West Circle"
45
+ #
46
+ # AddressForgery.street_address
47
+ # # => "93265 Harper Lane"
48
+ def self.street_address
49
+ "#{street_number} #{street_name} #{street_suffix}"
50
+ end
51
+
52
+ # Gets a random city out of the 'cities' dictionary.
53
+ #
54
+ # AddressForgery.city
55
+ # # => "Anaheim"
56
+ #
57
+ # AddressForgery.city
58
+ # # => "Sacramento"
59
+ def self.city
60
+ CITIES.random
61
+ end
62
+
63
+ # Gets a random state out of the 'states' dictionary.
64
+ #
65
+ # AddressForgery.state
66
+ # # => "Mississippi"
67
+ #
68
+ # AddressForgery.state
69
+ # # => "Minnesota"
70
+ def self.state
71
+ STATES.random
72
+ end
73
+
74
+ # Gets a random state abbreviation out of the 'state_abbrev' dictionary.
75
+ #
76
+ # AddressForgery.state_abbrev
77
+ # # => "GA"
78
+ #
79
+ # AddressForgery.state_abbrev
80
+ # # => "TX"
81
+ def self.state_abbrev
82
+ STATE_ABBREVS.random
83
+ end
84
+
85
+ # Gets one of the formats from 'zip_formats' and converts it to numbers.
86
+ #
87
+ # AddressForgery.zip
88
+ # # => "52474"
89
+ #
90
+ # AddressForgery.zip
91
+ # # => "66702-4349"
92
+ def self.zip
93
+ ZIP_FORMATS.random.to_numbers
94
+ end
95
+
96
+ # Gets one of the formats from 'phone_formats' and converts it to numbers.
97
+ #
98
+ # AddressForgery.phone
99
+ # # => "1-(416)185-8799"
100
+ #
101
+ # AddressForgery.phone
102
+ # # => "1-(589)248-0418"
103
+ def self.phone
104
+ PHONE_FORMATS.random.to_numbers
105
+ end
106
+
107
+ # Gets a random country out of the 'countries' dictionary.
108
+ #
109
+ # AddressForgery.country
110
+ # # => "Uruguay"
111
+ #
112
+ # AddressForgery.country
113
+ # # => "Romania"
114
+ def self.country
115
+ COUNTRIES.random
116
+ end
117
+ end
@@ -0,0 +1,73 @@
1
+ require 'digest/sha1'
2
+
3
+ class BasicForgery < Forgery
4
+ dictionaries :colors, :frequencies
5
+
6
+ HEX_DIGITS = %w{0 1 2 3 4 5 6 7 8 9 a b c d e f}
7
+ UPPER_ALPHA = ('A'..'Z').to_a
8
+ LOWER_ALPHA = ('a'..'z').to_a
9
+ NUMERIC = ('0'..'9').to_a
10
+ SPECIAL_CHARACTERS = %w{! ' @ # $ % ^ & * ( ) _ + - = [ ] { } ; : " , . / ?}
11
+ BOOLEAN = [true, false]
12
+
13
+ def self.password(options={})
14
+ options = {:at_least => 6,
15
+ :at_most => 12,
16
+ :allow_lower => true,
17
+ :allow_upper => true,
18
+ :allow_numeric => true,
19
+ :allow_special => false}.merge!(options)
20
+ self.text(options)
21
+ end
22
+
23
+ def self.encrypt(password="password", salt=Time.now.to_s)
24
+ Digest::SHA1.hexdigest("--#{salt}--#{password}--")
25
+ end
26
+
27
+ def self.boolean
28
+ BOOLEAN.random
29
+ end
30
+
31
+ def self.color
32
+ COLORS.random
33
+ end
34
+
35
+ def self.hex_color
36
+ hex_digits = (1..6).collect { HEX_DIGITS.random}
37
+ "##{hex_digits.join}"
38
+ end
39
+
40
+ def self.short_hex_color
41
+ hex_color[0,4]
42
+ end
43
+
44
+ def self.number(options={})
45
+ options = {:at_least => 1,
46
+ :at_most => 10}.merge(options)
47
+
48
+ (options[:at_least]..options[:at_most]).random
49
+ end
50
+
51
+ def self.text(options={})
52
+ options = {:at_least => 10,
53
+ :at_most => 15,
54
+ :allow_lower => true,
55
+ :allow_upper => true,
56
+ :allow_numeric => true,
57
+ :allow_special => false}.merge!(options)
58
+
59
+ allowed_characters = []
60
+ allowed_characters += LOWER_ALPHA if options[:allow_lower]
61
+ allowed_characters += UPPER_ALPHA if options[:allow_upper]
62
+ allowed_characters += NUMERIC if options[:allow_numeric]
63
+ allowed_characters += SPECIAL_CHARACTERS if options[:allow_special]
64
+
65
+ length = (options[:at_least]..options[:at_most]).random
66
+
67
+ allowed_characters.random_subset(length).join
68
+ end
69
+
70
+ def self.frequency
71
+ FREQUENCIES.random
72
+ end
73
+ end
@@ -0,0 +1,19 @@
1
+ class InternetForgery < Forgery
2
+ dictionaries :male_first_names, :female_first_names, :last_names, :top_level_domains, :company_names
3
+
4
+ def self.user_name
5
+ (MALE_FIRST_NAMES.random[0,1] + LAST_NAMES.random).downcase
6
+ end
7
+
8
+ def self.top_level_domain
9
+ TOP_LEVEL_DOMAINS.random
10
+ end
11
+
12
+ def self.domain_name
13
+ COMPANY_NAMES.random.downcase + '.' + self.top_level_domain
14
+ end
15
+
16
+ def self.email_address
17
+ self.user_name + '@' + self.domain_name
18
+ end
19
+ end
@@ -0,0 +1,107 @@
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
+
6
+ def self.text(what=:sentence, quantity=2, options={})
7
+ case what
8
+ when :character
9
+ self.character(options)
10
+ when :characters
11
+ self.characters(quantity, options)
12
+ when :word
13
+ self.word(options)
14
+ when :words
15
+ self.words(quantity, options)
16
+ when :sentence
17
+ self.sentence(options)
18
+ when :sentences
19
+ self.sentences(quantity, options)
20
+ when :paragraph
21
+ self.paragraph(options)
22
+ when :paragraphs
23
+ self.paragraphs(quantity, options)
24
+ end
25
+ end
26
+
27
+
28
+ def self.character(options={})
29
+ self.characters(1, options)
30
+ end
31
+
32
+ def self.characters(quantity=10, options={})
33
+ options.merge!(:random_limit => LOREM_IPSUM_CHARACTERS.length-quantity) if quantity.is_a?(Fixnum)
34
+
35
+ LOREM_IPSUM_CHARACTERS[range_from_quantity(quantity, options)]
36
+ end
37
+
38
+ def self.word(options={})
39
+ self.words(1, options)
40
+ end
41
+
42
+ def self.words(quantity=10, options={})
43
+ options.merge!(:random_limit => LOREM_IPSUM_WORDS.length-quantity) if quantity.is_a?(Fixnum)
44
+
45
+ LOREM_IPSUM_WORDS[range_from_quantity(quantity, options)].join(" ")
46
+ end
47
+
48
+ def self.sentence(options={})
49
+ self.sentences(1, options)
50
+ end
51
+
52
+ def self.sentences(quantity=2, options={})
53
+ options.merge!(:random_limit => (LOREM_IPSUM.length-quantity)) if quantity.is_a?(Fixnum)
54
+
55
+ LOREM_IPSUM[range_from_quantity(quantity, options)].join(" ")
56
+ end
57
+
58
+ def self.paragraph(options={})
59
+ self.paragraphs(1, options)
60
+ end
61
+
62
+ def self.paragraphs(quantity=2, options={})
63
+ options.reverse_merge!(:separator => "\n\n",
64
+ :wrap => {
65
+ :start => "",
66
+ :end => "" },
67
+ :html => false,
68
+ :sentences => 3)
69
+ options.merge!(:random_limit => (LOREM_IPSUM.length/options[:sentences])-quantity) if quantity.is_a?(Fixnum)
70
+
71
+ if options[:html]
72
+ options[:wrap] = { :start => "<p>",
73
+ :end => "</p>" }
74
+ end
75
+
76
+ range = range_from_quantity(quantity, options)
77
+ start = range.first * options[:sentences]
78
+
79
+ paragraphs = []
80
+
81
+ range.to_a.length.times do |i|
82
+ paragraphs << (
83
+ options[:wrap][:start] +
84
+ LOREM_IPSUM[start..(start+options[:sentences]-1)].join(" ") +
85
+ options[:wrap][:end]
86
+ )
87
+ start += options[:sentences]
88
+ end
89
+
90
+ paragraphs.join(options[:separator])
91
+ end
92
+
93
+
94
+ protected
95
+
96
+ def self.range_from_quantity(quantity, options={})
97
+ return quantity if quantity.is_a?(Range)
98
+
99
+ if options[:random]
100
+ start = (0..options[:random_limit]).random
101
+ start..(start+quantity-1)
102
+ else
103
+ 0..(quantity-1)
104
+ end
105
+ end
106
+
107
+ end
@@ -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,36 @@
1
+ class NameForgery < Forgery
2
+ dictionaries :last_names, :male_first_names, :female_first_names, :company_names,
3
+ :name_suffixes, :name_titles
4
+
5
+ def self.last_name
6
+ LAST_NAMES.random
7
+ end
8
+
9
+ def self.first_name
10
+ [MALE_FIRST_NAMES, FEMALE_FIRST_NAMES].random.random
11
+ end
12
+
13
+ def self.full_name
14
+ "#{self.first_name} #{self.last_name}"
15
+ end
16
+
17
+ def self.male_first_name
18
+ MALE_FIRST_NAMES.random
19
+ end
20
+
21
+ def self.female_first_name
22
+ FEMALE_FIRST_NAMES.random
23
+ end
24
+
25
+ def self.company_name
26
+ COMPANY_NAMES.random
27
+ end
28
+
29
+ def self.title
30
+ NAME_TITLES.random
31
+ end
32
+
33
+ def self.suffix
34
+ NAME_SUFFIXES.random
35
+ end
36
+ end
@@ -0,0 +1,23 @@
1
+ class PersonalForgery < Forgery
2
+ dictionaries :races, :languages, :shirt_sizes, :genders
3
+
4
+ def self.gender
5
+ GENDERS.random
6
+ end
7
+
8
+ def self.abbreviated_gender
9
+ gender[0,1]
10
+ end
11
+
12
+ def self.shirt_size
13
+ SHIRT_SIZES.random
14
+ end
15
+
16
+ def self.race
17
+ RACES.random
18
+ end
19
+
20
+ def self.language
21
+ LANGUAGES.random
22
+ end
23
+ end
data/lib/forgery.rb ADDED
@@ -0,0 +1,82 @@
1
+ # Require forgeries at the bottom of the file so Forgery works as a gem
2
+
3
+ Dir[File.expand_path(File.dirname(__FILE__) + '/extensions/**/*.rb')].uniq.each do |file|
4
+ require file
5
+ end
6
+
7
+ 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
+
38
+ def self.path_to_format(format)
39
+ if external_path_to_format(format) && File.exists?(external_path_to_format(format))
40
+ external_path_to_format(format)
41
+ else
42
+ internal_path_to_format(format)
43
+ end
44
+ end
45
+
46
+ def self.external_path_to_format(format)
47
+ RAILS_ROOT + '/lib/forgery/formats/' + format.to_s if defined?(RAILS_ROOT)
48
+ end
49
+
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
+ end
70
+
71
+ def Forgery(forgery, method=nil, *args)
72
+ klass = "#{forgery.to_s.camelize}Forgery".constantize
73
+ if method
74
+ klass.send(method, *args)
75
+ else
76
+ klass
77
+ end
78
+ end
79
+
80
+ Dir[File.expand_path(File.dirname(__FILE__) + '/forgeries/**/*.rb')].uniq.each do |file|
81
+ require file
82
+ end
data/lib/formats/phone ADDED
@@ -0,0 +1 @@
1
+ #-(###)###-####
@@ -0,0 +1,5 @@
1
+ #
2
+ ##
3
+ ###
4
+ ####
5
+ #####
data/lib/formats/zip ADDED
@@ -0,0 +1,2 @@
1
+ #####
2
+ #####-####
@@ -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,17 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Range do
4
+ it "should get a random number out of the range" do
5
+ range = (0..9)
6
+ 10.times { range.should include(range.random) }
7
+ end
8
+
9
+ it "should get a random string our of the range" do
10
+ range = ("a".."z")
11
+ 10.times { range.should include(range.random) }
12
+ end
13
+
14
+ it "should return nil if the maximum is less than the minimum" do
15
+ ("z".."a").random.should be_nil
16
+ end
17
+ 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,69 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe AddressForgery do
4
+ it "should return a random street" do
5
+ AddressForgery::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
+ AddressForgery::STREET_NUMBER_FORMATS.should include(original_format)
11
+ end
12
+
13
+ it "should return a random street suffix" do
14
+ AddressForgery::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
+ AddressForgery::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
+ AddressForgery::STREET_NUMBER_FORMATS.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
+ AddressForgery::STREETS.should include(street)
37
+ end
38
+ end
39
+
40
+ it "should return a random city" do
41
+ city = AddressForgery.city
42
+ AddressForgery::CITIES.should include(city)
43
+ end
44
+
45
+ it "should return a random state" do
46
+ state = AddressForgery.state
47
+ AddressForgery::STATES.should include(state)
48
+ end
49
+
50
+ it "should return a random state abbreviation" do
51
+ state_abbrev = AddressForgery.state_abbrev
52
+ AddressForgery::STATE_ABBREVS.should include(state_abbrev)
53
+ end
54
+
55
+ it "should return a random country" do
56
+ country = AddressForgery.country
57
+ AddressForgery::COUNTRIES.should include(country)
58
+ end
59
+
60
+ it "should return a random zip code" do
61
+ zip_format = AddressForgery.zip.gsub(/\d/, '#')
62
+ AddressForgery::ZIP_FORMATS.should include(zip_format)
63
+ end
64
+
65
+ it "should return a random phone number" do
66
+ phone_format = AddressForgery.phone.gsub(/\d/, '#')
67
+ AddressForgery::PHONE_FORMATS.should include(phone_format)
68
+ end
69
+ end