feiku 0.1.1 → 0.2.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3297b4de9084be2ec8060291c0e38b91b3b23a99408f31db1df9f216e547b01d
4
- data.tar.gz: 206266a45fc4dd2da0b6ac92b2a508c1cc9698fa77c5c5d4e0f5ee386614fee4
3
+ metadata.gz: 8fdd3bcaa1c2a95a6c3bebedae5573c41669e27f3af1aab25fcb0afcd579846b
4
+ data.tar.gz: b0da6fc6c0193929662a0e85adef3752f36dfb915c5c4224940fb6eccbc51940
5
5
  SHA512:
6
- metadata.gz: be412a317663c1229e1d4ba42473934d8742ecaade40fff46dae6fdf8da7ea884a34cac1df0b80c07a63fc41abb2710e8559eb18e3f1b2ccd2fa4f3b942295a1
7
- data.tar.gz: 33cb68c3f37854435e28d50ad4fa279971faf125590e3a4bf1a59c12b097df271eac43eba73501b588bf01170c04828c709972553ceeb95e46fc136a1f80c2ee
6
+ metadata.gz: 138a371ac72af75e4d9351026986763f087a589b0bc8eb667cab1b3c600e16e9e7f56e804d89f68805cc951822edcf23bbbac957718824a4f74e0d89caaaab26
7
+ data.tar.gz: 165b15cd7b8b9d87a577c428a4e2fa8678d597737d5df59fc9f0ecc8599bcfad248e7c218a8956aac3c63348feed92f77a05294a0909d64a080803e8b6edbb29
data/.rubocop.yml CHANGED
@@ -1,6 +1,14 @@
1
1
  AllCops:
2
+ Exclude:
3
+ - 'feiku.gemspec'
4
+ - 'vendor/**/*'
5
+ NewCops: enable
2
6
  TargetRubyVersion: 3.0
3
7
 
8
+ Metrics:
9
+ Exclude:
10
+ - 'test/**/*'
11
+
4
12
  Style/StringLiterals:
5
13
  EnforcedStyle: double_quotes
6
14
 
data/CHANGELOG.md CHANGED
@@ -1,5 +1,10 @@
1
1
  ## [Unreleased]
2
2
 
3
+ ## [0.2.0] - 2024-10-13
4
+
5
+ - Introduce Faker compatibility
6
+ - Enable unique generation
7
+
3
8
  ## [0.1.0] - 2024-08-23
4
9
 
5
10
  - Initial release
@@ -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
@@ -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!(/%\{[^}]+\}/) { n += 1 and "%s" }
22
- [format, n]
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: 10, &block)
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
- return generated if check_success_with(generated, block) && check_uniqueness(generated)
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
- return item if check_success_with(item) && check_uniqueness(item)
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
- # TODO
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
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Feiku
4
- VERSION = "0.1.1"
4
+ VERSION = "0.2.0"
5
5
  end
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
- def self.register(module_name, format:, value:, length: nil, pool_size: 0)
12
- const_set(module_name, Generator.new(format: format, value: value, length: length, pool_size: pool_size))
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
- Feiku.register(:Domain, format: "%<name>s.example", value: { name: Feiku::Username })
17
- Feiku.register(:Email,
18
- format: "%<name>s@%<domain>s",
19
- value: { name: Feiku::Username, domain: Feiku::Domain })
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.1.1
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-09-19 00:00:00.000000000 Z
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