Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLI interface for faker #1278

Closed
wants to merge 17 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
31 changes: 17 additions & 14 deletions Gemfile.lock
Expand Up @@ -3,55 +3,58 @@ PATH
specs:
faker (1.9.1)
i18n (>= 0.7)
thor (= 0.20.0)

GEM
remote: https://rubygems.org/
specs:
ast (2.4.0)
concurrent-ruby (1.0.5)
docile (1.3.0)
i18n (1.0.1)
docile (1.3.1)
i18n (1.1.0)
concurrent-ruby (~> 1.0)
jaro_winkler (1.5.1)
json (2.1.0)
minitest (5.10.3)
minitest (5.11.3)
parallel (1.12.1)
parser (2.5.1.2)
ast (~> 2.4.0)
power_assert (1.1.1)
power_assert (1.1.3)
powerpack (0.1.2)
rainbow (3.0.0)
rake (12.3.0)
rubocop (0.58.1)
rake (12.3.1)
rubocop (0.59.1)
jaro_winkler (~> 1.5.1)
parallel (~> 1.10)
parser (>= 2.5, != 2.5.1.1)
powerpack (~> 0.1)
rainbow (>= 2.2.2, < 4.0)
ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1)
ruby-progressbar (1.9.0)
ruby-progressbar (1.10.0)
simplecov (0.16.1)
docile (~> 1.1)
json (>= 1.8, < 3)
simplecov-html (~> 0.10.0)
simplecov-html (0.10.2)
test-unit (3.2.6)
test-unit (3.2.8)
power_assert
thor (0.20.0)
timecop (0.9.1)
unicode-display_width (1.4.0)

PLATFORMS
ruby

DEPENDENCIES
bundler (= 1.16.4)
faker!
minitest
rake
rubocop
simplecov
test-unit
timecop
minitest (= 5.11.3)
rake (= 12.3.1)
rubocop (= 0.59.1)
simplecov (= 0.16.1)
test-unit (= 3.2.8)
timecop (= 0.9.1)

BUNDLED WITH
1.16.4
6 changes: 6 additions & 0 deletions exe/faker
@@ -0,0 +1,6 @@
#!/usr/bin/env ruby
# frozen_string_literal: true

require 'faker'

Faker::CLI.start(ARGV)
49 changes: 29 additions & 20 deletions faker.gemspec
Expand Up @@ -3,26 +3,35 @@
$LOAD_PATH.push File.expand_path('lib', __dir__)
require 'faker/version'

Gem::Specification.new do |s|
s.name = 'faker'
s.version = Faker::VERSION
s.platform = Gem::Platform::RUBY
s.authors = ['Benjamin Curtis']
s.email = ['benjamin.curtis@gmail.com']
s.homepage = 'https://github.com/stympy/faker'
s.summary = 'Easily generate fake data'
s.description = 'Faker, a port of Data::Faker from Perl, is used to easily generate fake data: names, addresses, phone numbers, etc.'
s.license = 'MIT'
Gem::Specification.new do |spec|
spec.name = 'faker'
spec.version = Faker::VERSION
spec.platform = Gem::Platform::RUBY
spec.authors = ['Benjamin Curtis']
spec.email = ['benjamin.curtis@gmail.com']

s.add_runtime_dependency('i18n', '>= 0.7')
s.add_development_dependency('minitest')
s.add_development_dependency('rake')
s.add_development_dependency('rubocop')
s.add_development_dependency('simplecov')
s.add_development_dependency('test-unit')
s.add_development_dependency('timecop')
s.required_ruby_version = '>= 2.3'
spec.summary = 'Easily generate fake data'
spec.description = 'Faker, a port of Data::Faker from Perl, is used to easily generate fake data: names, addresses, phone numbers, etc.'
spec.homepage = 'https://github.com/stympy/faker'
spec.license = 'MIT'

s.files = Dir['lib/**/*'] + %w[History.md License.txt CHANGELOG.md README.md]
s.require_paths = ['lib']
spec.files = Dir['lib/**/*'] + %w[History.md License.txt CHANGELOG.md README.md]
spec.bindir = 'exe'
spec.executables = spec.files.grep(%r{^exe/}) do |file|
File.basename(file)
end
spec.require_paths = ['lib']
spec.required_ruby_version = '>= 2.3'

spec.add_dependency('thor', '0.20.0')

spec.add_development_dependency('bundler', '1.16.4')
spec.add_development_dependency('minitest', '5.11.3')
spec.add_development_dependency('rake', '12.3.1')
spec.add_development_dependency('rubocop', '0.59.1')
spec.add_development_dependency('simplecov', '0.16.1')
spec.add_development_dependency('test-unit', '3.2.8')
spec.add_development_dependency('timecop', '0.9.1')

spec.add_runtime_dependency('i18n', '>= 0.7')
end
16 changes: 11 additions & 5 deletions lib/faker.rb
Expand Up @@ -47,6 +47,7 @@ class << self
## by default numerify results do not start with a zero
def numerify(number_string, leading_zero: false)
return number_string.gsub(/#/) { rand(10).to_s } if leading_zero

number_string.sub(/#/) { rand(1..9).to_s }.gsub(/#/) { rand(10).to_s }
end

Expand Down Expand Up @@ -222,12 +223,17 @@ def rand(max = nil)
0
end
end

# TODO: Remove this evil eval method
# rubocop:disable Style/EvalWithLocation, Security/Eval
def module_methods(subclass)
eval("Faker::#{subclass}.public_methods(false)") - Faker::Base.public_methods(false)
end
# rubocop:enable Style/EvalWithLocation, Security/Eval
end
end
end

Dir.glob(File.join(File.dirname(__FILE__), 'faker', '*.rb')).sort.each { |f| require f }

require 'helpers/char'
require 'helpers/unique_generator'
require 'helpers/base58'
%w[faker helpers].each do |path|
Dir.glob(File.join(File.dirname(__FILE__), path, '*.rb')).sort.each { |file| require file }
end
1 change: 1 addition & 0 deletions lib/faker/avatar.rb
Expand Up @@ -8,6 +8,7 @@ class << self
def image(slug = nil, size = '300x300', format = 'png', set = 'set1', bgset = nil)
raise ArgumentError, 'Size should be specified in format 300x300' unless size =~ /^[0-9]+x[0-9]+$/
raise ArgumentError, "Supported formats are #{SUPPORTED_FORMATS.join(', ')}" unless SUPPORTED_FORMATS.include?(format)

slug ||= Faker::Lorem.words.join
bgset_query = "&bgset=#{bgset}" if bgset
"https://robohash.org/#{slug}.#{format}?size=#{size}&set=#{set}#{bgset_query}"
Expand Down
22 changes: 22 additions & 0 deletions lib/faker/cli.rb
@@ -0,0 +1,22 @@
# frozen_string_literal: true

require 'thor'

module Faker
class CLI < Thor
Faker.constants.sort.each do |constant|
desc "#{constant.downcase} [-f #{Faker::Base.module_methods(constant).join('|')}]",
"Returns fake #{constant.downcase} data"
option :faker_type, aliases: '-f', desc: 'the faker data type'
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm thinking we could merge this (faker [Constant] -f=[data type]) into faker list [Constant] --type=[data type] in #1507 ?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree 👍


define_method :"#{constant.downcase}" do
begin
puts Object.const_get("Faker::#{constant.capitalize}.#{options.faker_type}")
rescue I18n::MissingTranslationData
puts "Usage: `faker #{constant.downcase} -f=#{options.faker_type}`"
puts "Run `faker help #{constant.downcase}` for a list of valid types"
end
end
end
end
end
1 change: 1 addition & 0 deletions lib/faker/commerce.rb
Expand Up @@ -22,6 +22,7 @@ def department(max = 3, fixed_amount = false)
categories = categories(num)

return merge_categories(categories) if num > 1

categories[0]
end

Expand Down
1 change: 1 addition & 0 deletions lib/faker/company.rb
Expand Up @@ -128,6 +128,7 @@ def polish_taxpayer_identification_number
# Get a random Polish register of national economy number. More info https://pl.wikipedia.org/wiki/REGON
def polish_register_of_national_economy(length = 9)
raise ArgumentError, 'Length should be 9 or 14' unless [9, 14].include? length

random_digits = []
loop do
random_digits = Array.new(length) { rand(10) }
Expand Down
1 change: 1 addition & 0 deletions lib/faker/date.rb
Expand Up @@ -12,6 +12,7 @@ def between(from, to)

def between_except(from, to, excepted)
raise ArgumentError, 'From date, to date and excepted date must not be the same' if from == to && to == excepted

excepted = get_date_object(excepted)

loop do
Expand Down
1 change: 1 addition & 0 deletions lib/faker/hipster.rb
Expand Up @@ -17,6 +17,7 @@ def words(num = 3, supplemental = false, spaces_allowed = false)
word_list *= ((resolved_num / word_list.length) + 1)

return shuffle(word_list)[0, resolved_num] if spaces_allowed

words = shuffle(word_list)[0, resolved_num]
words.each_with_index { |w, i| words[i] = word if w =~ /\s/ }
end
Expand Down
2 changes: 2 additions & 0 deletions lib/faker/internet.rb
Expand Up @@ -22,9 +22,11 @@ def safe_email(name = nil)
def username(specifier = nil, separators = %w[. _])
with_locale(:en) do
return shuffle(specifier.scan(/\w+/)).join(sample(separators)).downcase if specifier.respond_to?(:scan)

if specifier.is_a?(Integer)
# If specifier is Integer and has large value, Argument error exception is raised to overcome memory full error
raise ArgumentError, 'Given argument is too large' if specifier > 10**6

tries = 0 # Don't try forever in case we get something like 1_000_000.
result = nil
loop do
Expand Down
1 change: 1 addition & 0 deletions lib/faker/lorem.rb
Expand Up @@ -27,6 +27,7 @@ def character
def characters(char_count = 255)
char_count = resolve(char_count)
return '' if char_count.to_i < 1

Array.new(char_count) { sample(CHARACTERS) }.join
end

Expand Down
1 change: 1 addition & 0 deletions lib/faker/lovecraft.rb
Expand Up @@ -34,6 +34,7 @@ def words(num = 3, spaces_allowed = false)
word_list *= ((resolved_num / word_list.length) + 1)

return shuffle(word_list)[0, resolved_num] if spaces_allowed

words = shuffle(word_list)[0, resolved_num]
words.each_with_index { |w, i| words[i] = word if w =~ /\s/ }
end
Expand Down
1 change: 1 addition & 0 deletions lib/faker/time.rb
Expand Up @@ -38,6 +38,7 @@ def time_with_format(time, format)

def hours(period)
raise ArgumentError, 'invalid period' unless TIME_RANGES.key? period

sample(TIME_RANGES[period].to_a)
end

Expand Down
1 change: 1 addition & 0 deletions script/txt2html
Expand Up @@ -21,6 +21,7 @@ class Fixnum
def ordinal
# teens
return 'th' if (10..19).cover?(self % 100)

# others
case self % 10
when 1
Expand Down
8 changes: 4 additions & 4 deletions test/test_determinism.rb
@@ -1,7 +1,7 @@
# frozen_string_literal: true

require_relative 'test_helper'
# rubocop:disable Security/Eval,Style/EvalWithLocation
# rubocop:disable Security/Eval
class TestDeterminism < Test::Unit::TestCase
def setup
@all_methods = all_methods.freeze
Expand Down Expand Up @@ -45,14 +45,14 @@ def all_methods

def subclasses
Faker.constants.delete_if do |subclass|
%i[Base Bank Char Base58 ChileRut Config Date Internet Time VERSION].include?(subclass)
%i[Base Bank Base58 Char CLI ChileRut Config Date Internet Time VERSION].include?(subclass)
end.sort
end

def subclass_methods(subclass)
eval("Faker::#{subclass}.public_methods(false) - Faker::Base.public_methods(false)").sort.map do |method|
Faker::Base.module_methods(subclass).sort.map do |method|
"Faker::#{subclass}.#{method}"
end.sort
end
end
# rubocop:enable Security/Eval,Style/EvalWithLocation
# rubocop:enable Security/Eval
File renamed without changes.