feiku 0.1.1 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.rubocop.yml +8 -0
- data/CHANGELOG.md +5 -0
- data/lib/feiku/faker_compat.rb +32 -0
- data/lib/feiku/generator.rb +6 -3
- data/lib/feiku/unit.rb +20 -11
- data/lib/feiku/version.rb +1 -1
- data/lib/feiku.rb +31 -7
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8fdd3bcaa1c2a95a6c3bebedae5573c41669e27f3af1aab25fcb0afcd579846b
|
4
|
+
data.tar.gz: b0da6fc6c0193929662a0e85adef3752f36dfb915c5c4224940fb6eccbc51940
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 138a371ac72af75e4d9351026986763f087a589b0bc8eb667cab1b3c600e16e9e7f56e804d89f68805cc951822edcf23bbbac957718824a4f74e0d89caaaab26
|
7
|
+
data.tar.gz: 165b15cd7b8b9d87a577c428a4e2fa8678d597737d5df59fc9f0ecc8599bcfad248e7c218a8956aac3c63348feed92f77a05294a0909d64a080803e8b6edbb29
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -0,0 +1,32 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Feiku
|
4
|
+
# MetaProxy is a class just for const_missing
|
5
|
+
class MetaProxy
|
6
|
+
def self.const_missing(name)
|
7
|
+
Proxy.new(name)
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
# Proxy is a simple blank object to invoke method_missing
|
12
|
+
class Proxy < BasicObject
|
13
|
+
def initialize(name)
|
14
|
+
@name = name
|
15
|
+
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def method_missing(meth)
|
20
|
+
generator = ::Feiku.lookup(@name, meth)
|
21
|
+
raise ArgumentError, "No generator found for #{@name}.#{meth}" unless generator
|
22
|
+
|
23
|
+
generator.generate
|
24
|
+
end
|
25
|
+
|
26
|
+
def respond_to_missing?(meth)
|
27
|
+
!!::Feiku.lookup(@name, meth)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
Faker = Feiku::MetaProxy
|
data/lib/feiku/generator.rb
CHANGED
@@ -11,23 +11,26 @@ module Feiku
|
|
11
11
|
class Generator
|
12
12
|
RANDOM_STRING = [*"a".."z", *"A".."Z"].freeze
|
13
13
|
RANDOM_INTEGER = [*0..9].freeze
|
14
|
-
def initialize(format:, value:, length:, pool_size: 0)
|
14
|
+
def initialize(format:, value:, length:, pool_size: 0, &block) # rubocop:disable Metrics/MethodLength
|
15
15
|
@length = length
|
16
16
|
@value = value
|
17
17
|
@format, @size = if value.is_a?(Hash)
|
18
18
|
[format, value.size]
|
19
19
|
else
|
20
20
|
n = 0
|
21
|
-
format.gsub
|
22
|
-
[
|
21
|
+
f = format.gsub(/%\{[^}]+\}/) { n += 1 and "%s" }
|
22
|
+
[f, n]
|
23
23
|
end
|
24
24
|
@pool = pool_size.zero? ? nil : Array.new(pool_size) { _generate }
|
25
|
+
self.class.class_eval(&block) if block_given?
|
25
26
|
end
|
26
27
|
|
27
28
|
def generate
|
28
29
|
@pool.nil? ? _generate : @pool.sample
|
29
30
|
end
|
30
31
|
|
32
|
+
private
|
33
|
+
|
31
34
|
def _generate
|
32
35
|
@fillings = case @value
|
33
36
|
when :string, :integer
|
data/lib/feiku/unit.rb
CHANGED
@@ -11,25 +11,34 @@ module Feiku
|
|
11
11
|
@data_type = data_type
|
12
12
|
@length = length
|
13
13
|
@unique = false
|
14
|
+
@uniqueness_pool = []
|
14
15
|
end
|
15
16
|
|
16
|
-
def generate(max_attempt:
|
17
|
+
def generate(max_attempt: 1000, &block)
|
17
18
|
length = @length.is_a?(Integer) ? @length : @length.to_a.sample
|
18
19
|
generated = _generate(length)
|
19
|
-
|
20
|
+
if check_success_with(generated, block) && check_uniqueness(generated)
|
21
|
+
@uniqueness_pool << generated
|
22
|
+
return generated
|
23
|
+
end
|
24
|
+
|
25
|
+
try_until_success(length, max_attempt, &block)
|
26
|
+
end
|
20
27
|
|
28
|
+
def try_until_success(length, max_attempt, &block)
|
21
29
|
attempt_count = 0
|
22
30
|
while attempt_count <= max_attempt
|
23
31
|
item = _generate(length)
|
24
|
-
|
32
|
+
if check_success_with(item, block) && check_uniqueness(item)
|
33
|
+
@uniqueness_pool << item
|
34
|
+
return item
|
35
|
+
end
|
36
|
+
|
37
|
+
attempt_count += 1
|
25
38
|
end
|
26
39
|
raise Feiku::Error, "Cannot generate correct data within given attempt times: #{max_attempt}"
|
27
40
|
end
|
28
41
|
|
29
|
-
def filter_result(generated, &block)
|
30
|
-
generated = _generate(length) until block.call(generated)
|
31
|
-
end
|
32
|
-
|
33
42
|
def unique
|
34
43
|
@unique = true
|
35
44
|
self
|
@@ -46,8 +55,7 @@ module Feiku
|
|
46
55
|
def check_uniqueness(item)
|
47
56
|
return true unless @unique
|
48
57
|
|
49
|
-
|
50
|
-
item == 42
|
58
|
+
@uniqueness_pool.none? { |pool_item| pool_item == item }
|
51
59
|
end
|
52
60
|
|
53
61
|
def _generate(length)
|
@@ -58,7 +66,8 @@ module Feiku
|
|
58
66
|
else raise Feiku::Error
|
59
67
|
end
|
60
68
|
end
|
69
|
+
Username = Unit.new(data_type: :alphanumeric, length: 2..10)
|
70
|
+
Firstname = Unit.new(data_type: ->(l) { Feiku::Unit::RANDOM_STRING.sample(l).join.capitalize }, length: 3..8)
|
71
|
+
Lastname = Firstname
|
61
72
|
end
|
62
|
-
|
63
|
-
Username = Unit.new(data_type: :alphanumeric, length: 2..10)
|
64
73
|
end
|
data/lib/feiku/version.rb
CHANGED
data/lib/feiku.rb
CHANGED
@@ -3,17 +3,41 @@
|
|
3
3
|
require_relative "feiku/version"
|
4
4
|
require_relative "feiku/generator"
|
5
5
|
require_relative "feiku/unit"
|
6
|
+
require_relative "feiku/faker_compat"
|
6
7
|
|
7
8
|
# Toplevel
|
8
9
|
module Feiku
|
10
|
+
@faker_compat_registry = {}
|
11
|
+
|
9
12
|
class Error < StandardError; end
|
10
13
|
|
11
|
-
|
12
|
-
|
14
|
+
# Primary interface to add fake data definition
|
15
|
+
def self.register(module_name, format:, value:, length: nil, pool_size: 0, faker_compat: nil) # rubocop:disable Metrics/ParameterLists
|
16
|
+
generator = Generator.new(format: format, value: value, length: length, pool_size: pool_size)
|
17
|
+
@faker_compat_registry.update(faker_compat => generator) if faker_compat
|
18
|
+
remove_const(module_name) if const_defined?(module_name)
|
19
|
+
const_set(module_name, generator)
|
13
20
|
end
|
14
|
-
end
|
15
21
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
22
|
+
# An interface for Faker compatibility
|
23
|
+
def self.lookup(module_name, method_name)
|
24
|
+
@faker_compat_registry.fetch("#{module_name}.#{method_name}")
|
25
|
+
end
|
26
|
+
|
27
|
+
register(:Name, format: "%<first_name>s %<last_name>s",
|
28
|
+
value: { first_name: Unit::Firstname, last_name: Unit::Lastname },
|
29
|
+
faker_compat: "Name.name")
|
30
|
+
register(:Firstname, format: "%<name>s", value: { name: Unit::Firstname }, faker_compat: "Name.first_name")
|
31
|
+
register(:Middlename, format: "%<name>s", value: { name: Unit::Firstname }, faker_compat: "Name.middle_name")
|
32
|
+
register(:Lastname, format: "%<name>s", value: { name: Unit::Firstname }, faker_compat: "Name.last_name")
|
33
|
+
register(:NameWithMiddle, format: "%<first_name>s %<middle_name>s %<last_name>s",
|
34
|
+
value: {
|
35
|
+
first_name: Unit::Firstname,
|
36
|
+
middle_name: Unit::Firstname,
|
37
|
+
last_name: Unit::Lastname
|
38
|
+
},
|
39
|
+
faker_compat: "Name.name_with_middle")
|
40
|
+
register(:Domain, format: "%<name>s.example", value: { name: Unit::Username })
|
41
|
+
register(:Email, format: "%<name>s@%<domain>s",
|
42
|
+
value: { name: Unit::Username, domain: Domain })
|
43
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: feiku
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- OKURA Masafumi
|
8
8
|
bindir: exe
|
9
9
|
cert_chain: []
|
10
|
-
date: 2024-
|
10
|
+
date: 2024-10-13 00:00:00.000000000 Z
|
11
11
|
dependencies: []
|
12
12
|
description: Feiku (pronounced as "fake") is a tool to generate fake data. Unlike
|
13
13
|
other solutions, it doesn't use YAML file to define data. Instead, it generates
|
@@ -25,6 +25,7 @@ files:
|
|
25
25
|
- README.md
|
26
26
|
- Rakefile
|
27
27
|
- lib/feiku.rb
|
28
|
+
- lib/feiku/faker_compat.rb
|
28
29
|
- lib/feiku/generator.rb
|
29
30
|
- lib/feiku/unit.rb
|
30
31
|
- lib/feiku/version.rb
|