synthra 0.1.0
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.
- checksums.yaml +7 -0
- data/.rspec +4 -0
- data/.rubocop.yml +40 -0
- data/.yardopts +18 -0
- data/ACCESS_DOCS.md +116 -0
- data/ADVANCED_FEATURES_SUMMARY.md +245 -0
- data/CHANGELOG.md +498 -0
- data/CODE_OF_CONDUCT.md +122 -0
- data/CONTRIBUTING.md +307 -0
- data/DOCUMENTATION.md +204 -0
- data/DOCUMENTATION_GUIDE.md +194 -0
- data/LICENSE +22 -0
- data/README.md +1458 -0
- data/Rakefile +128 -0
- data/benchmark/README.md +591 -0
- data/benchmark/batch_generation.rb +63 -0
- data/benchmark/engine_comparison.rb +295 -0
- data/benchmark/single_record.rb +108 -0
- data/benchmark/streaming.rb +74 -0
- data/docs/ACTIVERECORD_INFERENCE.md +524 -0
- data/docs/API_SERVER.md +278 -0
- data/docs/CONFIG_FILE.md +315 -0
- data/docs/DATA_CONTRACTS.md +312 -0
- data/docs/ENHANCED_REPL.md +304 -0
- data/docs/FACTORY_BOT.md +271 -0
- data/docs/GITHUB_ACTION.md +420 -0
- data/docs/GRAPHQL_EXPORT.md +303 -0
- data/docs/GRAPHQL_FEDERATION.md +651 -0
- data/docs/HOW_TO_GENERATE_DOCS.md +252 -0
- data/docs/LSP.md +189 -0
- data/docs/MIGRATION_GENERATOR.md +547 -0
- data/docs/MOCK_SERVER.md +280 -0
- data/docs/NATIVE_ENGINE.md +298 -0
- data/docs/OPENAPI_EXPORT.md +252 -0
- data/docs/PERFORMANCE_MODE.md +228 -0
- data/docs/PERSONAS.md +547 -0
- data/docs/PROPERTY_TESTING.md +284 -0
- data/docs/PROTOBUF_EXPORT.md +276 -0
- data/docs/QUALITY_METRICS.md +555 -0
- data/docs/QUICK_REFERENCE.md +88 -0
- data/docs/RAILS_ENGINE.md +404 -0
- data/docs/RAILS_INTEGRATION.md +454 -0
- data/docs/README.md +175 -0
- data/docs/REPL_QUICK_REFERENCE.md +149 -0
- data/docs/RUST_INTEGRATION_GUIDE.md +1376 -0
- data/docs/SCENARIOS.md +576 -0
- data/docs/SECURITY_TESTING.md +318 -0
- data/docs/SNAPSHOT_TESTING.md +308 -0
- data/docs/STRING_TEXT_TYPES_REFERENCE.md +512 -0
- data/docs/TERRAFORM_EXPORT.md +447 -0
- data/docs/TIME_TRAVEL.md +507 -0
- data/docs/USAGE_GUIDE.md +980 -0
- data/docs/WEBHOOK_SIMULATOR.md +579 -0
- data/docs/advanced_features.md +183 -0
- data/docs/api_reference.md +153 -0
- data/docs/behaviors.md +138 -0
- data/docs/best_practices.md +191 -0
- data/docs/dsl_reference.md +172 -0
- data/docs/examples.md +162 -0
- data/docs/generation_modes.md +125 -0
- data/docs/getting_started.md +92 -0
- data/docs/index.html +177 -0
- data/docs/strategic/CLOUD_REGISTRY_ARCHITECTURE.md +268 -0
- data/docs/strategic/SIMD_OPTIMIZATION_STRATEGY.md +153 -0
- data/docs/troubleshooting.md +215 -0
- data/docs/type_reference.md +224 -0
- data/examples/hostile_mode_demo.rb +64 -0
- data/exe/synthra +6 -0
- data/ext/synthra_native/Cargo.lock +972 -0
- data/ext/synthra_native/Cargo.toml +46 -0
- data/ext/synthra_native/extconf.rb +41 -0
- data/ext/synthra_native/src/generator.rs +397 -0
- data/ext/synthra_native/src/lib.rs +229 -0
- data/ext/synthra_native/src/types.rs +1485 -0
- data/lib/generators/synthra/install_generator.rb +86 -0
- data/lib/generators/synthra/templates/api_response.dsl +15 -0
- data/lib/generators/synthra/templates/fake_data.rake +116 -0
- data/lib/generators/synthra/templates/synthra.yml +31 -0
- data/lib/generators/synthra/templates/synthra_support.rb +19 -0
- data/lib/generators/synthra/templates/user.dsl +11 -0
- data/lib/synthra/activerecord_inference.rb +394 -0
- data/lib/synthra/api.rb +381 -0
- data/lib/synthra/api_server.rb +718 -0
- data/lib/synthra/behaviors/applicator.rb +165 -0
- data/lib/synthra/behaviors/base.rb +155 -0
- data/lib/synthra/behaviors/close_connection.rb +60 -0
- data/lib/synthra/behaviors/deprecated.rb +100 -0
- data/lib/synthra/behaviors/failure.rb +69 -0
- data/lib/synthra/behaviors/latency.rb +103 -0
- data/lib/synthra/behaviors/partial_data.rb +83 -0
- data/lib/synthra/behaviors/randomize_order.rb +74 -0
- data/lib/synthra/behaviors/registry.rb +238 -0
- data/lib/synthra/behaviors/simulate_error.rb +79 -0
- data/lib/synthra/cli/commands/base.rb +105 -0
- data/lib/synthra/cli/commands/diff.rb +227 -0
- data/lib/synthra/cli/commands/docs.rb +67 -0
- data/lib/synthra/cli/commands/export.rb +150 -0
- data/lib/synthra/cli/commands/generate.rb +72 -0
- data/lib/synthra/cli/commands/import.rb +80 -0
- data/lib/synthra/cli/commands/lint.rb +53 -0
- data/lib/synthra/cli/commands/live.rb +57 -0
- data/lib/synthra/cli/commands/seed.rb +99 -0
- data/lib/synthra/cli/commands/validate.rb +28 -0
- data/lib/synthra/cli.rb +2471 -0
- data/lib/synthra/config_file.rb +129 -0
- data/lib/synthra/configuration.rb +281 -0
- data/lib/synthra/contracts_registry.rb +408 -0
- data/lib/synthra/database_seeder.rb +268 -0
- data/lib/synthra/deterministic_ids.rb +218 -0
- data/lib/synthra/documentation_generator.rb +414 -0
- data/lib/synthra/engine.rb +251 -0
- data/lib/synthra/errors.rb +1169 -0
- data/lib/synthra/export/base.rb +85 -0
- data/lib/synthra/export/csv.rb +101 -0
- data/lib/synthra/export/graphql.rb +266 -0
- data/lib/synthra/export/graphql_federation.rb +377 -0
- data/lib/synthra/export/graphviz.rb +258 -0
- data/lib/synthra/export/javascript.rb +327 -0
- data/lib/synthra/export/json_data.rb +61 -0
- data/lib/synthra/export/json_schema.rb +290 -0
- data/lib/synthra/export/openapi.rb +514 -0
- data/lib/synthra/export/protobuf.rb +483 -0
- data/lib/synthra/export/python.rb +560 -0
- data/lib/synthra/export/sql.rb +381 -0
- data/lib/synthra/export/sql_insert.rb +152 -0
- data/lib/synthra/export/terraform.rb +501 -0
- data/lib/synthra/export/type_mapping.rb +389 -0
- data/lib/synthra/export/typescript.rb +300 -0
- data/lib/synthra/export/xml_data.rb +104 -0
- data/lib/synthra/export/yaml_data.rb +56 -0
- data/lib/synthra/export.rb +404 -0
- data/lib/synthra/factory_bot_integration.rb +157 -0
- data/lib/synthra/field.rb +440 -0
- data/lib/synthra/functions/registry.rb +104 -0
- data/lib/synthra/generator/context.rb +372 -0
- data/lib/synthra/generator/engine.rb +336 -0
- data/lib/synthra/generator/faker_adapter.rb +425 -0
- data/lib/synthra/generator/modes.rb +444 -0
- data/lib/synthra/generator/resolver.rb +256 -0
- data/lib/synthra/generator/rng.rb +273 -0
- data/lib/synthra/generator/streamer.rb +63 -0
- data/lib/synthra/generator/uniqueness.rb +118 -0
- data/lib/synthra/initializer.rb +97 -0
- data/lib/synthra/limits.rb +279 -0
- data/lib/synthra/live_preview.rb +518 -0
- data/lib/synthra/loader_config.rb +78 -0
- data/lib/synthra/lsp/server.rb +689 -0
- data/lib/synthra/migration_generator.rb +301 -0
- data/lib/synthra/mixin.rb +174 -0
- data/lib/synthra/mock_server.rb +458 -0
- data/lib/synthra/native_engine.rb +304 -0
- data/lib/synthra/openapi_importer.rb +228 -0
- data/lib/synthra/output/json_formatter.rb +40 -0
- data/lib/synthra/output/ndjson_formatter.rb +55 -0
- data/lib/synthra/parser/ast.rb +1287 -0
- data/lib/synthra/parser/lexer.rb +1152 -0
- data/lib/synthra/parser/parser.rb +1664 -0
- data/lib/synthra/parser/tokens.rb +461 -0
- data/lib/synthra/performance_mode.rb +364 -0
- data/lib/synthra/personas.rb +397 -0
- data/lib/synthra/property_testing.rb +172 -0
- data/lib/synthra/quality_metrics.rb +405 -0
- data/lib/synthra/rails_test_helper.rb +248 -0
- data/lib/synthra/registry.rb +533 -0
- data/lib/synthra/relationships.rb +193 -0
- data/lib/synthra/repl/enhanced_repl.rb +607 -0
- data/lib/synthra/repl/formatter.rb +191 -0
- data/lib/synthra/scenarios.rb +423 -0
- data/lib/synthra/schema.rb +605 -0
- data/lib/synthra/schema_inheritance.rb +104 -0
- data/lib/synthra/schema_versioning.rb +212 -0
- data/lib/synthra/snapshot_testing.rb +199 -0
- data/lib/synthra/time_travel.rb +338 -0
- data/lib/synthra/type_definitions.rb +274 -0
- data/lib/synthra/types/address_location/addresses.rb +125 -0
- data/lib/synthra/types/address_location/airports.rb +200 -0
- data/lib/synthra/types/address_location/banks_hospitals.rb +207 -0
- data/lib/synthra/types/address_location/locations.rb +406 -0
- data/lib/synthra/types/base.rb +48 -0
- data/lib/synthra/types/commerce_products/commerce.rb +119 -0
- data/lib/synthra/types/commerce_products/companies.rb +71 -0
- data/lib/synthra/types/commerce_products/construction.rb +126 -0
- data/lib/synthra/types/commerce_products/products.rb +205 -0
- data/lib/synthra/types/core/collections.rb +513 -0
- data/lib/synthra/types/core/defaults.rb +76 -0
- data/lib/synthra/types/core/enums.rb +102 -0
- data/lib/synthra/types/core/identifiers.rb +445 -0
- data/lib/synthra/types/core/primitives.rb +586 -0
- data/lib/synthra/types/core/references.rb +466 -0
- data/lib/synthra/types/core/sequences.rb +304 -0
- data/lib/synthra/types/crypto/crypto.rb +162 -0
- data/lib/synthra/types/date_time/dates.rb +387 -0
- data/lib/synthra/types/finance_banking/banking.rb +424 -0
- data/lib/synthra/types/finance_banking/credit_cards.rb +24 -0
- data/lib/synthra/types/finance_banking/identifiers.rb +93 -0
- data/lib/synthra/types/formula.rb +184 -0
- data/lib/synthra/types/health_medical/medical.rb +150 -0
- data/lib/synthra/types/hostile_payloads.rb +122 -0
- data/lib/synthra/types/json_array.rb +51 -0
- data/lib/synthra/types/media_entertainment/media.rb +62 -0
- data/lib/synthra/types/naughty_string.rb +30 -0
- data/lib/synthra/types/personal_names/chinese.rb +41 -0
- data/lib/synthra/types/personal_names/identifiers.rb +187 -0
- data/lib/synthra/types/personal_names/names.rb +246 -0
- data/lib/synthra/types/personal_names/national_id.rb +89 -0
- data/lib/synthra/types/personal_names/titles_suffixes.rb +41 -0
- data/lib/synthra/types/regex.rb +248 -0
- data/lib/synthra/types/registry.rb +182 -0
- data/lib/synthra/types/repeating_element.rb +50 -0
- data/lib/synthra/types/scenario.rb +29 -0
- data/lib/synthra/types/technology_internet/apps.rb +67 -0
- data/lib/synthra/types/technology_internet/communication.rb +162 -0
- data/lib/synthra/types/technology_internet/devices.rb +80 -0
- data/lib/synthra/types/technology_internet/formats.rb +139 -0
- data/lib/synthra/types/technology_internet/networking.rb +143 -0
- data/lib/synthra/types/template.rb +92 -0
- data/lib/synthra/types/text_content/business.rb +128 -0
- data/lib/synthra/types/text_content/colors.rb +70 -0
- data/lib/synthra/types/text_content/misc.rb +237 -0
- data/lib/synthra/types/text_content/security.rb +130 -0
- data/lib/synthra/types/text_content/text_generation.rb +532 -0
- data/lib/synthra/types/travel/travel.rb +150 -0
- data/lib/synthra/utils/string_distance.rb +133 -0
- data/lib/synthra/validator/dsl_validator.rb +339 -0
- data/lib/synthra/validator/path_validator.rb +615 -0
- data/lib/synthra/version.rb +35 -0
- data/lib/synthra/webhook_simulator.rb +341 -0
- data/lib/synthra.rb +259 -0
- data/schemas/address.dsl +16 -0
- data/schemas/api_response.dsl +8 -0
- data/schemas/error_payload.dsl +9 -0
- data/schemas/order.dsl +10 -0
- data/schemas/order_item.dsl +8 -0
- data/schemas/payment.dsl +11 -0
- data/schemas/social_post.dsl +13 -0
- data/schemas/user.dsl +10 -0
- data/scripts/batch_fix_all.rb +96 -0
- data/scripts/delete_old_files.rb +32 -0
- data/scripts/fix_all_grouped_files.rb +137 -0
- data/scripts/fix_all_indentation.rb +48 -0
- data/scripts/fix_all_syntax.rb +124 -0
- data/scripts/fix_grouped_files.rb +184 -0
- data/scripts/fix_syntax_errors.rb +108 -0
- data/scripts/group_domain_types.rb +112 -0
- data/scripts/group_domain_types_fixed.rb +150 -0
- data/scripts/merge_domains_to_one_file.rb +68 -0
- data/scripts/move_existing_types.rb +130 -0
- data/scripts/split_grouped_types.rb +142 -0
- data/tech_docs/README.md +134 -0
- data/tech_docs/advanced/streaming.md +405 -0
- data/tech_docs/advanced/thread_safety.md +253 -0
- data/tech_docs/api/overview.md +485 -0
- data/tech_docs/appendices/type_chart.md +193 -0
- data/tech_docs/basic_concepts.md +383 -0
- data/tech_docs/behaviors/overview.md +346 -0
- data/tech_docs/dsl/complex_types.md +790 -0
- data/tech_docs/dsl/core_types.md +464 -0
- data/tech_docs/dsl/datetime_types.md +325 -0
- data/tech_docs/dsl/field_modifiers.md +414 -0
- data/tech_docs/dsl/grammar.md +431 -0
- data/tech_docs/dsl/schema_definition.md +399 -0
- data/tech_docs/export/README.md +276 -0
- data/tech_docs/installation.md +273 -0
- data/tech_docs/integration/ci_cd.md +707 -0
- data/tech_docs/integration/ci_cd_guide.md +579 -0
- data/tech_docs/integration/factory_bot.md +485 -0
- data/tech_docs/integration/rails.md +630 -0
- data/tech_docs/integration/rspec.md +449 -0
- data/tech_docs/modes/overview.md +350 -0
- data/tech_docs/performance/NATIVE_RUST_EXTENSION.md +1270 -0
- data/tech_docs/performance/OPTIMIZATION_GUIDE.md +901 -0
- data/tech_docs/quick_start.md +256 -0
- data/tech_docs/templates/README.md +805 -0
- data/tech_docs/tutorials/advanced.md +371 -0
- data/tech_docs/tutorials/getting_started.md +189 -0
- data/tech_docs/tutorials/intermediate.md +231 -0
- data/tech_docs/tutorials/template_gallery.md +569 -0
- data/tech_example/01_basic_usage.rb +238 -0
- data/tech_example/02_types_demo.rb +336 -0
- data/tech_example/04_cli_usage.md +429 -0
- data/tech_example/05_database_seeding.rb +283 -0
- data/tech_example/07_rspec_integration.rb +359 -0
- data/tech_example/10_custom_types.rb +387 -0
- data/tech_example/12_behaviors.rb +372 -0
- data/tech_example/13_twitter_dm_example.rb +120 -0
- data/tech_example/14_exact_json_structure.rb +253 -0
- data/tech_example/16_lsp_server.rb +56 -0
- data/tech_example/17_property_testing.rb +92 -0
- data/tech_example/18_enhanced_repl.rb +120 -0
- data/tech_example/19_security_fuzzing.rb +145 -0
- data/tech_example/NEW_FEATURES.md +169 -0
- data/tech_example/README.md +118 -0
- data/tech_example/schemas/api_response.dsl +123 -0
- data/tech_example/schemas/ecommerce.dsl +121 -0
- data/tech_example/schemas/twitter_dm.dsl +109 -0
- data/tech_example/schemas/user.dsl +36 -0
- data/vscode-extension/README.md +246 -0
- data/vscode-extension/language-configuration.json +31 -0
- data/vscode-extension/package.json +55 -0
- data/vscode-extension/snippets/fakedatadsl.json +198 -0
- data/vscode-extension/syntaxes/fakedatadsl.tmLanguage.json +128 -0
- metadata +478 -0
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# =============================================================================
|
|
4
|
+
|
|
5
|
+
# Synthra Faker Adapter
|
|
6
|
+
# =============================================================================
|
|
7
|
+
#
|
|
8
|
+
# Wraps Faker calls to use per-instance Random instead of global state.
|
|
9
|
+
# This ensures thread safety and deterministic generation per Engine instance.
|
|
10
|
+
#
|
|
11
|
+
# @example Usage in type generators
|
|
12
|
+
# faker = FakerAdapter.new(rng)
|
|
13
|
+
# name = faker.name
|
|
14
|
+
# email = faker.email
|
|
15
|
+
#
|
|
16
|
+
# =============================================================================
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
module Synthra
|
|
20
|
+
module Generator
|
|
21
|
+
|
|
22
|
+
# Adapter for Faker that uses per-instance Random
|
|
23
|
+
#
|
|
24
|
+
# Wraps all Faker calls to use a specific Random instance instead of
|
|
25
|
+
# modifying global Faker::Config.random. This enables thread-safe
|
|
26
|
+
# concurrent generation with different seeds.
|
|
27
|
+
#
|
|
28
|
+
# @note Performance Consideration: All FakerAdapter instances share a
|
|
29
|
+
# single class-level mutex to synchronize access to Faker's global state.
|
|
30
|
+
# Under very high concurrency (100+ threads), Faker calls will serialize
|
|
31
|
+
# through this mutex, creating a potential bottleneck. This is an
|
|
32
|
+
# acceptable trade-off for correctness and thread safety. For typical
|
|
33
|
+
# use cases (< 50 concurrent threads), the performance impact is negligible.
|
|
34
|
+
#
|
|
35
|
+
# @note Thread Safety: The mutex ensures that Faker::Config.random is
|
|
36
|
+
# correctly set and restored for each call, preventing race conditions
|
|
37
|
+
# in multi-threaded environments. Each Engine instance has its own
|
|
38
|
+
# FakerAdapter with its own Random instance, ensuring deterministic
|
|
39
|
+
# output per Engine.
|
|
40
|
+
#
|
|
41
|
+
# @example Create adapter with RNG
|
|
42
|
+
# rng = RNG.new(42)
|
|
43
|
+
# faker = FakerAdapter.new(rng)
|
|
44
|
+
# faker.name # => "John Smith" (deterministic with seed 42)
|
|
45
|
+
#
|
|
46
|
+
|
|
47
|
+
class FakerAdapter
|
|
48
|
+
|
|
49
|
+
# Global mutex for synchronizing Faker::Config.random access
|
|
50
|
+
#
|
|
51
|
+
# This mutex ensures thread-safe access to Faker's global random state.
|
|
52
|
+
# All FakerAdapter instances share this mutex, which may cause some
|
|
53
|
+
# serialization under high concurrency, but ensures correctness.
|
|
54
|
+
#
|
|
55
|
+
# @api private
|
|
56
|
+
|
|
57
|
+
@mutex = Mutex.new
|
|
58
|
+
|
|
59
|
+
class << self
|
|
60
|
+
attr_reader :mutex
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
# Create a new FakerAdapter
|
|
65
|
+
#
|
|
66
|
+
# @param rng [RNG] the random number generator to use
|
|
67
|
+
#
|
|
68
|
+
|
|
69
|
+
def initialize(rng)
|
|
70
|
+
@rng = rng
|
|
71
|
+
@faker_random = Random.new(rng.seed)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
# Generate a name using Faker
|
|
76
|
+
#
|
|
77
|
+
# @return [String] generated name
|
|
78
|
+
#
|
|
79
|
+
|
|
80
|
+
def name
|
|
81
|
+
with_faker_random { Faker::Name.name }
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
# Generate an email using Faker
|
|
86
|
+
#
|
|
87
|
+
# @return [String] generated email
|
|
88
|
+
#
|
|
89
|
+
|
|
90
|
+
def email
|
|
91
|
+
with_faker_random { Faker::Internet.email }
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
|
|
95
|
+
# Generate a phone number using Faker
|
|
96
|
+
#
|
|
97
|
+
# @return [String] generated phone number
|
|
98
|
+
#
|
|
99
|
+
|
|
100
|
+
def phone_number
|
|
101
|
+
with_faker_random { Faker::PhoneNumber.phone_number }
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
# Generate a URL using Faker
|
|
106
|
+
#
|
|
107
|
+
# @return [String] generated URL
|
|
108
|
+
#
|
|
109
|
+
|
|
110
|
+
def url
|
|
111
|
+
with_faker_random { Faker::Internet.url }
|
|
112
|
+
end
|
|
113
|
+
|
|
114
|
+
|
|
115
|
+
# Generate an IPv4 address using Faker
|
|
116
|
+
#
|
|
117
|
+
# @return [String] generated IPv4 address
|
|
118
|
+
#
|
|
119
|
+
|
|
120
|
+
def ip_v4_address
|
|
121
|
+
with_faker_random { Faker::Internet.ip_v4_address }
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
# Generate an IPv6 address using Faker
|
|
126
|
+
#
|
|
127
|
+
# @return [String] generated IPv6 address
|
|
128
|
+
#
|
|
129
|
+
|
|
130
|
+
def ip_v6_address
|
|
131
|
+
with_faker_random { Faker::Internet.ip_v6_address }
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
# Generate text characters using Faker
|
|
136
|
+
#
|
|
137
|
+
# @param number [Integer] number of characters to generate
|
|
138
|
+
# @param locale [Symbol] locale to use (e.g., :en, :ar, :es)
|
|
139
|
+
# @return [String] generated text
|
|
140
|
+
#
|
|
141
|
+
|
|
142
|
+
def characters(number:, locale: nil)
|
|
143
|
+
with_faker_random do
|
|
144
|
+
if locale && Faker::Config.respond_to?(:locale=)
|
|
145
|
+
original_locale = Faker::Config.locale
|
|
146
|
+
begin
|
|
147
|
+
Faker::Config.locale = locale
|
|
148
|
+
Faker::Lorem.characters(number: number)
|
|
149
|
+
rescue StandardError
|
|
150
|
+
# :nocov:
|
|
151
|
+
# If locale not supported, fallback to current locale
|
|
152
|
+
Faker::Lorem.characters(number: number)
|
|
153
|
+
# :nocov:
|
|
154
|
+
ensure
|
|
155
|
+
Faker::Config.locale = original_locale
|
|
156
|
+
end
|
|
157
|
+
else
|
|
158
|
+
Faker::Lorem.characters(number: number)
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
# Generate a country code using Faker
|
|
165
|
+
#
|
|
166
|
+
# @return [String] generated country code
|
|
167
|
+
#
|
|
168
|
+
|
|
169
|
+
def country_code
|
|
170
|
+
with_faker_random { Faker::Address.country_code }
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
# Generate a currency code using Faker
|
|
175
|
+
#
|
|
176
|
+
# @return [String] generated currency code
|
|
177
|
+
#
|
|
178
|
+
|
|
179
|
+
def currency_code
|
|
180
|
+
with_faker_random { Faker::Currency.code }
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
|
|
184
|
+
# Generate a zip code using Faker
|
|
185
|
+
#
|
|
186
|
+
# @return [String] generated zip code
|
|
187
|
+
#
|
|
188
|
+
|
|
189
|
+
def zip_code
|
|
190
|
+
with_faker_random { Faker::Address.zip_code }
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
|
|
194
|
+
# Generate a postcode using Faker
|
|
195
|
+
#
|
|
196
|
+
# @return [String] generated postcode
|
|
197
|
+
#
|
|
198
|
+
|
|
199
|
+
def postcode
|
|
200
|
+
with_faker_random { Faker::Address.postcode }
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
# Generate a date in the past using Faker
|
|
205
|
+
#
|
|
206
|
+
# @param days [Integer] number of days in the past
|
|
207
|
+
# @return [Date] generated date
|
|
208
|
+
#
|
|
209
|
+
|
|
210
|
+
def date_backward(days:)
|
|
211
|
+
with_faker_random { Faker::Date.backward(days: days) }
|
|
212
|
+
end
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
# Generate a date in the future using Faker
|
|
216
|
+
#
|
|
217
|
+
# @param days [Integer] number of days in the future
|
|
218
|
+
# @return [Date] generated date
|
|
219
|
+
#
|
|
220
|
+
|
|
221
|
+
def date_forward(days:)
|
|
222
|
+
with_faker_random { Faker::Date.forward(days: days) }
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
|
|
226
|
+
# Generate a time in the past using Faker
|
|
227
|
+
#
|
|
228
|
+
# @param days [Integer] number of days in the past
|
|
229
|
+
# @return [Time] generated time
|
|
230
|
+
#
|
|
231
|
+
|
|
232
|
+
def time_backward(days:)
|
|
233
|
+
with_faker_random { Faker::Time.backward(days: days) }
|
|
234
|
+
end
|
|
235
|
+
|
|
236
|
+
|
|
237
|
+
# Generate a gender using Faker
|
|
238
|
+
#
|
|
239
|
+
# @return [String] generated gender
|
|
240
|
+
#
|
|
241
|
+
|
|
242
|
+
def gender
|
|
243
|
+
with_faker_random { Faker::Gender.type }
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
# Generate a timezone using Faker
|
|
248
|
+
#
|
|
249
|
+
# @return [String] generated timezone
|
|
250
|
+
#
|
|
251
|
+
|
|
252
|
+
def time_zone
|
|
253
|
+
with_faker_random { Faker::Address.time_zone }
|
|
254
|
+
end
|
|
255
|
+
|
|
256
|
+
|
|
257
|
+
# Generate a first name using Faker
|
|
258
|
+
#
|
|
259
|
+
# @return [String] generated first name
|
|
260
|
+
#
|
|
261
|
+
|
|
262
|
+
def first_name
|
|
263
|
+
with_faker_random { Faker::Name.first_name }
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
# Generate a last name using Faker
|
|
268
|
+
#
|
|
269
|
+
# @return [String] generated last name
|
|
270
|
+
#
|
|
271
|
+
|
|
272
|
+
def last_name
|
|
273
|
+
with_faker_random { Faker::Name.last_name }
|
|
274
|
+
end
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
# Generate an airline name using Faker
|
|
278
|
+
#
|
|
279
|
+
# @return [String] generated airline name
|
|
280
|
+
#
|
|
281
|
+
|
|
282
|
+
def airline
|
|
283
|
+
with_faker_random { Faker::Airline.name }
|
|
284
|
+
end
|
|
285
|
+
|
|
286
|
+
|
|
287
|
+
# Generate a blood type using Faker
|
|
288
|
+
#
|
|
289
|
+
# @return [String] generated blood type
|
|
290
|
+
#
|
|
291
|
+
|
|
292
|
+
def blood_type
|
|
293
|
+
with_faker_random { Faker::Blood.type }
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
|
|
297
|
+
# Generate a city using Faker
|
|
298
|
+
#
|
|
299
|
+
# @return [String] generated city
|
|
300
|
+
#
|
|
301
|
+
|
|
302
|
+
def city
|
|
303
|
+
with_faker_random { Faker::Address.city }
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
|
|
307
|
+
# Generate a state using Faker
|
|
308
|
+
#
|
|
309
|
+
# @return [String] generated state
|
|
310
|
+
#
|
|
311
|
+
|
|
312
|
+
def state
|
|
313
|
+
with_faker_random { Faker::Address.state }
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
|
|
317
|
+
# Generate a street address using Faker
|
|
318
|
+
#
|
|
319
|
+
# @return [String] generated street address
|
|
320
|
+
#
|
|
321
|
+
|
|
322
|
+
def street_address
|
|
323
|
+
with_faker_random { Faker::Address.street_address }
|
|
324
|
+
end
|
|
325
|
+
|
|
326
|
+
|
|
327
|
+
# Generate a street name using Faker
|
|
328
|
+
#
|
|
329
|
+
# @return [String] generated street name
|
|
330
|
+
#
|
|
331
|
+
|
|
332
|
+
def street_name
|
|
333
|
+
with_faker_random { Faker::Address.street_name }
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
# Generate a company name using Faker
|
|
338
|
+
#
|
|
339
|
+
# @return [String] generated company name
|
|
340
|
+
#
|
|
341
|
+
|
|
342
|
+
def company_name
|
|
343
|
+
with_faker_random { Faker::Company.name }
|
|
344
|
+
end
|
|
345
|
+
|
|
346
|
+
|
|
347
|
+
# Generate a buzzword using Faker
|
|
348
|
+
#
|
|
349
|
+
# @return [String] generated buzzword
|
|
350
|
+
#
|
|
351
|
+
|
|
352
|
+
def buzzword
|
|
353
|
+
with_faker_random { Faker::Company.buzzword }
|
|
354
|
+
end
|
|
355
|
+
|
|
356
|
+
|
|
357
|
+
# Generate a catch phrase using Faker
|
|
358
|
+
#
|
|
359
|
+
# @return [String] generated catch phrase
|
|
360
|
+
#
|
|
361
|
+
|
|
362
|
+
def catch_phrase
|
|
363
|
+
with_faker_random { Faker::Company.catch_phrase }
|
|
364
|
+
end
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
# Generate a color using Faker
|
|
368
|
+
#
|
|
369
|
+
# @return [String] generated color
|
|
370
|
+
#
|
|
371
|
+
|
|
372
|
+
def color
|
|
373
|
+
with_faker_random { Faker::Commerce.color }
|
|
374
|
+
end
|
|
375
|
+
|
|
376
|
+
|
|
377
|
+
# Generate a female first name using Faker
|
|
378
|
+
#
|
|
379
|
+
# @return [String] generated female first name
|
|
380
|
+
#
|
|
381
|
+
|
|
382
|
+
def female_first_name
|
|
383
|
+
with_faker_random { Faker::Name.female_first_name }
|
|
384
|
+
end
|
|
385
|
+
|
|
386
|
+
|
|
387
|
+
# Generate a male first name using Faker
|
|
388
|
+
#
|
|
389
|
+
# @return [String] generated male first name
|
|
390
|
+
#
|
|
391
|
+
|
|
392
|
+
def male_first_name
|
|
393
|
+
with_faker_random { Faker::Name.male_first_name }
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
private
|
|
397
|
+
|
|
398
|
+
|
|
399
|
+
# Temporarily set Faker's random and execute block
|
|
400
|
+
#
|
|
401
|
+
# This method synchronizes access to Faker::Config.random to ensure
|
|
402
|
+
# thread safety. It saves the current random, sets ours, executes
|
|
403
|
+
# the block, then restores the original.
|
|
404
|
+
#
|
|
405
|
+
# @yield [] block to execute with our random
|
|
406
|
+
# @return [Object] result of block
|
|
407
|
+
#
|
|
408
|
+
|
|
409
|
+
def with_faker_random
|
|
410
|
+
|
|
411
|
+
# Use class-level mutex to synchronize access to global Faker state
|
|
412
|
+
self.class.mutex.synchronize do
|
|
413
|
+
old_random = Faker::Config.random
|
|
414
|
+
begin
|
|
415
|
+
Faker::Config.random = @faker_random
|
|
416
|
+
yield
|
|
417
|
+
ensure
|
|
418
|
+
Faker::Config.random = old_random
|
|
419
|
+
end
|
|
420
|
+
end
|
|
421
|
+
end
|
|
422
|
+
end
|
|
423
|
+
end
|
|
424
|
+
end
|
|
425
|
+
|