eco-helpers 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +1 -0
  3. data/.rspec +3 -0
  4. data/README.md +20 -0
  5. data/eco-helpers.gemspec +34 -0
  6. data/lib/eco-helpers.rb +15 -0
  7. data/lib/eco/api.rb +13 -0
  8. data/lib/eco/api/common.rb +10 -0
  9. data/lib/eco/api/common/people.rb +17 -0
  10. data/lib/eco/api/common/people/base_parser.rb +16 -0
  11. data/lib/eco/api/common/people/default_parsers.rb +40 -0
  12. data/lib/eco/api/common/people/default_parsers/boolean_parser.rb +28 -0
  13. data/lib/eco/api/common/people/default_parsers/date_parser.rb +33 -0
  14. data/lib/eco/api/common/people/default_parsers/multi_parser.rb +33 -0
  15. data/lib/eco/api/common/people/default_parsers/numeric_parser.rb +23 -0
  16. data/lib/eco/api/common/people/default_parsers/select_parser.rb +29 -0
  17. data/lib/eco/api/common/people/entries.rb +120 -0
  18. data/lib/eco/api/common/people/person_entry.rb +380 -0
  19. data/lib/eco/api/common/people/person_factory.rb +114 -0
  20. data/lib/eco/api/common/people/person_modifier.rb +62 -0
  21. data/lib/eco/api/common/people/person_parser.rb +140 -0
  22. data/lib/eco/api/common/people/types.rb +47 -0
  23. data/lib/eco/api/common/session.rb +15 -0
  24. data/lib/eco/api/common/session/base_session.rb +46 -0
  25. data/lib/eco/api/common/session/environment.rb +47 -0
  26. data/lib/eco/api/common/session/file_manager.rb +90 -0
  27. data/lib/eco/api/common/session/logger.rb +105 -0
  28. data/lib/eco/api/common/session/mailer.rb +92 -0
  29. data/lib/eco/api/common/session/s3_uploader.rb +110 -0
  30. data/lib/eco/api/common/version_patches.rb +11 -0
  31. data/lib/eco/api/common/version_patches/external_person.rb +11 -0
  32. data/lib/eco/api/eco_faker.rb +59 -0
  33. data/lib/eco/api/organization.rb +13 -0
  34. data/lib/eco/api/organization/account.rb +23 -0
  35. data/lib/eco/api/organization/people.rb +118 -0
  36. data/lib/eco/api/organization/policy_groups.rb +51 -0
  37. data/lib/eco/api/organization/preferences.rb +28 -0
  38. data/lib/eco/api/organization/preferences_reference.json +23 -0
  39. data/lib/eco/api/organization/presets.rb +138 -0
  40. data/lib/eco/api/organization/presets_backup.rb +220 -0
  41. data/lib/eco/api/organization/presets_values.json +10 -0
  42. data/lib/eco/api/organization/tag_tree.rb +134 -0
  43. data/lib/eco/api/organization_old.rb +73 -0
  44. data/lib/eco/api/session.rb +180 -0
  45. data/lib/eco/api/session/batch.rb +132 -0
  46. data/lib/eco/api/session/batch_job.rb +152 -0
  47. data/lib/eco/api/session/batch_jobs.rb +131 -0
  48. data/lib/eco/api/session/batch_status.rb +138 -0
  49. data/lib/eco/api/session/task.rb +92 -0
  50. data/lib/eco/api/session_config.rb +179 -0
  51. data/lib/eco/api/session_config/api.rb +47 -0
  52. data/lib/eco/api/session_config/apis.rb +78 -0
  53. data/lib/eco/api/session_config/files.rb +30 -0
  54. data/lib/eco/api/session_config/logger.rb +54 -0
  55. data/lib/eco/api/session_config/mailer.rb +65 -0
  56. data/lib/eco/api/session_config/people.rb +89 -0
  57. data/lib/eco/api/session_config/s3_bucket.rb +62 -0
  58. data/lib/eco/api/session_config/use_cases.rb +30 -0
  59. data/lib/eco/api/usecases.rb +12 -0
  60. data/lib/eco/api/usecases/base_case.rb +14 -0
  61. data/lib/eco/api/usecases/case_data.rb +13 -0
  62. data/lib/eco/api/usecases/default_cases.rb +53 -0
  63. data/lib/eco/api/usecases/default_cases/change_email_case.rb +47 -0
  64. data/lib/eco/api/usecases/default_cases/create_details_case.rb +29 -0
  65. data/lib/eco/api/usecases/default_cases/create_details_with_supervisor_case.rb +49 -0
  66. data/lib/eco/api/usecases/default_cases/delete_case.rb +20 -0
  67. data/lib/eco/api/usecases/default_cases/email_as_id_case.rb +24 -0
  68. data/lib/eco/api/usecases/default_cases/hris_case.rb +67 -0
  69. data/lib/eco/api/usecases/default_cases/new_email_case.rb +26 -0
  70. data/lib/eco/api/usecases/default_cases/new_id_case.rb +26 -0
  71. data/lib/eco/api/usecases/default_cases/refresh_presets.rb +25 -0
  72. data/lib/eco/api/usecases/default_cases/reinvite_case.rb +22 -0
  73. data/lib/eco/api/usecases/default_cases/remove_account_case.rb +36 -0
  74. data/lib/eco/api/usecases/default_cases/reset_landing_page_case.rb +24 -0
  75. data/lib/eco/api/usecases/default_cases/set_default_tag_case.rb +44 -0
  76. data/lib/eco/api/usecases/default_cases/set_supervisor_case.rb +39 -0
  77. data/lib/eco/api/usecases/default_cases/to_csv_case.rb +36 -0
  78. data/lib/eco/api/usecases/default_cases/update_details_case.rb +30 -0
  79. data/lib/eco/api/usecases/default_cases/upsert_account_case.rb +35 -0
  80. data/lib/eco/api/usecases/use_case.rb +177 -0
  81. data/lib/eco/api/usecases/use_group.rb +104 -0
  82. data/lib/eco/cli.rb +9 -0
  83. data/lib/eco/cli/input.rb +109 -0
  84. data/lib/eco/cli/input_multi.rb +137 -0
  85. data/lib/eco/cli/root.rb +8 -0
  86. data/lib/eco/cli/session.rb +9 -0
  87. data/lib/eco/cli/session/batch.rb +9 -0
  88. data/lib/eco/common.rb +7 -0
  89. data/lib/eco/common/base_cli.rb +116 -0
  90. data/lib/eco/common/language.rb +9 -0
  91. data/lib/eco/data.rb +9 -0
  92. data/lib/eco/data/crypto.rb +7 -0
  93. data/lib/eco/data/crypto/encryption.rb +318 -0
  94. data/lib/eco/data/files.rb +10 -0
  95. data/lib/eco/data/files/directory.rb +93 -0
  96. data/lib/eco/data/files/file_pattern.rb +32 -0
  97. data/lib/eco/data/files/helpers.rb +90 -0
  98. data/lib/eco/data/mapper.rb +54 -0
  99. data/lib/eco/data/random.rb +10 -0
  100. data/lib/eco/data/random/distribution.rb +133 -0
  101. data/lib/eco/data/random/fake.rb +320 -0
  102. data/lib/eco/data/random/values.rb +80 -0
  103. data/lib/eco/language.rb +12 -0
  104. data/lib/eco/language/curry.rb +28 -0
  105. data/lib/eco/language/hash_transform.rb +68 -0
  106. data/lib/eco/language/hash_transform_modifier.rb +114 -0
  107. data/lib/eco/language/match.rb +30 -0
  108. data/lib/eco/language/match_modifier.rb +190 -0
  109. data/lib/eco/language/models.rb +11 -0
  110. data/lib/eco/language/models/attribute_parser.rb +38 -0
  111. data/lib/eco/language/models/collection.rb +181 -0
  112. data/lib/eco/language/models/modifier.rb +68 -0
  113. data/lib/eco/language/models/wrap.rb +114 -0
  114. data/lib/eco/language/values_at.rb +159 -0
  115. data/lib/eco/lexic/dictionary.rb +33 -0
  116. data/lib/eco/lexic/dictionary/dictionary.txt +355484 -0
  117. data/lib/eco/lexic/dictionary/tags.json +38 -0
  118. data/lib/eco/scripting.rb +30 -0
  119. data/lib/eco/scripting/README.md +11 -0
  120. data/lib/eco/scripting/arguments.rb +40 -0
  121. data/lib/eco/tester.rb +97 -0
  122. data/lib/eco/version.rb +3 -0
  123. metadata +325 -0
@@ -0,0 +1,32 @@
1
+ module Eco
2
+ module Data
3
+ module Files
4
+ class FilePattern
5
+ def initialize(file = "")
6
+ @source_file = file
7
+ end
8
+
9
+ def resolve(dir: nil, start: "")
10
+ pattern(dir).gsub('*', start)
11
+ end
12
+
13
+ def match?(file, dir: nil)
14
+ /#{Regexp.escape(self.pattern(dir))}/i.match?(file)
15
+ end
16
+
17
+ def any?(files, dir: nil)
18
+ return false unless files.is_a?(Array)
19
+ files.any? { |file| match?(file, dir: dir) }
20
+ end
21
+
22
+ def pattern(dir = nil)
23
+ return File.join(dir, "*") if @source_file.to_s.empty?
24
+ filename = File.basename(@source_file)
25
+ path = File.dirname(@source_file)
26
+ path = File.join(dir, path) if dir
27
+ File.join(path, "*" + filename)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,90 @@
1
+ module Eco
2
+ module Data
3
+ module Files
4
+ DEFAULT_TIMESTAMP_PATTERN = '%Y-%m-%dT%H%M%S'
5
+
6
+ def self.included(base)
7
+ base.send(:include, InstanceMethods)
8
+ base.extend(ClassMethods)
9
+ end
10
+
11
+ module InstanceMethods
12
+
13
+ end
14
+
15
+ module ClassMethods
16
+ def create_directory(path, includes_file: false)
17
+ Directory.create(path, includes_file: includes_file)
18
+ end
19
+
20
+ def split(path)
21
+ dir_path, file = File.split(path)
22
+ dir_path = dir_path.gsub(File::SEPARATOR, File::ALT_SEPARATOR || File::SEPARATOR)
23
+ dir_path.split(File::ALT_SEPARATOR || File::SEPARATOR).push(file)
24
+ end
25
+
26
+ def file_name(fullname)
27
+ File.basename(fullname)
28
+ end
29
+
30
+ def file_basename(fullname)
31
+ File.basename(fullname, File.extname(fullname))
32
+ end
33
+
34
+ def file_path(fullname)
35
+ File.dirname(fullname)
36
+ end
37
+
38
+ def file_fullpath(fullname)
39
+ file_path(File.expand_path(fullname))
40
+ end
41
+
42
+ def file_exists?(file)
43
+ return false if !file
44
+ return File.exists?(file) || File.exists?(File.expand_path(file))
45
+ end
46
+
47
+ def dir_exists?(path)
48
+ Dir.exist?(path) || Dir.exist?(File.expand_path(path))
49
+ end
50
+
51
+ def timestamp(timestamp_pattern = DEFAULT_TIMESTAMP_PATTERN)
52
+ Time.now.strftime(timestamp_pattern)
53
+ end
54
+
55
+ def timestamp_file(filename, timestamp_pattern = DEFAULT_TIMESTAMP_PATTERN)
56
+ file_pattern = Eco::Data::Files::FilePattern.new(filename)
57
+ file_pattern.resolve(start: timestamp(timestamp_pattern) + '_')
58
+ end
59
+
60
+ def copy_file(source_file, dest_file, time_stamp: false)
61
+ dest_file = timestamp_file(dest_file) if time_stamp
62
+ File.write(dest_file, File.read(source_file))
63
+ end
64
+
65
+ def has_bom?(path)
66
+ return false if !path
67
+ File.open(path, "rb") do |f|
68
+ bytes = f.read(3)
69
+ return bytes.unpack("C*") == [239, 187, 191]
70
+ end
71
+ end
72
+
73
+ def encoding(path)
74
+ has_bom?(path) ? "bom|utf-8" : "utf-8"
75
+ end
76
+
77
+ def script_subfolder
78
+ basename = File.basename($0, File.extname($0))
79
+ path = File.dirname($0)
80
+ File.join(path, basename)
81
+ end
82
+ end
83
+
84
+ class << self
85
+ include Files::ClassMethods
86
+ end
87
+
88
+ end
89
+ end
90
+ end
@@ -0,0 +1,54 @@
1
+ module Eco
2
+ module Data
3
+ class Mapper
4
+
5
+ # it expects [[v1a, v1b], [v2a, v2b] ...]
6
+ def initialize (array_of_arrays = [], internal: :last)
7
+ @source = array_of_arrays
8
+
9
+ if @source
10
+ @source = @source.map { |a| a.reverse } unless internal == :last
11
+
12
+ # first declarations take priority
13
+ @by_external = @source.reverse.to_h
14
+ @by_internal = @source.reverse.map do |pair|
15
+ pair.reverse
16
+ end.to_h
17
+ end
18
+ end
19
+
20
+ def list(type = :internal)
21
+ return [] if !@source
22
+ @source.map do |pair|
23
+ type == :internal ? pair.first : pair.last
24
+ end.uniq
25
+ end
26
+
27
+ def internal?(value)
28
+ return true if !@source
29
+ @by_internal.key?(value)
30
+ end
31
+
32
+ def external?(value)
33
+ return true if !@source
34
+ @by_external.key?(value)
35
+ end
36
+
37
+ def include?(value)
38
+ return true if !@source
39
+ internal?(value) || external?(value)
40
+ end
41
+
42
+ def to_internal(value)
43
+ return value if !@source
44
+ @by_external[value]
45
+ end
46
+
47
+ def to_external(value)
48
+ return value if !@source
49
+ @by_internal[value]
50
+ end
51
+
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,10 @@
1
+ module Eco
2
+ module Data
3
+ module Random
4
+ end
5
+ end
6
+ end
7
+
8
+ require_relative 'random/distribution'
9
+ require_relative 'random/values'
10
+ require_relative 'random/fake'
@@ -0,0 +1,133 @@
1
+ require 'distribution' # source: https://github.com/sciruby/distribution
2
+
3
+ # todo: remove distribution dependency by developing a normal distribution generator
4
+ # - Reference: https://stackoverflow.com/a/6178290/4352306
5
+
6
+ module Eco
7
+ module Data
8
+ module Random
9
+ class Distribution
10
+
11
+ MAX_DECIMALS = 10
12
+ BALANCE = ["uniform", "normal", "half-normal", "forged"]
13
+
14
+ attr_accessor :decimals
15
+ attr_reader :calls
16
+ attr_reader :range, :min, :max, :balance, :mean, :sigma
17
+ attr_reader :weights, :weights_distribution
18
+ def initialize(init = {})
19
+ @calls = 0
20
+ @weight_positions = 0
21
+
22
+ @decimals = init.fetch('decimals', MAX_DECIMALS)
23
+ self.range = init.fetch('range', 0..1)
24
+ self.weights = init.fetch('weights', nil)
25
+ self.balance = init.fetch('balance', nil)
26
+
27
+ @normal = ::Distribution::Normal.rng(@mean, @sigma)
28
+ @random = ::Random.new
29
+ end
30
+
31
+ def balance=(value)
32
+ @balance = value
33
+ @balance = BALANCE[0] if !BALANCE.include?(@balance)
34
+ case @balance
35
+ when 'forged'
36
+ if @weights&.instance_of?(Array)
37
+ top = @weights.length - 1
38
+ self.range = (0..top)
39
+ end
40
+ end
41
+ end
42
+
43
+ def range=(value)
44
+ @range = value
45
+ @min = @range.first; @max = @range.last
46
+ @mean = @max / 2
47
+ @sigma = (@max - @mean) / 3.5
48
+ end
49
+
50
+ def weights=(value)
51
+ @weights = nil; @weights_distribution = nil; @weight_positions = 0
52
+ @weights = value if value && value.instance_of?(Array)
53
+ if @weights
54
+ total = @weights.inject(0, :+)
55
+ @weight_positions = total * 20
56
+ @weights_distribution = Array.new(@weight_positions)
57
+
58
+ i = 0; j = 0
59
+ while i < @weights.length
60
+ positions = (@weights[i] * @weight_positions / total).round
61
+ positions.times do
62
+ @weights_distribution[j] = i
63
+ j += 1
64
+ end
65
+ i += 1
66
+ end
67
+ if (missing = @weight_positions - j) >= 0
68
+ (missing + 1).times {
69
+ @weights_distribution[j] = 0
70
+ j += 1
71
+ }
72
+ end
73
+ end
74
+ end
75
+
76
+ def generate
77
+ @calls += 1
78
+ case @balance
79
+ when 'uniform'
80
+ num = generate_uniform
81
+ when 'normal'
82
+ num = generate_normal
83
+ when 'half-normal'
84
+ num = generate_half_normal
85
+ when 'forged'
86
+ num = generate_forged
87
+ else
88
+ num = generate_uniform
89
+ end
90
+
91
+ num = generate if num && !@range.member?(num.round)
92
+ return num && num.round(@decimals)
93
+ end
94
+
95
+ private
96
+
97
+ def generate_uniform
98
+ @random.rand(@range)
99
+ end
100
+
101
+ def generate_normal
102
+ @normal.call
103
+ end
104
+
105
+ def generate_half_normal
106
+ num = generate_normal
107
+ num = normal_mirror(num, @mean) if num.round < @mean
108
+ num = generate_half_normal if num.round == @mean
109
+ num -= @mean
110
+ num = num - 1 if num.round > 0 # move distribution to left (mirroring doubles density except at mean)
111
+ return num
112
+ end
113
+
114
+ def generate_forged
115
+ #raise "You need to assign weights to be able to use the forge balance!" if !@weights_distribution&.instance_of?(Array)
116
+ if @weights_distribution&.instance_of?(Array)
117
+ top = @weight_positions - 1
118
+ pos = @random.rand(0..top)
119
+ return weights_distribution[pos]
120
+ end
121
+ return generate_normal # should raise error at the beginning of the function
122
+ end
123
+
124
+ def normal_mirror (num, mean)
125
+ return mean + (mean - num) if num.round < mean
126
+ return mean - (num - mean) if num.round > mean
127
+ return num
128
+ end
129
+
130
+ end
131
+ end
132
+ end
133
+ end
@@ -0,0 +1,320 @@
1
+ require 'faker'
2
+
3
+ module Eco
4
+ module Data
5
+ module Random
6
+ class Fake
7
+
8
+ MAX_UNIQUE_ERRORS = 13
9
+ DEFAULT_LOCALE = 'en'
10
+ DEFAULT_EMAIL_PATTERN = 'oscar+name@ecoportal.co.nz'
11
+ LOCALES_MAPS = {'en' => 'en', 'nz' => 'en-NZ', 'ca' => 'en-CA', 'uk' => 'en-GB', 'usa' => 'en-USA'}
12
+ TOPICS_MAPS = {
13
+ 'general' => ['General', 'Vehicle', 'University', 'Address'],
14
+ 'fantasy' => ['LordOfTheRings', 'Hobbit', 'HarryPotter', 'BackToTheFuture', 'FunnyName', 'GameOfThrones', 'PricesBride', 'StarWars', 'StarkTrek'],
15
+ 'medieval-fantasy' => ['LordOfTheRings', 'Hobbit', 'GameOfThrones', 'PricesBride'],
16
+ 'futuristic-fantasy' => ['BackToTheFuture', 'StarWars', 'StarTrek'],
17
+ 'tolkien' => ['LordOfTheRings', 'Hobbit'],
18
+ 'funny' => ['FunnyName', 'Simpsons', 'Superhero'],
19
+ 'famous' => ['Book', 'GreekPhilosophers' ,'Scientists', 'SiliconValley', 'Space', 'WorldCup'],
20
+ 'philosophers' => 'GreekPhilosophers'
21
+ }
22
+ @name = nil; @name_topics = nil
23
+ @location = nil; @location_topics = nil
24
+
25
+ attr_reader :local, :topic, :general_topic_on_fail
26
+ attr_reader :today, :email_pattern, :unique_errors, :unique_resets, :force_unique
27
+
28
+ def initialize(init = {})
29
+ @unique_resets = 0; @unique_errors = 0
30
+ init_topics
31
+ self.topic = init.fetch('topic', TOPICS_MAPS.keys.sample)
32
+ self.general_topic_on_fail = init.fetch('general_topic_on_fail', false)
33
+ self.force_unique = init.fetch('force_unique', false)
34
+
35
+ self.local = init.fetch('local', nil)
36
+ self.today = init.fetch('today', Date.today)
37
+ self.email_pattern = init.fetch('email_pattern', DEFAULT_EMAIL_PATTERN)
38
+
39
+ @boolean = Faker::Boolean.method('boolean')
40
+ @date_between = Faker::Date.method('between')
41
+
42
+ @gender = Faker::Gender.method('binary_type')
43
+
44
+ @name = get_topic_wrapper(@name_topics)
45
+ @company = get_topic_wrapper(@company_topics)
46
+ @location = get_topic_wrapper(@location_topics)
47
+
48
+ @community = wrap_method { Faker::Address.community }
49
+ @address = wrap_method { Faker::Address.unique.full_address }
50
+ @country = wrap_method { Faker::Address.country }
51
+ @city = wrap_method { Faker::Address.city }
52
+ @postcode = wrap_method { Faker::Address.postcode }
53
+ @timezone = Faker::Address.method('time_zone')
54
+
55
+ @phone = wrap_method { Faker::PhoneNumber.unique.phone_number }
56
+ @mobile = wrap_method { Faker::PhoneNumber.unique.cell_phone }
57
+ @mobile_code = wrap_method { Faker::Code.unique.imei }
58
+ end
59
+
60
+ def topic=(value)
61
+ @topic = TOPICS_MAPS.values.first # 'General'
62
+ @topic = TOPICS_MAPS[value.downcase] if value && TOPICS_MAPS.keys.include?(value.downcase)
63
+ init_topic_wrappers
64
+ end
65
+
66
+ def general_topic_on_fail=(value)
67
+ @general_topic_on_fail = value
68
+ end
69
+
70
+ def today=(value)
71
+ @today = nil
72
+ @today = value if value.instance_of?(Date)
73
+ @today = Date.today if !@today
74
+ end
75
+
76
+ def email_pattern=(value)
77
+ @email_pattern = value
78
+ @email_pattern = DEFAULT_EMAIL_PATTERN if !@mail_pattern&.include?('@ecoportal.co.nz')
79
+ end
80
+
81
+ def local=(value)
82
+ @local = DEFAULT_LOCALE
83
+ alias_locales = LOCALES_MAPS.keys; locales = LOCALES_MAPS.values
84
+ permitted = value && (alias_locales.include?(value.downcase) || locales.include?(value))
85
+ @local = LOCALES_MAPS[value.downcase] if permitted
86
+ ::Faker::Config.locale = @local
87
+ end
88
+
89
+ def force_unique=(value)
90
+ @force_unique = !!value
91
+ end
92
+
93
+ def reset_unique
94
+ @unique_errors = 0
95
+ @unique_resets += 1
96
+ ::Faker::UniqueGenerator.clear
97
+ end
98
+
99
+ def boolean
100
+ @boolean.call
101
+ end
102
+
103
+ def past_date(years = 3)
104
+ @date_between.call(previous_date(years), @today)
105
+ end
106
+
107
+ def future_date(years = 3)
108
+ @date_between.call(@today, later_date(years))
109
+ end
110
+
111
+ def birthday(min_age = 18, max_age = 65)
112
+ @date_between.call(previous_date(min_age), previous_date(max_age))
113
+ end
114
+
115
+ def name
116
+ new_value = get_unique(@name, @name_topics)
117
+ @name = get_topic_wrapper(@name_topics)
118
+ return new_value
119
+ end
120
+
121
+ def company
122
+ new_value = get_unique(@company, @company_topics)
123
+ @company = get_topic_wrapper(@company_topics)
124
+ return new_value
125
+ end
126
+
127
+ def community
128
+ @community.call
129
+ end
130
+
131
+ def location
132
+ new_value = get_unique(@location, @location_topics)
133
+ @location = get_topic_wrapper(@location_topics)
134
+ return new_value
135
+ end
136
+
137
+ def address
138
+ @address.call
139
+ end
140
+
141
+ def contry
142
+ @country.call
143
+ end
144
+
145
+ def city
146
+ @city.call
147
+ end
148
+
149
+ def postcode
150
+ @postcode.call
151
+ end
152
+
153
+ def timezone
154
+ @timezone.call
155
+ end
156
+
157
+ def gender
158
+ @geneder.call
159
+ end
160
+
161
+ def email(str_name = nil)
162
+ str_name = self.name if !str_name&.strip
163
+ @email_pattern.gsub('name', email_encode(str_name))
164
+ end
165
+
166
+ def phone
167
+ @phone.call
168
+ end
169
+
170
+ def mobile
171
+ @mobile.call
172
+ end
173
+
174
+ def mobile_code
175
+ @mobile_code.call
176
+ end
177
+
178
+ private
179
+
180
+ def unique_error_count
181
+ @unique_errors += 1
182
+ unique_overflow = @unique_errors > MAX_UNIQUE_ERRORS
183
+ err_msg = "Error uniqueness broken"
184
+ raise Faker::UniqueGenerator::RetryLimitExceeded.new(err_msg), err_msg if self.force_unique && unique_overflow
185
+ self.reset_unique if unique_overflow
186
+ end
187
+
188
+ def previous_date(years = 3)
189
+ @today - (years * 365)
190
+ end
191
+
192
+ def later_date(years = 3)
193
+ @today + (years * 365)
194
+ end
195
+
196
+ def init_topics
197
+ @name_topics = {
198
+ 'General' => wrap_method { Faker::Name.unique.name },
199
+ 'LordOfTheRings' => wrap_method { Faker::LordOfTheRings.unique.character },
200
+ 'Hobbit' => wrap_method { Faker::Hobbit.unique.character },
201
+ 'BackToTheFuture' => wrap_method { Faker::BackToTheFuture.unique.character },
202
+ 'HarryPotter' => wrap_method { Faker::HarryPotter.unique.character },
203
+ 'GameOfThrones' => wrap_method { Faker::GameOfThrones.unique.character },
204
+ 'PrincesBride' => wrap_method { Faker::PrincesBride.unique.character },
205
+ 'StarWars' => wrap_method { Faker::StarWars.unique.character },
206
+ 'StarTrek' => wrap_method { Faker::StarTrek.unique.character },
207
+ 'Simpsons' => wrap_method { Faker::Simpsons.unique.character },
208
+ 'Superhero' => wrap_method { Faker::Superhero.unique.name },
209
+ 'FunnyName' => wrap_method { Faker::FunnyName.unique.name },
210
+ 'Book' => wrap_method { Faker::Book.unique.author },
211
+ 'GreekPhilosophers' => wrap_method { Faker::GreekPhilosophers.unique.name },
212
+ 'Scientists' => wrap_method { Faker::Science.unique.scientist },
213
+ 'SiliconValley' => wrap_method { Faker::SiliconValley.unique.character },
214
+ 'WorldCup' => wrap_method { Faker::WorldCup.unique.roster }
215
+ }
216
+
217
+ @location_topics = {
218
+ 'General' => wrap_method { Faker::Nation.capital_city },
219
+ 'LordOfTheRings' => wrap_method { Faker::LordOfTheRings.location },
220
+ 'Hobbit' => wrap_method { Faker::Hobbit.location },
221
+ 'HarryPotter' => wrap_method { Faker::HarryPotter.location },
222
+ 'GameOfThrones' => wrap_method { Faker::GameOfThrones.city },
223
+ 'Simpsons' => wrap_method { Faker::Simpsons.location },
224
+ 'StarTrek' => wrap_method { Faker::StarTrek.location },
225
+ 'WorldCup' => wrap_method { Faker::WorldCup.city },
226
+ 'University' => wrap_method { Faker::University.name },
227
+ 'Address' => wrap_method { Faker::Address.city }
228
+ }
229
+
230
+ @company_topics = {
231
+ 'General' => wrap_method { Faker::Company.name },
232
+ 'Vehicle' => wrap_method { Faker::Vehicle.manufacture },
233
+ 'SiliconValley' => wrap_method { Faker::SiliconValley.company },
234
+ 'Space' => wrap_method { Faker::Space.company }
235
+ }
236
+
237
+ @deparment_topics = {
238
+ 'General' => wrap_method { Faker::Commerce.department }
239
+ }
240
+ end
241
+
242
+ def init_topic_wrappers
243
+ @name = get_topic_wrapper(@name_topics)
244
+ @location = get_topic_wrapper(@location_topics)
245
+ end
246
+
247
+ def get_topic_wrapper(type_topics)
248
+ all_topics = @topic.instance_of?(Array)? @topic : [@topic]
249
+ topics = filter_by_key(type_topics, all_topics)
250
+ failed_topic = !@topic || !topics || topics.values.length < 1
251
+
252
+ if !failed_topic
253
+ topic = topics.values.sample
254
+ #puts "\"Custom!!!!\""
255
+ else
256
+ if @general_topic_on_fail
257
+ topic = type_topics.fetch('General', nil)
258
+ #puts "\"Genearal!!!!\""
259
+ else
260
+ topic = type_topics.values.sample
261
+ #puts "\"Force Random!!!!\""
262
+ end
263
+ end
264
+ return topic
265
+ end
266
+
267
+ def get_unique(wrapper, related_topics)
268
+ begin
269
+ new_value = wrapper.call
270
+ rescue Faker::UniqueGenerator::RetryLimitExceeded
271
+ unique_error_count
272
+ wrapper = get_topic_wrapper(related_topics)
273
+ new_value = get_unique(wrapper, related_topics)
274
+ end
275
+ return new_value
276
+ end
277
+
278
+ def filter_by_key (hash, keys)
279
+ hash.select { |k,v| keys.include?(k) }
280
+ end
281
+
282
+ # should allow different topics
283
+ def email_encode(str)
284
+ return nil if !str.is_a?(String)
285
+ return str.gsub(/\s+/,"_")&.gsub(/\W/,"")&.slice(0,25).downcase
286
+ end
287
+
288
+ def wrap_method(&block)
289
+ block
290
+ end
291
+
292
+ def self.test(test_times = 500, fantasy: true, force_unique: false)
293
+ pp "########## Testing Faker wrapper ###########"
294
+ topic = if fantasy then 'fantasy' else nil end
295
+ faker = self.new({
296
+ 'today' => Date.new(2018,1,1),
297
+ 'locale' => 'nz',
298
+ 'topic' => topic,
299
+ 'general_topic_on_fail' => true,
300
+ 'force_unique' => force_unique
301
+ })
302
+ begin
303
+ items = 0
304
+ test_times.times {
305
+ pp "#{name=faker.name} - #{faker.birthday(20, 40).to_s} : #{faker.mobile} : #{faker.email(name)}" + \
306
+ " : #{faker.location} : #{faker.company} : #{faker.community}"
307
+ items += 1
308
+ }
309
+ rescue ::Faker::UniqueGenerator::RetryLimitExceeded => e
310
+ puts "### Error: #{e.message} ###"
311
+ end
312
+ puts "total generated: #{items}"
313
+ puts "locale: #{faker.local}; topic: #{topic}"
314
+ puts "unique errors: #{faker.unique_errors} & #{faker.unique_resets} resets"
315
+ end
316
+
317
+ end
318
+ end
319
+ end
320
+ end