new_data_magic 1.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,65 @@
1
+ dm:
2
+ value1: this is value 1
3
+ value2: this is value 2
4
+ full_name: ~full_name
5
+ first_name: ~first_name
6
+ last_name: ~last_name
7
+ name_prefix: ~name_prefix
8
+ name_suffix: ~name_suffix
9
+ street: ~street_address
10
+ street_plus: ~street_address(true)
11
+ city: ~city
12
+ state: ~state
13
+ state_ab: ~state_abbr
14
+ zip: ~zip_code
15
+ country: ~country
16
+ second_address: ~secondary_address
17
+ company: ~company_name
18
+ email: ~email_address
19
+ email_plus: ~email_address('buddy')
20
+ domain_name: ~domain_name
21
+ url: ~url
22
+ user_name: ~user_name
23
+ phone: ~phone_number
24
+ cell: ~cell_phone
25
+ catch_phrase: ~catch_phrase
26
+ words: ~words
27
+ sentence: ~sentence
28
+ sentences: ~sentences
29
+ paragraphs: ~paragraphs
30
+ characters: ~characters
31
+ bool_true: true
32
+ bool_false: false
33
+ random: ~randomize ['Tom', 'Dick', 'Harry']
34
+ ordered: ~sequential ['first', 'second', 'third']
35
+ range: ~randomize 1..5
36
+ mask: ~mask "###-AAA_aaa"
37
+ job_title: ~job_title
38
+ today: ~today
39
+ tomorrow: ~tomorrow
40
+ yesterday: ~yesterday
41
+ 5daysfromtoday: ~5.days_from_today
42
+ 5daysago: ~5.days_ago
43
+ some_month: ~month
44
+ month_abbr: ~month_abbr
45
+ some_day: ~day_of_week
46
+ day_abbr: ~day_of_week_abbr
47
+ this:
48
+ is_nested: Nested Value
49
+ translate_nested:
50
+ full_name: ~full_name
51
+ first_name: ~first_name
52
+ color_hex: ~color_hex
53
+ color_name: ~color_name
54
+ number: ~number(digits = 10, true)
55
+ decimal: ~decimal(before_decimal = 5, after_decimal = 3)
56
+ merge: ~merge(separator = '--', [first_name, last_name, number(3)])
57
+ date_between: ~date_between(from = '01/01/2021', to = '31/12/2021', format = '%d/%m/%y')
58
+
59
+ dynamic:
60
+ blah: ~blah
61
+
62
+ other:
63
+ name: Cheezy
64
+ address: 123 Main Street
65
+ email: cheezy@example.com
@@ -0,0 +1,7 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Hash
4
+ def deep_copy
5
+ Marshal.load(Marshal.dump(self))
6
+ end
7
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: true
2
+
3
+ class Integer
4
+ def days_from_today(format = '%D')
5
+ the_day = Date.today + self
6
+ the_day.strftime(format)
7
+ end
8
+
9
+ def days_ago(format = '%D')
10
+ the_day = Date.today - self
11
+ the_day.strftime(format)
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ # frozen_string_literal: true
2
+
3
+ class String
4
+ def is_integer
5
+ true if Integer(self)
6
+ rescue StandardError
7
+ false
8
+ end
9
+ end
@@ -0,0 +1,100 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DataMagic
4
+ module DateTranslation
5
+ #
6
+ # return today's date
7
+ #
8
+ # @param String the format to use for the date. Default is %D
9
+ #
10
+ # See http://ruby-doc.org/stdlib-1.9.3/libdoc/date/rdoc/Date.html#method-i-strftime
11
+ # for details of the formats
12
+ #
13
+ def today(format = '%D')
14
+ Date.today.strftime(format)
15
+ end
16
+ alias dm_today today
17
+
18
+ #
19
+ # return tomorrow's date
20
+ #
21
+ # @param String the format to use for the date. Default is %D
22
+ #
23
+ # See http://ruby-doc.org/stdlib-1.9.3/libdoc/date/rdoc/Date.html#method-i-strftime
24
+ # for details of the formats
25
+ #
26
+ def tomorrow(format = '%D')
27
+ tomorrow = Date.today + 1
28
+ tomorrow.strftime(format)
29
+ end
30
+ alias dm_tomorrow tomorrow
31
+
32
+ #
33
+ # return yesterday's date
34
+ #
35
+ # @param String the format to use for the date. Default is %D
36
+ #
37
+ # See http://ruby-doc.org/stdlib-1.9.3/libdoc/date/rdoc/Date.html#method-i-strftime
38
+ # for details of the formats
39
+ #
40
+ def yesterday(format = '%D')
41
+ yesterday = Date.today - 1
42
+ yesterday.strftime(format)
43
+ end
44
+ alias dm_yesterday yesterday
45
+
46
+ #
47
+ # return a month
48
+ #
49
+ def month
50
+ randomize(Date::MONTHNAMES[1..-1])
51
+ end
52
+ alias dm_month month
53
+
54
+ #
55
+ # return a month abbreviation
56
+ #
57
+ def month_abbr
58
+ randomize(Date::ABBR_MONTHNAMES[1..-1])
59
+ end
60
+ alias dm_month_abbr month_abbr
61
+
62
+ #
63
+ # return a day of the week
64
+ #
65
+ def day_of_week
66
+ randomize(Date::DAYNAMES)
67
+ end
68
+ alias dm_day_of_week day_of_week
69
+
70
+ def day_of_week_abbr
71
+ randomize(Date::ABBR_DAYNAMES)
72
+ end
73
+ alias dm_day_of_week_abbr day_of_week_abbr
74
+
75
+ ##################################################################
76
+ # #
77
+ # NEW TRANSLATOR STARTS HERE #
78
+ # #
79
+ ##################################################################
80
+
81
+ #
82
+ # return random date within the range
83
+ #
84
+ def date_between(from = nil, to = nil, format = '%D')
85
+ raise ArgumentError, 'Invalid date format' if from.to_s.empty? || to.to_s.empty?
86
+
87
+ start_date = from.nil? ? Date.today.strftime(format) : Date.strptime(from, format)
88
+ end_date = to.nil? ? Date.today.strftime(format) : Date.strptime(to, format)
89
+
90
+ Faker::Date.between(from: start_date, to: end_date).strftime(format)
91
+ end
92
+ alias dm_date_between date_between
93
+
94
+ ##################################################################
95
+ # #
96
+ # NEW TRANSLATOR ENDS HERE #
97
+ # #
98
+ ##################################################################
99
+ end
100
+ end
@@ -0,0 +1,370 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DataMagic
4
+ module StandardTranslation
5
+ attr_reader :parent
6
+
7
+ #
8
+ # return a random name (first and last)
9
+ #
10
+ def full_name
11
+ Faker::Name.name
12
+ end
13
+ alias dm_full_name full_name
14
+
15
+ #
16
+ # return a random first name
17
+ #
18
+ def first_name
19
+ Faker::Name.first_name
20
+ end
21
+ alias dm_first_name first_name
22
+
23
+ #
24
+ # return a random last name
25
+ #
26
+ def last_name
27
+ Faker::Name.last_name
28
+ end
29
+ alias dm_last_name last_name
30
+
31
+ #
32
+ # return a random name prefix
33
+ #
34
+ def name_prefix
35
+ Faker::Name.prefix
36
+ end
37
+ alias dm_name_prefix name_prefix
38
+
39
+ #
40
+ # return a random name suffix
41
+ #
42
+ def name_suffix
43
+ Faker::Name.suffix
44
+ end
45
+ alias dm_name_suffix name_suffix
46
+
47
+ #################################################################################
48
+ # In newer version of Faker, Faker::Name.title is changed to Faker::Job.title #
49
+ #################################################################################
50
+
51
+ #
52
+ # return a random job title
53
+ #
54
+ def job_title
55
+ Faker::Job.title
56
+ end
57
+ alias dm_job_title job_title
58
+
59
+ #
60
+ # return a random street address
61
+ #
62
+ def street_address(include_secondary = false)
63
+ Faker::Address.street_address(include_secondary: include_secondary)
64
+ end
65
+ alias dm_street_address street_address
66
+
67
+ #
68
+ # return a random secondary address
69
+ #
70
+ def secondary_address
71
+ Faker::Address.secondary_address
72
+ end
73
+ alias dm_secondary_address secondary_address
74
+
75
+ #
76
+ # return a random city
77
+ #
78
+ def city
79
+ Faker::Address.city
80
+ end
81
+ alias dm_city city
82
+
83
+ #
84
+ # return a random state
85
+ #
86
+ def state
87
+ Faker::Address.state
88
+ end
89
+ alias dm_state state
90
+
91
+ #
92
+ # return a random state abbreviation
93
+ #
94
+ def state_abbr
95
+ Faker::Address.state_abbr
96
+ end
97
+ alias dm_state_abbr state_abbr
98
+
99
+ #
100
+ # return a random 5 or 9 digit zip code
101
+ #
102
+ def zip_code
103
+ Faker::Address.zip
104
+ end
105
+ alias dm_zip_code zip_code
106
+
107
+ #
108
+ # return a random country
109
+ #
110
+ def country
111
+ Faker::Address.country
112
+ end
113
+ alias dm_country country
114
+
115
+ #
116
+ # return a random company name
117
+ #
118
+ def company_name
119
+ Faker::Company.name
120
+ end
121
+ alias dm_company_name company_name
122
+
123
+ #
124
+ # return a random catch phrase
125
+ #
126
+ def catch_phrase
127
+ Faker::Company.catch_phrase
128
+ end
129
+ alias dm_catch_phrase catch_phrase
130
+
131
+ #
132
+ # return a credit card number
133
+ #
134
+ def credit_card_number
135
+ Faker::Business.credit_card_number
136
+ end
137
+ alias dm_credit_card_number credit_card_number
138
+
139
+ #
140
+ # return a credit card type
141
+ #
142
+ def credit_card_type
143
+ Faker::Business.credit_card_type
144
+ end
145
+ alias dm_credit_card_type credit_card_type
146
+
147
+ #
148
+ # return random words - default is 3 words
149
+ #
150
+ def words(number = 3)
151
+ Faker::Lorem.words(number: number).join(' ')
152
+ end
153
+ alias dm_words words
154
+
155
+ #
156
+ # return a random sentence - default minimum word count is 4
157
+ #
158
+ def sentence(min_word_count = 4)
159
+ Faker::Lorem.sentence(word_count: min_word_count)
160
+ end
161
+ alias dm_sentence sentence
162
+
163
+ #
164
+ # return random sentences - default is 3 sentences
165
+ #
166
+ def sentences(sentence_count = 3)
167
+ Faker::Lorem.sentences(number: sentence_count).join(' ')
168
+ end
169
+ alias dm_sentences sentences
170
+
171
+ #
172
+ # return random paragraphs - default is 3 paragraphs
173
+ #
174
+ def paragraphs(paragraph_count = 3)
175
+ Faker::Lorem.paragraphs(number: paragraph_count).join('\n\n')
176
+ end
177
+ alias dm_paragraphs paragraphs
178
+
179
+ #
180
+ # return random characters - default is 255 characters
181
+ #
182
+ def characters(character_count = 255)
183
+ Faker::Lorem.characters(number: character_count)
184
+ end
185
+ alias dm_characters characters
186
+
187
+ #
188
+ # return a random email address
189
+ #
190
+ def email_address(name = nil, domain = nil)
191
+ Faker::Internet.email(name: name, domain: domain)
192
+ end
193
+ alias dm_email_address email_address
194
+
195
+ #
196
+ # return a random domain name
197
+ #
198
+ def domain_name
199
+ Faker::Internet.domain_name
200
+ end
201
+ alias dm_domain_name domain_name
202
+
203
+ #
204
+ # return a random url
205
+ #
206
+ def url
207
+ Faker::Internet.url
208
+ end
209
+ alias dm_url url
210
+
211
+ #
212
+ # return a random user name
213
+ #
214
+ def user_name
215
+ Faker::Internet.user_name
216
+ end
217
+ alias dm_user_name user_name
218
+
219
+ #
220
+ # return a random phone number
221
+ #
222
+ def phone_number
223
+ value = Faker::PhoneNumber.phone_number
224
+ remove_extension(value)
225
+ end
226
+ alias dm_phone_number phone_number
227
+
228
+ #
229
+ # return a random cell number
230
+ #
231
+ def cell_phone
232
+ value = Faker::PhoneNumber.cell_phone
233
+ remove_extension(value)
234
+ end
235
+ alias dm_cell_phone cell_phone
236
+
237
+ #
238
+ # return a random value from an array or range
239
+ #
240
+ def randomize(value)
241
+ case value
242
+ when Array then value[rand(value.size)]
243
+ when Range then rand((value.last + 1) - value.first) + value.first
244
+ else value
245
+ end
246
+ end
247
+ alias dm_randomize randomize
248
+
249
+ #
250
+ # return an element from the array. The first request will return
251
+ # the first element, the second request will return the second,
252
+ # and so forth.
253
+ #
254
+ def sequential(value)
255
+ index = index_variable_for(value)
256
+ index = (index ? index + 1 : 0)
257
+ index = 0 if index == value.length
258
+ set_index_variable(value, index)
259
+ value[index]
260
+ end
261
+
262
+ #
263
+ # return a value based on a mast
264
+ # The # character will be replaced with a number
265
+ # The A character will be replaced with an upper case letter
266
+ # The a character will be replaced with a lower case letter
267
+ #
268
+ def mask(value)
269
+ result = ''
270
+ value.each_char do |ch|
271
+ result += case ch
272
+ when '#' then randomize(0..9).to_s
273
+ when 'A' then ('A'..'Z').to_a[rand(26)]
274
+ when 'a' then ('a'..'z').to_a[rand(26)]
275
+ else ch
276
+ end
277
+ end
278
+ result
279
+ end
280
+ alias dm_mask mask
281
+
282
+ ##################################################################
283
+ # #
284
+ # NEW TRANSLATOR STARTS HERE #
285
+ # #
286
+ ##################################################################
287
+
288
+ #
289
+ # return a random color code in hex
290
+ #
291
+ def color_hex
292
+ Faker::Color.hex_color
293
+ end
294
+ alias dm_color_hex color_hex
295
+
296
+ #
297
+ # return a random color name
298
+ #
299
+ def color_name
300
+ Faker::Color.color_name
301
+ end
302
+ alias dm_color_name color_name
303
+
304
+ #
305
+ # return a random number in specified digits
306
+ #
307
+ def number(digits, leading_zero = false)
308
+ leading_zero ? Faker::Number.leading_zero_number(digits: digits) : Faker::Number.number(digits: digits)
309
+ end
310
+ alias dm_number number
311
+
312
+ #
313
+ # return a random number in decimal
314
+ #
315
+ def decimal(before_decimal, after_decimal = 2)
316
+ Faker::Number.decimal(l_digits: before_decimal, r_digits: after_decimal)
317
+ end
318
+ alias dm_decimal decimal
319
+
320
+ #
321
+ # merge variables
322
+ #
323
+ def merge(separator = ' ', *params)
324
+ params.join(separator)
325
+ end
326
+ alias dm_merge merge
327
+
328
+ ##################################################################
329
+ # #
330
+ # NEW TRANSLATOR ENDS HERE #
331
+ # #
332
+ ##################################################################
333
+
334
+ private
335
+
336
+ def set_index_variable(ary, value)
337
+ index_hash[index_name(ary)] = value
338
+ end
339
+
340
+ def index_variable_for(ary)
341
+ value = index_hash[index_name(ary)]
342
+ index_hash[index_name(ary)] = -1 unless value
343
+ index_hash[index_name(ary)]
344
+ end
345
+
346
+ def index_name(ary)
347
+ "#{ary[0]}#{ary[1]}_index".gsub(' ', '_').downcase
348
+ end
349
+
350
+ def index_hash
351
+ dh = data_hash[parent]
352
+ data_hash[parent] = {} unless dh
353
+ data_hash[parent]
354
+ end
355
+
356
+ def data_hash
357
+ $data_magic_data_hash ||= {}
358
+ end
359
+
360
+ def process(value)
361
+ eval value
362
+ end
363
+
364
+ def remove_extension(phone)
365
+ index = phone.index('x')
366
+ phone = phone[0, (index - 1)] if index
367
+ phone
368
+ end
369
+ end
370
+ end
@@ -0,0 +1,15 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'data_magic/date_translation'
4
+ require 'data_magic/standard_translation'
5
+
6
+ module DataMagic
7
+ class Translation
8
+ include StandardTranslation
9
+ include DateTranslation
10
+
11
+ def initialize(parent)
12
+ @parent = parent
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module DataMagic
4
+ VERSION = '1.2'
5
+ end
data/lib/data_magic.rb ADDED
@@ -0,0 +1,114 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'data_magic/core_ext/string'
4
+ require 'data_magic/core_ext/integer'
5
+ require 'data_magic/core_ext/hash'
6
+ require 'data_magic/version'
7
+ require 'data_magic/translation'
8
+ require 'data_magic/date_translation'
9
+ require 'data_magic/standard_translation'
10
+ require 'yml_reader'
11
+ require 'faker'
12
+ require 'byebug'
13
+
14
+ module DataMagic
15
+ extend YmlReader
16
+ extend StandardTranslation
17
+ extend DateTranslation
18
+
19
+ attr_reader :parent
20
+
21
+ I18n.enforce_available_locales = false if I18n.respond_to? :enforce_available_locales
22
+
23
+ def self.locale=(value)
24
+ Faker::Config.locale = value
25
+ end
26
+
27
+ def self.included(cls)
28
+ @parent = cls
29
+ translators.each do |translator|
30
+ Translation.send :include, translator
31
+ end
32
+ end
33
+
34
+ def data_for(key, additional = {})
35
+ if key.is_a?(String) && key.match(%r{/})
36
+ filename, record = key.split('/')
37
+ DataMagic.load("#{filename}.yml")
38
+ else
39
+ record = key.to_s
40
+ DataMagic.load(the_file) unless DataMagic.yml
41
+ end
42
+ data = DataMagic.yml[record]
43
+ raise ArgumentError, "Undefined key #{key}" unless data
44
+
45
+ prep_data(data.merge(additional.key?(record) ? additional[record] : additional).deep_copy)
46
+ end
47
+
48
+ # Given a scenario, load any fixture it needs.
49
+ # Fixture tags should be in the form of @datamagic_FIXTUREFILE
50
+ def self.load_for_scenario(scenario, fixture_folder = DataMagic.yml_directory)
51
+ orig_yml_directory = DataMagic.yml_directory
52
+ DataMagic.yml_directory = fixture_folder
53
+ fixture_files = fixture_files_on(scenario)
54
+
55
+ DataMagic.load "#{fixture_files.last}.yml" if fixture_files.count.positive?
56
+ DataMagic.yml_directory = orig_yml_directory
57
+ end
58
+
59
+ private_class_method
60
+
61
+ def the_file
62
+ ENV['DATA_MAGIC_FILE'] || 'default.yml'
63
+ end
64
+
65
+ def prep_data(data)
66
+ case data
67
+ when Hash
68
+ data.each { |key, value| data[key] = prep_data(value) }
69
+ when Array
70
+ data.each_with_index { |value, i| data[i] = prep_data(value) }
71
+ when String
72
+ return translate(data[1..-1]) if data[0, 1] == '~'
73
+ end
74
+ data
75
+ end
76
+
77
+ def translate(value)
78
+ translation.send :process, value
79
+ rescue StandardError => e
80
+ raise "Failed to translate: #{value}\n Reason: #{e.message}\n"
81
+ end
82
+
83
+ def translation
84
+ @translation ||= Translation.new parent
85
+ end
86
+
87
+ # Load a fixture and merge it with an existing hash
88
+ def self.load_fixture_and_merge_with(fixture_name, base_hash, fixture_folder = DEFAULT_FIXTURE_FOLDER)
89
+ new_hash = load_fixture(fixture_name, fixture_folder)
90
+ base_hash.deep_merge new_hash
91
+ end
92
+
93
+ def self.fixture_files_on(scenario)
94
+ # tags for cuke 2, source_tags for cuke 1
95
+ tags = scenario.send(scenario.respond_to?(:tags) ? :tags : :source_tags)
96
+ tags.map(&:name).select { |t| t =~ /@datamagic_/ }.map { |t| t.gsub('@datamagic_', '').to_sym }
97
+ end
98
+
99
+ class << self
100
+ attr_accessor :yml
101
+
102
+ def default_directory
103
+ 'config/data'
104
+ end
105
+
106
+ def add_translator(translator)
107
+ translators << translator
108
+ end
109
+
110
+ def translators
111
+ @translators ||= []
112
+ end
113
+ end
114
+ end