pseudo_entity 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,3 @@
1
+ class PseudoEntity
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,138 @@
1
+ class PseudoEntity
2
+
3
+ require 'pseudo_entity/randoms'
4
+
5
+ include Enumerable
6
+ include Randoms
7
+
8
+ def initialize(options={})
9
+ parse_options options
10
+ end
11
+
12
+ def address
13
+ "#{street_address}\n#{city}, #{state}. #{zip_code}"
14
+ end
15
+
16
+ def age
17
+ Date.today.year - birth_day.year
18
+ end
19
+
20
+ def apartment?
21
+ street_modifier_needed == :apartment
22
+ end
23
+
24
+ def birth_year
25
+ birth_day.year
26
+ end
27
+
28
+ def credit_card_last_four
29
+ credit_card_number[-4..-1]
30
+ end
31
+ alias :credit_card_last4 :credit_card_last_four
32
+
33
+ def full_name
34
+ "#{first_name} #{last_name}"
35
+ end
36
+
37
+ def google_map_url
38
+ "https://maps.google.com/maps?q=loc:#{latitude},#{longitude}"
39
+ end
40
+
41
+ # Reset all internal values causing them to be regenerated.
42
+ def reset!
43
+ self.instance_variables.each { |variable| instance_variable_set(variable, nil) }
44
+ self
45
+ end
46
+
47
+ def street_address
48
+ # Yes it is in 2-1 order because that's how the US Post Office says to do it.
49
+ # Apartment, Suites, etc go on the first line if there are two lines or at the end of the single line
50
+ # http://pe.usps.com/businessmail101/addressing/deliveryaddress.htm
51
+ "#{street_address_line_2} #{street_address_line_1}".strip
52
+ end
53
+
54
+ def street_address_line_1
55
+ if apartment?
56
+ "APT #{apartment_number}"
57
+ elsif suite?
58
+ "STE #{suite_number}"
59
+ else
60
+ street_position
61
+ end
62
+ end
63
+
64
+ def street_address_line_2
65
+ street_address_line_1 # Force the determination of line 1 as this effects line 2
66
+ street_modifier_needed? ? street_position : nil
67
+ end
68
+
69
+ def suite?
70
+ street_modifier_needed == :suite
71
+ end
72
+
73
+ def yelp_business_id
74
+ # Yelp API version 2.0 id
75
+ "#{company_name.gsub(' ', '-').delete('.')}-#{city.gsub(' ', '-').delete('.')}"
76
+ end
77
+
78
+ def yelp_business_url
79
+ "http://www.yelp.com/biz/#{yelp_business_id}"
80
+ end
81
+
82
+ def yelp_user_id
83
+ random_alpha_numeric(22)
84
+ end
85
+
86
+ def to_s
87
+ add = address.sub("\n","\n ")
88
+ [
89
+ "Name: #{full_name}",
90
+ "Age: #{age}",
91
+ "Sex: #{sex}",
92
+ "Email: #{email_address}",
93
+ "IP Address: #{ip_address}",
94
+ "Website: #{website}",
95
+ "Short Url: #{short_url}",
96
+ "Phone: #{phone_number}",
97
+ "Address: #{add}",
98
+ "Coordinates: #{latitude}, #{longitude}",
99
+ "Timezone: #{time_zone}",
100
+ "Bank: #{bank_name} #{bank_routing_number} #{bank_account_number}",
101
+ "Credit Union: #{credit_union_name}",
102
+ "Card: #{credit_card_issuer} #{credit_card_number}",
103
+ "Company: #{company_name}",
104
+ "Slogan: #{slogan}",
105
+ "Tax ID: #{federal_tax_id}",
106
+ "Login: #{login}",
107
+ "Password: #{password}"
108
+ ].join("\n")
109
+ end
110
+
111
+ def self.all
112
+ @all = Randoms.names.map { |name| new :first_name => name.first, :last_name => name.last }
113
+ end
114
+
115
+ def self.each(&block)
116
+ all.each(&block)
117
+ end
118
+
119
+ def self.to_a
120
+ all
121
+ end
122
+
123
+ def self.load_caches(verbose=false)
124
+ entity = new
125
+ RandomValues.each do |method|
126
+ puts method if verbose
127
+ begin
128
+ entity.send(method)
129
+ rescue => e
130
+ puts e.message
131
+ end
132
+ end
133
+ true
134
+ end
135
+
136
+ end
137
+
138
+ require 'pseudo_entity/version'
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'pseudo_entity/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'pseudo_entity'
8
+ spec.version = PseudoEntity::VERSION
9
+ spec.authors = ['Frank Hall']
10
+ spec.email = ['ChapterHouse.Dune@gmail.com']
11
+ spec.description = %q{A class for generating realistic looking data for people, companies, etc.}
12
+ spec.summary = %q{A class for generating realistic looking data for people, companies, etc.}
13
+ spec.homepage = 'http://chapterhouse.github.io/pseudo_entity'
14
+ spec.license = 'MIT'
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ['lib']
20
+
21
+ spec.add_development_dependency 'bundler', '~> 1.3'
22
+ spec.add_development_dependency 'rake'
23
+ spec.add_development_dependency 'rspec', '~> 2.13'
24
+
25
+ spec.add_runtime_dependency 'uuidtools', '~> 2.1'
26
+ spec.add_runtime_dependency 'active_support', '>= 2.0'
27
+ spec.add_runtime_dependency 'tzinfo'
28
+ spec.add_runtime_dependency 'huge_enumerable'
29
+
30
+ end
@@ -0,0 +1,276 @@
1
+ require 'spec_helper'
2
+
3
+ describe PseudoEntity::Randoms do
4
+
5
+ RSpec::Matchers.define :be_all_digits do
6
+ match do |string|
7
+ string.gsub(/[0-9]*/,'').empty?
8
+ end
9
+ end
10
+
11
+ RSpec::Matchers.define :be_all_alphabetic_characters do
12
+ match do |string|
13
+ string.gsub(/[a-z]|[A-Z]*/,'').empty?
14
+ end
15
+ end
16
+
17
+ RSpec::Matchers.define :be_all_alphanumeric_characters do
18
+ match do |string|
19
+ string.gsub(/[a-z]|[A-Z][0-9]*/,'').empty?
20
+ end
21
+ end
22
+
23
+
24
+ context "when included" do
25
+
26
+ let(:class_a_regex) { /^10\.(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){2}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/ }
27
+ let(:class_b_regex) { /^172\.(?:(?:1[6-9]|2[0-9]|3[0-1]?)\.)(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.)(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/ }
28
+ let(:class_c_regex) { /^192\.168\.(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.)(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/ }
29
+
30
+ subject(:instance) do
31
+ klass = Class.new
32
+ klass.send(:include, PseudoEntity::Randoms)
33
+ klass.new
34
+ end
35
+
36
+ it "responds to all RandomValues" do
37
+ PseudoEntity::RandomValues.all? { |method| instance.respond_to?(method.to_sym) }.should be_true
38
+ end
39
+
40
+ it "lists all RandomValues as methods" do
41
+ (PseudoEntity::RandomValues - instance.methods).should be_empty
42
+ end
43
+
44
+ it "responds to ArityValues" do
45
+ methods = PseudoEntity::ArityValues.map { |regexp| regexp.to_s.match(/.*\^(.*_)\\d.*/)[1] + rand(100).to_s }
46
+ methods.all? { |method| instance.respond_to?(method.to_sym) }.should be_true
47
+ end
48
+
49
+ it "responds to ArityRandoms" do
50
+ methods = PseudoEntity::ArityRandoms.map { |regexp| regexp.to_s.match(/.*\^(.*_)\\d.*/)[1] + rand(100).to_s }
51
+ methods.all? { |method| instance.respond_to?(method.to_sym, true) }.should be_true
52
+ end
53
+
54
+ it "has private ArityRandoms" do
55
+ methods = PseudoEntity::ArityRandoms.map { |regexp| regexp.to_s.match(/.*\^(.*_)\\d.*/)[1] + rand(100).to_s }
56
+ methods.all? { |method| !instance.respond_to?(method.to_sym) }.should be_true
57
+ end
58
+
59
+ it "has corresponding private random_X methods for RandomValues" do
60
+ (PseudoEntity::RandomValues.map { |method| "random_#{method}".to_sym } - instance.private_methods).should be_empty
61
+ end
62
+
63
+ context "#parse_options" do
64
+
65
+ it "sets initial values" do
66
+ value_names = PseudoEntity::RandomValues
67
+ hash = value_names.inject({}) { |hsh, name| hsh[name] = "123 #{name}"; hsh}
68
+ instance.send(:parse_options, hash)
69
+ value_names.all? { |name| instance.send(name) == "123 #{name}" }.should be_true
70
+ end
71
+
72
+ end
73
+
74
+ context "#random_alpha" do
75
+
76
+ it "returns X characters" do
77
+ instance.send(:random_alpha, 256).size.should eql(256)
78
+ end
79
+
80
+ it "only generates alphabetic characters" do
81
+ instance.stub(:rand).and_return(*(0..51).to_a)
82
+ instance.send(:random_alpha, 256).should be_all_alphanumeric_characters
83
+ # If only alphabetic characters are available then nothing should show up at slot 52
84
+ instance.stub(:rand).and_return(52)
85
+ instance.send(:random_alpha, 1).size.should eq(0)
86
+ end
87
+
88
+ end
89
+
90
+ context "#random_alpha_numeric" do
91
+
92
+ it "returns X characters" do
93
+ instance.send(:random_alpha_numeric, 256).size.should eql(256)
94
+ end
95
+
96
+ it "only generates alphabetic characters or digits" do
97
+ instance.stub(:rand).and_return(*(0..61).to_a)
98
+ instance.send(:random_alpha, 256).should be_all_alphabetic_characters
99
+ # If only alphabetic characters and digits are available then nothing should show up at slot 62
100
+ instance.stub(:rand).and_return(62)
101
+ instance.send(:random_alpha_numeric, 1).size.should eq(0)
102
+ end
103
+
104
+ end
105
+
106
+ context "#random_apartment_number" do
107
+
108
+ it "never returns zero or less" do
109
+ instance.stub(:rand).and_return(0)
110
+ instance.send(:random_apartment_number).should > 0
111
+ end
112
+
113
+ end
114
+
115
+ context "#random_bank_account_number" do
116
+
117
+ it "is thirteen characters long" do
118
+ instance.send(:random_bank_account_number).size.should eql(13)
119
+ end
120
+
121
+ it "is all digits" do
122
+ instance.send(:random_bank_account_number).should be_all_digits
123
+ end
124
+
125
+ end
126
+
127
+ context "#random_bank_routing_number" do
128
+
129
+ it "is nine characters long" do
130
+ instance.send(:random_bank_routing_number).size.should eql(9)
131
+ end
132
+
133
+ it "is all digits" do
134
+ instance.send(:random_bank_routing_number).should be_all_digits
135
+ end
136
+
137
+ end
138
+
139
+ context "#random_numeric" do
140
+
141
+ it "return X characters" do
142
+ instance.send(:random_alpha_numeric, 256).size.should eql(256)
143
+ end
144
+
145
+ it "only generates digits" do
146
+ instance.send(:random_numeric, 256).should be_all_digits
147
+ end
148
+
149
+ end
150
+
151
+ context "#random_birth_day" do
152
+
153
+ it "is always be at least 21 years ago" do
154
+ instance.stub(:rand).and_return(0)
155
+ (Date.today.year - instance.send(:random_birth_day).year).should >= 21
156
+ end
157
+
158
+ end
159
+
160
+ context "#random_class_a_ip_address" do
161
+
162
+ it "is in the private class A range" do
163
+ instance.send(:random_class_a_ip_address).should =~ class_a_regex
164
+ end
165
+
166
+ end
167
+
168
+ context "#random_class_b_ip_address" do
169
+
170
+ it "is in the private class B range" do
171
+ instance.send(:random_class_b_ip_address).should =~ class_b_regex
172
+ end
173
+
174
+ end
175
+
176
+ context "#random_class_c_ip_address" do
177
+
178
+ it "is in the private class C range" do
179
+ instance.send(:random_class_c_ip_address).should =~ class_c_regex
180
+ end
181
+
182
+ end
183
+
184
+ context "#random_email_address" do
185
+
186
+ it "conforms to the pattern name@domain" do
187
+ simple_email_regex = /^.*@.*\..*$/
188
+ instance.send(:random_email_address) =~ simple_email_regex
189
+ end
190
+
191
+ end
192
+
193
+ context "#random_facebook_id" do
194
+
195
+ it "is all digits" do
196
+ instance.send(:random_facebook_id).should be_all_digits
197
+ end
198
+
199
+ it "is a maximum of 64 bits long" do
200
+ # This is a little brittle but not sure how else to test this
201
+ instance.should_receive(:rand).with(2**64).and_return(2**64)
202
+ instance.send(:random_facebook_id)
203
+ end
204
+
205
+ end
206
+
207
+ context "#random_federal_tax_id" do
208
+
209
+ it "is nine characters long" do
210
+ instance.send(:random_federal_tax_id).size.should eql(9)
211
+ end
212
+
213
+ it "is all digits" do
214
+ instance.send(:random_federal_tax_id).should be_all_digits
215
+ end
216
+
217
+ end
218
+
219
+ context "#random_google_analytics_account_id" do
220
+ it "conforms to Google's Analytic Account pattern" do
221
+ instance.send(:random_google_analytics_account_id).should =~ /^UA-\d{7}-\d{2}$/
222
+ end
223
+ end
224
+
225
+ context "#random_ip_address" do
226
+
227
+ it "is one of the non routable IP addresses" do
228
+ ip_address = instance.send(:random_ip_address)
229
+ [class_a_regex, class_b_regex, class_c_regex].any? { |regexp| ip_address =~ regexp }.should be_true
230
+ end
231
+
232
+ end
233
+
234
+ context "#random_phone_number" do
235
+
236
+ it "is a ten digit comma separated value" do
237
+ instance.send(:random_phone_number).should =~ /^[0-9]{3}-[0-9]{3}-[0-9]{4}$/
238
+ end
239
+
240
+ end
241
+
242
+ context "#random_property_number" do
243
+
244
+ it "will never be less than 10" do
245
+ instance.stub(:rand).and_return(0)
246
+ instance.send(:random_property_number).should >= 10
247
+ end
248
+
249
+ end
250
+
251
+ context "#random_sex" do
252
+
253
+ it "will never be less than 10" do
254
+ instance.stub(:rand).and_return(0)
255
+ instance.send(:random_property_number).should >= 10
256
+ end
257
+
258
+ end
259
+
260
+ end
261
+
262
+ context "as itself" do
263
+
264
+ subject(:random) { PseudoEntity::Randoms }
265
+
266
+ it "should create a token smaller than 32 characters" do
267
+ random.token(3).size.should eq(3)
268
+ end
269
+
270
+ it "should create a token larger than 32 characters" do
271
+ random.token(128).size.should eq(128)
272
+ end
273
+
274
+ end
275
+
276
+ end
@@ -0,0 +1,157 @@
1
+ require 'spec_helper'
2
+
3
+ describe PseudoEntity do
4
+
5
+ let(:age) { 10 }
6
+ let(:date) { age.years.ago }
7
+ let(:cc_last_four) { '4321' }
8
+ let(:latitude) { 1.2 }
9
+ let(:longitude) { 3.4 }
10
+ let(:street_position) { 'street_position' }
11
+ let(:company_name) { 'Some Company Ltd.'}
12
+ let(:city) { 'St. Archibald' }
13
+ let(:state) { 'ZZ' }
14
+ let(:zip_code) { 12345 }
15
+ let(:first_name) { 'John' }
16
+ let(:last_name) { 'Smith' }
17
+
18
+ subject(:pseudo_entity) do
19
+ PseudoEntity.new.tap{ |pe|
20
+ pe.stub(:birth_day).and_return(date)
21
+ pe.stub(:city).and_return(city)
22
+ pe.stub(:state).and_return(state)
23
+ pe.stub(:zip_code).and_return(zip_code)
24
+ pe.stub(:credit_card_number).and_return('98765' + cc_last_four)
25
+ pe.stub(:first_name).and_return(first_name)
26
+ pe.stub(:last_name).and_return(last_name)
27
+ pe.stub(:latitude).and_return(latitude)
28
+ pe.stub(:longitude).and_return(longitude)
29
+ pe.stub(:street_position).and_return(street_position)
30
+ pe.stub(:company_name).and_return(company_name)
31
+ pe.stub(:city).and_return(city)
32
+ }
33
+ end
34
+
35
+ it "should calculate age" do
36
+ pseudo_entity.age.should eql(age)
37
+ end
38
+
39
+ it "should combine components into a full address" do
40
+ pseudo_entity.stub(:street_address).and_return('street_address')
41
+ pseudo_entity.address.should eql("street_address\n#{city}, #{state}. #{zip_code}")
42
+ end
43
+
44
+ it "should identify when an address is and is not an apartment" do
45
+ pseudo_entity.stub(:street_modifier_needed).and_return(:apartment)
46
+ pseudo_entity.apartment?.should be_true
47
+ pseudo_entity.stub(:street_modifier_needed).and_return(:something_else)
48
+ pseudo_entity.apartment?.should be_false
49
+ end
50
+
51
+ it "should extract birth year" do
52
+ pseudo_entity.birth_year.should eql(date.year)
53
+ end
54
+
55
+ it "should extract the last four digits of the credit card number" do
56
+ pseudo_entity.credit_card_last_four.should eql(cc_last_four)
57
+ end
58
+
59
+ it "should combine names into a full name" do
60
+ pseudo_entity.full_name.should eql("#{first_name} #{last_name}")
61
+ end
62
+
63
+ it "should generate a google map url from latitude and longitude" do
64
+ pseudo_entity.google_map_url.should eql("https://maps.google.com/maps?q=loc:#{latitude},#{longitude}")
65
+ end
66
+
67
+ it "should not return new values without resetting" do
68
+ names = [ 'Jack', 'Jill' ]
69
+ pseudo_entity = PseudoEntity.new
70
+ pseudo_entity.stub(:random_first_name).and_return(names.shift)
71
+ pseudo_entity.first_name.should equal(pseudo_entity.first_name)
72
+ end
73
+
74
+ it "should return new values after a reset" do
75
+ names = [ 'Jack', 'Jill' ]
76
+ pseudo_entity = PseudoEntity.new
77
+ pseudo_entity.stub(:random_first_name).and_return(names.shift)
78
+ name = pseudo_entity.first_name
79
+ pseudo_entity.reset!
80
+ pseudo_entity.stub(:random_first_name).and_return(names.shift)
81
+ pseudo_entity.first_name.should_not eql(name)
82
+ end
83
+
84
+ it "should return self after a reset" do
85
+ pseudo_entity.reset!.should equal(pseudo_entity)
86
+ end
87
+
88
+ it "should combine addresses in 2,1 order" do
89
+ pseudo_entity.stub(:street_address_line_1).and_return(:street_address_line_1)
90
+ pseudo_entity.stub(:street_address_line_2).and_return(:street_address_line_2)
91
+ pseudo_entity.street_address.should eql('street_address_line_2 street_address_line_1')
92
+ end
93
+
94
+ it "should trim missing street information" do
95
+ pseudo_entity.stub(:street_address_line_1).and_return(:street_address_line_1)
96
+ pseudo_entity.stub(:street_address_line_2).and_return('')
97
+ pseudo_entity.street_address.should == 'street_address_line_1'
98
+ pseudo_entity.stub(:street_address_line_1).and_return('')
99
+ pseudo_entity.stub(:street_address_line_2).and_return(:street_address_line_2)
100
+ pseudo_entity.street_address.should eql('street_address_line_2')
101
+ end
102
+
103
+ it "should apartment number as street address line 1 when the address is at an apartment" do
104
+ apartment_number = 1234
105
+ pseudo_entity.stub(:apartment_number).and_return(apartment_number)
106
+ pseudo_entity.stub(:apartment?).and_return(true)
107
+ pseudo_entity.stub(:suite?).and_return(false)
108
+ pseudo_entity.street_address_line_1.should eql("APT #{apartment_number}")
109
+ end
110
+
111
+ it "should suite number as street address line 1 when the address is at a suite" do
112
+ suite_number = 1234
113
+ pseudo_entity.stub(:suite_number).and_return(suite_number)
114
+ pseudo_entity.stub(:apartment?).and_return(false)
115
+ pseudo_entity.stub(:suite?).and_return(true)
116
+ pseudo_entity.street_address_line_1.should eql("STE #{suite_number}")
117
+ end
118
+
119
+ it "should use the street position as street address line 1 when not at an apartment or suite" do
120
+ pseudo_entity.stub(:apartment?).and_return(false)
121
+ pseudo_entity.stub(:suite?).and_return(false)
122
+ pseudo_entity.street_address_line_1.should eql(street_position)
123
+ end
124
+
125
+ it "should use street position as street address line 2 when a street modifier is needed" do
126
+ pseudo_entity.stub(:street_modifier_needed?).and_return(true)
127
+ pseudo_entity.street_address_line_2.should eql(street_position)
128
+ end
129
+
130
+ it "should return nil as street address line 2 when a street modifier is not needed" do
131
+ pseudo_entity.stub(:street_modifier_needed?).and_return(false)
132
+ pseudo_entity.street_address_line_2.should be_nil
133
+ end
134
+
135
+ it "should identify when an address is and is not an suite" do
136
+ pseudo_entity.stub(:street_modifier_needed).and_return(:suite)
137
+ pseudo_entity.suite?.should be_true
138
+ pseudo_entity.stub(:street_modifier_needed).and_return(:something_else)
139
+ pseudo_entity.suite?.should be_false
140
+ end
141
+
142
+ it "should generate a yelp business id from the company name and the city" do
143
+ pseudo_entity.yelp_business_id.should == 'Some-Company-Ltd-St-Archibald'
144
+ end
145
+
146
+ it "should generate a yelp business url from the yelp business id" do
147
+ pseudo_entity.stub(:yelp_business_id).and_return(:yelp_business_id)
148
+ pseudo_entity.yelp_business_url.should == 'http://www.yelp.com/biz/yelp_business_id'
149
+ end
150
+
151
+ it "should generate a string 22 characters long for yelp user id" do
152
+ yelp_user_id = pseudo_entity.yelp_user_id
153
+ yelp_user_id.should be_an_instance_of(String)
154
+ yelp_user_id.size.should eql(22)
155
+ end
156
+
157
+ end
@@ -0,0 +1 @@
1
+ require 'pseudo_entity'