diff --git a/Gemfile.lock b/Gemfile.lock index aea547412f..ccca280914 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -3,11 +3,6 @@ PATH specs: faker (1.9.4) i18n (>= 0.7) - pastel (~> 0.7.2) - thor (~> 0.20.0) - tty-pager (~> 0.12.0) - tty-screen (~> 0.6.5) - tty-tree (~> 0.3.0) GEM remote: https://rubygems.org/ @@ -16,7 +11,6 @@ GEM coderay (1.1.2) concurrent-ruby (1.1.5) docile (1.3.1) - equatable (0.5.0) i18n (1.6.0) concurrent-ruby (~> 1.0) jaro_winkler (1.5.2) @@ -26,9 +20,6 @@ GEM parallel (1.12.1) parser (2.5.3.0) ast (~> 2.4.0) - pastel (0.7.2) - equatable (~> 0.5.0) - tty-color (~> 0.4.0) power_assert (1.1.3) powerpack (0.1.2) pry (0.12.2) @@ -50,25 +41,10 @@ GEM json (>= 1.8, < 3) simplecov-html (~> 0.10.0) simplecov-html (0.10.2) - strings (0.1.4) - strings-ansi (~> 0.1.0) - unicode-display_width (~> 1.4.0) - unicode_utils (~> 1.4.0) - strings-ansi (0.1.0) test-unit (3.2.8) power_assert - thor (0.20.3) timecop (0.9.1) - tty-color (0.4.3) - tty-pager (0.12.1) - strings (~> 0.1.4) - tty-screen (~> 0.6) - tty-which (~> 0.4) - tty-screen (0.6.5) - tty-tree (0.3.0) - tty-which (0.4.1) unicode-display_width (1.4.1) - unicode_utils (1.4.0) PLATFORMS ruby diff --git a/README.md b/README.md index 967e9c0270..a705aea39c 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,6 @@ development. - [NOTE](#note) - [Installing](#installing) - [Usage](#usage) - - [CLI](#cli) - [Ensuring unique values](#ensuring-unique-values) - [Deterministic Random](#deterministic-random) - [Generators](#generators) @@ -67,14 +66,6 @@ Faker::Name.name #=> "Christophe Bartell" Faker::Internet.email #=> "kirsten.greenholt@corkeryfisher.info" ``` -### CLI - -Usage Instructions [available here](https://github.com/stympy/faker/blob/master/lib/cli/README.md) - -```bash -$ faker -``` - ### Ensuring unique values Prefix your method call with `unique`. For example: ```ruby diff --git a/bin/faker b/bin/faker index 4cecb026e6..1e4b289c5d 100755 --- a/bin/faker +++ b/bin/faker @@ -3,17 +3,3 @@ lib_path = File.expand_path('../lib', __dir__) $LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include?(lib_path) - -require 'cli' - -Signal.trap('INT') do - warn("\n#{caller.join("\n")}: interrupted") - exit(1) -end - -begin - Faker::CLI::Base.start -rescue Faker::CLI::Base::Error => err - puts "ERROR: #{err.message}" - exit 1 -end diff --git a/faker.gemspec b/faker.gemspec index eb13e831db..014d523abc 100644 --- a/faker.gemspec +++ b/faker.gemspec @@ -26,11 +26,6 @@ Gem::Specification.new do |spec| spec.metadata['bug_tracker_uri'] = 'https://github.com/stympy/faker/issues' spec.add_dependency('i18n', '>= 0.7') - spec.add_dependency('pastel', '~> 0.7.2') - spec.add_dependency('thor', '~> 0.20.0') - spec.add_dependency('tty-pager', '~> 0.12.0') - spec.add_dependency('tty-screen', '~> 0.6.5') - spec.add_dependency('tty-tree', '~> 0.3.0') spec.add_development_dependency('minitest', '5.11.3') spec.add_development_dependency('pry', '0.12.2') diff --git a/lib/cli.rb b/lib/cli.rb deleted file mode 100644 index 5b87554494..0000000000 --- a/lib/cli.rb +++ /dev/null @@ -1,53 +0,0 @@ -# frozen_string_literal: true - -require 'thor' - -require 'cli/commands/list' -require 'cli/commands/search' -require 'faker/version' - -module Faker - module CLI - class Base < Thor - Error = Class.new(StandardError) - # Skip default deprecation warning output; the CLI will display that. - Gem::Deprecate.skip_during do - desc 'version', 'Faker version' - def version - puts "v#{Faker::VERSION}" - end - map %w[--version -v] => :version - - desc 'list', 'List all Faker constants' - method_option :help, aliases: '-h', type: :boolean, - desc: 'Display usage information' - method_option :show_methods, aliases: '-m', type: :boolean, default: true, - desc: 'Display Faker constants with methods' - method_option :verbose, aliases: '-v', type: :boolean, - desc: 'Include sample Faker output' - def list(*) - if options[:help] - invoke :help, ['list'] - else - Faker::CLI::Commands::List.new(options).execute - end - end - - desc 'search [Faker]', 'Search Faker method(s)' - method_option :help, aliases: '-h', type: :boolean, - desc: 'Display usage information' - method_option :show_methods, aliases: '-m', type: :boolean, default: true, - desc: 'Display Faker constants with methods' - method_option :verbose, aliases: '-v', type: :boolean, - desc: 'Include sample Faker output' - def search(query) - if options[:help] - invoke :help, ['search'] - else - Faker::CLI::Commands::Search.new(options).execute(query) - end - end - end - end - end -end diff --git a/lib/cli/README.md b/lib/cli/README.md deleted file mode 100644 index 627b1ffb99..0000000000 --- a/lib/cli/README.md +++ /dev/null @@ -1,55 +0,0 @@ -# faker (cli) - -## Usage - -1.) Run a quick lookup - -```bash -$ faker search name -# Faker::SwordArtOnline -# └── real_name -# └── game_name -# Faker::Superhero -# └── name -# .... -``` - -2.) List methods - -```sh -$ faker list -# Faker::BackToTheFuture -# ├── quote -# ├── date -# └── character -# Faker::Finance -# └── credit_card -# .... -``` - -`faker` also includes an option to display sample output via the `--verbose` or `-v` flag. :wink: - -3.) - -```sh -$ faker list -v -# Faker::Appliance -# ├── brand=> Whirlpool -# └── equipment=> Sump pump -# Faker::UmphreysMcgee -# └── song=> Headphones & Snowcones -$ faker search name -v -# Faker::App -# └── name=> Subin -# Faker::Address -# └── street_name=> Percy Landing -# .... -``` - -## Features! :sunglasses: :dancers: - -- [x] List classes with methods E.g. Faker::FunnyName is displayed with `.name`,`.first_name` e.t.c. -- [x] Expand search to Faker::Base sub classes -- [x] Paginate results :book: - -![screenshot 2019-01-05 at 03 02 08](https://user-images.githubusercontent.com/17295175/50717135-59d85780-1096-11e9-8d0d-eca95646644d.jpg) diff --git a/lib/cli/command.rb b/lib/cli/command.rb deleted file mode 100644 index 277e7a12e2..0000000000 --- a/lib/cli/command.rb +++ /dev/null @@ -1,24 +0,0 @@ -# frozen_string_literal: true - -require 'forwardable' - -require_relative 'renderer' - -module Faker - module CLI - class Command - extend Forwardable - - def_delegators :command, :run - attr_reader :options - - def initialize(options) - @options = options - end - - def render(result, output) - Renderer.call(result, options, output) - end - end - end -end diff --git a/lib/cli/commands/list.rb b/lib/cli/commands/list.rb deleted file mode 100644 index 060c88db77..0000000000 --- a/lib/cli/commands/list.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -require_relative '../command' -require_relative '../reflectors/list' - -module Faker - module CLI - module Commands - class List < Command - def execute(output: $stdout) - result = Reflectors::List.call(options) - render(result, output) - end - end - end - end -end diff --git a/lib/cli/commands/search.rb b/lib/cli/commands/search.rb deleted file mode 100644 index ec04ecc73a..0000000000 --- a/lib/cli/commands/search.rb +++ /dev/null @@ -1,29 +0,0 @@ -# frozen_string_literal: true - -require_relative '../command' -require_relative '../reflectors/search' - -module Faker - module CLI - module Commands - class Search < Command - def execute(input, output: $stdout) - result = Reflectors::Search.call(input) - render(result, output) - end - - private - - def render(result, output) - return not_found(output) if result.empty? - - super(result, output) - end - - def not_found(output) - output.puts "\nSorry, we couldn't find a match 😢", "\n" - end - end - end - end -end diff --git a/lib/cli/reflector.rb b/lib/cli/reflector.rb deleted file mode 100644 index 7ff45b35a1..0000000000 --- a/lib/cli/reflector.rb +++ /dev/null @@ -1,48 +0,0 @@ -# frozen_string_literal: true - -require 'faker' - -module Faker - module CLI - # Abstract `Faker` Reflector - introspects the `Faker` module - # - # @api private - # @abstract - # - class Reflector - Faker::Base.class_eval do - # Select `Faker` subclasses - # @return [Array] `Faker::Base` sub classes - def self.descendants - @descendants ||= ObjectSpace.each_object(Class).select do |klass| - klass < self - end - end - - # Select public class methods - # @return [Array] public methods - def self.my_singleton_methods - singleton_methods(false).select { |m| respond_to?(m) } - end - end - - attr_reader :descendants_with_methods - - def initialize(*) - @descendants_with_methods = Hash.new { |h, k| h[k] = [] } - end - - protected - - def store(descendant, methods) - return if methods.empty? - - descendants_with_methods[descendant].concat(methods) - end - - def faker_descendants - @faker_descendants ||= Faker::Base.descendants - end - end - end -end diff --git a/lib/cli/reflectors/list.rb b/lib/cli/reflectors/list.rb deleted file mode 100644 index 719188b3bc..0000000000 --- a/lib/cli/reflectors/list.rb +++ /dev/null @@ -1,39 +0,0 @@ -# frozen_string_literal: true - -require_relative '../reflector' - -module Faker - module CLI - module Reflectors - # List command reflector - # @api private - # - class List < Reflector - attr_reader :show_methods - - def self.call(options) - new(options).call - end - - def initialize(options = {}) - @show_methods = options[:show_methods] - - super - end - - def call - show_methods ? all_descendants_with_methods : faker_descendants - end - - private - - def all_descendants_with_methods - faker_descendants.each do |descendant| - store(descendant, descendant.my_singleton_methods) - end - descendants_with_methods - end - end - end - end -end diff --git a/lib/cli/reflectors/search.rb b/lib/cli/reflectors/search.rb deleted file mode 100644 index 48e88a0276..0000000000 --- a/lib/cli/reflectors/search.rb +++ /dev/null @@ -1,46 +0,0 @@ -# frozen_string_literal: true - -require_relative '../reflector' - -module Faker - module CLI - module Reflectors - # Find command reflector - # @api private - # - class Search < Reflector - attr_reader :query - - def self.call(query) - new(query).call - end - - def initialize(query) - @query = query - - super - end - - def call - search_descendants_matching_query - descendants_with_methods - end - - private - - def search_descendants_matching_query - faker_descendants.each do |descendant| - methods = descendant.my_singleton_methods - matching = methods.select { |method| query_matches?(method.to_s) } - store(descendant, matching) - end - end - - def query_matches?(method_name) - method_name_parts = method_name.split(/_/).reject(&:empty?) - query.match(/#{method_name_parts.join('|')}/) - end - end - end - end -end diff --git a/lib/cli/renderer.rb b/lib/cli/renderer.rb deleted file mode 100644 index 0e3f635067..0000000000 --- a/lib/cli/renderer.rb +++ /dev/null @@ -1,93 +0,0 @@ -# frozen_string_literal: true - -require 'pastel' -require 'tty/pager' -require 'tty/screen' -require 'tty/tree' - -module Faker - module CLI - class Renderer - attr_reader :crayon, :hash, :options, :output, :pager - - def self.call(*args) - new(*args).call - end - - def initialize(hash, options, output) - @hash = hash - @options = options - @output = output - @crayon = Pastel.new(enabled: output.tty?) - @pager = TTY::Pager.new(command: 'less -R') - end - - def call - if paginable? - pager.page(render) - else - output.puts(render) - end - end - - def render - tree.render - end - - def tree - @tree ||= TTY::Tree.new(build_tree) - end - - def paginable? - gt_screen_height? && output.tty? - end - - def gt_screen_height? - tree.nodes.size > TTY::Screen.height - end - - private - - def build_tree - results = hash.reduce({}) do |h, (const, methods)| - h.merge! node(const, methods&.sort) - end - - results.sort_by(&:to_s).to_h - end - - def node(const, methods) - { - crayon.green(const.to_s) => leaf(const, methods) - } - end - - def leaf(const, methods) - (methods || []).map { |m| crayon.cyan(*leaf_args(m, const)) } - end - - def leaf_args(method, const) - [method.to_s].tap { |arr| verbose_output(method, const, arr) if verbose? } - end - - def verbose? - options[:verbose] - end - - def verbose_output(method, const, arr) - fake, message = faker_method(method, const) - arr << crayon.dim.white("=> #{fake}") << crayon.dim.magenta.bold(message.to_s) - end - - def faker_method(method, const) - [const.public_send(method), ensure_method_is_supported(method, const)] - rescue ArgumentError => _exception - ['N/A', ''] - end - - def ensure_method_is_supported(method, const) - const.respond_to?(:"_deprecated_#{method}") ? ' ( WILL BE DEPRECATED )' : '' - end - end - end -end diff --git a/test/cli/commands/test_list.rb b/test/cli/commands/test_list.rb deleted file mode 100644 index 224a196cf8..0000000000 --- a/test/cli/commands/test_list.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -require_relative '../../test_helper' - -require 'cli' - -describe Faker::CLI::Commands::List do - before do - @list = Faker::CLI::Commands::List - end - - describe 'when single `list` command' do - it 'executes successfully' do - output = StringIO.new - options = {} - - command = @list.new(options) - command.execute(output: output) - - assert_match(/Faker/, output.string) - assert_equal(true, output.string.lines.size.positive?) - end - end - - describe 'when `list -v` verbose command' do - it 'executes successfully' do - output = StringIO.new - options = { verbose: true } - - command = @list.new(options) - command.execute(output: output) - constant = output.string.lines[0] - - assert_match(/Faker::/, constant) - end - end -end diff --git a/test/cli/commands/test_search.rb b/test/cli/commands/test_search.rb deleted file mode 100644 index 89a22fd326..0000000000 --- a/test/cli/commands/test_search.rb +++ /dev/null @@ -1,36 +0,0 @@ -# frozen_string_literal: true - -require_relative '../../test_helper' - -require 'cli' - -describe Faker::CLI::Commands::Search do - before do - @search = Faker::CLI::Commands::Search - end - - describe 'when query object exists' do - it 'returns results' do - output = StringIO.new - options = {} - - command = @search.new(options) - command.execute('image', output: output) - - assert_match(/Faker/, output.string) - assert_equal(true, output.string.lines.size.positive?) - end - end - - describe 'when query object does not exist' do - it 'returns a not found message' do - output = StringIO.new - options = {} - - command = @search.new(options) - command.execute('foobar', output: output) - - assert_match(/Sorry, we couldn't find a match/, output.string) - end - end -end diff --git a/test/cli/integration/test_list.rb b/test/cli/integration/test_list.rb deleted file mode 100644 index 6f1e9329f8..0000000000 --- a/test/cli/integration/test_list.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -require_relative '../../test_helper' - -require 'cli' - -describe '`faker list` command' do - it 'executes `faker help list` command successfully' do - output = `faker help list` - expected_output = <<~OUT - Usage: - faker list - - Options: - -h, [--help], [--no-help] # Display usage information - -m, [--show-methods], [--no-show-methods] # Display Faker constants with methods - # Default: true - -v, [--verbose], [--no-verbose] # Include sample Faker output - - List all Faker constants - OUT - - assert_match(expected_output, output) - end - - it 'executes `faker list` command successfully' do - output = `faker list` - - assert_match(/Faker::/, output) - end - - it 'executes `faker list -v` command successfully' do - output = `faker list -v` - - assert_match(/Faker::/, output) - end -end diff --git a/test/cli/integration/test_search.rb b/test/cli/integration/test_search.rb deleted file mode 100644 index 0b3e1a21de..0000000000 --- a/test/cli/integration/test_search.rb +++ /dev/null @@ -1,42 +0,0 @@ -# frozen_string_literal: true - -require_relative '../../test_helper' - -require 'cli' - -describe '`faker search` command' do - it 'executes `faker help search` command successfully' do - output = `faker help search` - expected_output = <<~OUT - Usage: - faker search [Faker] - - Options: - -h, [--help], [--no-help] # Display usage information - -m, [--show-methods], [--no-show-methods] # Display Faker constants with methods - # Default: true - -v, [--verbose], [--no-verbose] # Include sample Faker output - - Search Faker method(s) - OUT - - assert_match(expected_output, output) - end - - describe 'when search query exists' do - it 'returns results' do - output = `faker search name` - - assert_match(/Faker::/, output) - assert_match(/└──/, output) - end - end - - describe 'when search query does not exist' do - it 'returns a not found message' do - output = `faker search foobar` - - assert_match(/Sorry, we couldn't find a match/, output) - end - end -end diff --git a/test/cli/integration/test_version.rb b/test/cli/integration/test_version.rb deleted file mode 100644 index 7fa85f7185..0000000000 --- a/test/cli/integration/test_version.rb +++ /dev/null @@ -1,14 +0,0 @@ -# frozen_string_literal: true - -require_relative '../../test_helper' - -require 'cli' - -describe '`faker version` command' do - it 'executes `faker version` command successfully' do - output = `faker version` - expected_output = 'v1.9.4' - - assert_match(expected_output, output) - end -end diff --git a/test/cli/reflectors/test_list.rb b/test/cli/reflectors/test_list.rb deleted file mode 100644 index 4e33ea3e14..0000000000 --- a/test/cli/reflectors/test_list.rb +++ /dev/null @@ -1,46 +0,0 @@ -# frozen_string_literal: true - -require_relative '../../test_helper' - -require 'cli' - -describe Faker::CLI::Reflectors::List do - before do - @reflector = Faker::CLI::Reflectors::List - end - - describe '#call' do - describe 'when show methods is enabled' do - it 'returns all descendants and their methods' do - options = { show_methods: true } - - reflector = @reflector.new(options) - result = reflector.call - - sample_result = result.first - sample_result_key = sample_result.first.to_s - sample_result_value = sample_result.last - - assert_kind_of(Hash, result) - assert_match(/Faker::/, sample_result_key) - assert_kind_of(Array, sample_result_value) - refute_empty(sample_result_value) - end - end - - describe 'when show methods is disabled' do - it 'returns only the descendants' do - options = { show_methods: false } - - reflector = @reflector.new(options) - result = reflector.call - - sample_result = result.first.to_s - - assert_kind_of(Array, result) - assert_match(/Faker::/, sample_result) - refute_empty(result) - end - end - end -end diff --git a/test/cli/reflectors/test_search.rb b/test/cli/reflectors/test_search.rb deleted file mode 100644 index d83f277f8e..0000000000 --- a/test/cli/reflectors/test_search.rb +++ /dev/null @@ -1,37 +0,0 @@ -# frozen_string_literal: true - -require_relative '../../test_helper' - -require 'cli' - -describe Faker::CLI::Reflectors::Search do - before do - @reflector = Faker::CLI::Reflectors::Search - end - - describe '#call' do - describe 'when a match is found' do - it 'it returns the list of matches' do - query = 'firstname' - - reflector = @reflector.new(query) - result = reflector.call - - assert_includes(result[Faker::Name], :first_name) - assert_kind_of(Hash, result) - end - end - - describe 'when no match is found' do - it 'returns an empty hash' do - query = 'foobar' - - reflector = @reflector.new(query) - result = reflector.call - - assert_empty(result) - assert_kind_of(Hash, result) - end - end - end -end diff --git a/test/cli/test_renderer.rb b/test/cli/test_renderer.rb deleted file mode 100644 index bf44f91e9a..0000000000 --- a/test/cli/test_renderer.rb +++ /dev/null @@ -1,158 +0,0 @@ -# frozen_string_literal: true - -require_relative '../test_helper' - -require 'cli' - -module MockFaker - class Foo - def self.bar - 'bar' - end - end -end - -describe Faker::CLI::Renderer do - before do - @renderer = Faker::CLI::Renderer - end - - describe '#call' do - # TODO: describe 'when paginable object' - - describe 'when non paginable interface' do - it 'renders the full content' do - hash = { MockFaker::Foo => [:bar] } - options = {} - output = StringIO.new - - renderer = @renderer.new(hash, options, output) - renderer.call - - assert_equal "MockFaker::Foo\n└── bar\n", output.string - end - end - end - - describe '#render' do - describe 'when the verbose option is enabled' do - it 'renders methods with data' do - hash = { MockFaker::Foo => [:bar] } - options = { verbose: true } - output = StringIO.new - - renderer = @renderer.new(hash, options, output) - result = renderer.render - - assert_equal "MockFaker::Foo\n└── bar=> bar\n", result - assert_empty output.string - end - end - - describe 'when the verbose option is disabled' do - it 'renders methods only' do - hash = { MockFaker::Foo => [:bar] } - options = { verbose: false } - output = StringIO.new - - renderer = @renderer.new(hash, options, output) - result = renderer.render - - assert_equal "MockFaker::Foo\n└── bar\n", result - assert_empty output.string - end - end - end - - describe '#tree' do - it 'returns the tree object' do - hash = { MockFaker::Foo => [:bar] } - options = {} - output = StringIO.new - - renderer = @renderer.new(hash, options, output) - result = renderer.tree - - assert_equal true, result.nodes.size.positive? - assert_kind_of TTY::Tree, result - assert_empty output.string - end - - it 'memoizes the tree object' do - hash = { MockFaker::Foo => [:bar] } - options = {} - output = StringIO.new - - renderer = @renderer.new(hash, options, output) - first_result = renderer.tree - second_result = renderer.tree - - assert_equal first_result, second_result - end - end - - describe '#gt_screen_height?' do - describe 'when tree size is greater than the screen size' do - it 'returns true' do - hash = { MockFaker::Foo => [:bar] } - options = {} - output = StringIO.new - - TTY::Screen.stub :height, 1 do - renderer = @renderer.new(hash, options, output) - result = renderer.gt_screen_height? - - assert_equal true, result - end - end - end - - describe 'when the tree size is less than the screen size' do - it 'returns false' do - hash = { MockFaker::Foo => [:bar] } - options = {} - output = StringIO.new - - renderer = @renderer.new(hash, options, output) - result = renderer.gt_screen_height? - - assert_equal false, result - end - end - end - - describe '#paginable?' do - describe 'when interactive terminal' do - it 'returns true' do - hash = { MockFaker::Foo => [:bar] } - options = {} - - output_mock = Minitest::Mock.new - - def output_mock.tty? - true - end - - TTY::Screen.stub :height, 1 do - renderer = @renderer.new(hash, options, output_mock) - result = renderer.paginable? - - assert_equal true, result - end - end - end - - describe 'when non-interactive terminal' do - it 'returns false' do - hash = { MockFaker::Foo => [:bar] } - options = {} - output = StringIO.new - - renderer = @renderer.new(hash, options, output) - result = renderer.paginable? - - assert_equal false, result - end - end - end -end diff --git a/unreleased_README.md b/unreleased_README.md index 2f755db48e..f0d45b4261 100644 --- a/unreleased_README.md +++ b/unreleased_README.md @@ -20,7 +20,6 @@ development. - [NOTE](#note) - [Installing](#installing) - [Usage](#usage) - - [CLI](#cli) - [Ensuring unique values](#ensuring-unique-values) - [Deterministic Random](#deterministic-random) - [Generators](#generators) @@ -67,14 +66,6 @@ Faker::Name.name #=> "Christophe Bartell" Faker::Internet.email #=> "kirsten.greenholt@corkeryfisher.info" ``` -### CLI - -Usage Instructions [available here](https://github.com/stympy/faker/blob/master/lib/cli/README.md) - -```bash -$ faker -``` - ### Ensuring unique values Prefix your method call with `unique`. For example: ```ruby