Skip to content

Commit

Permalink
Merge pull request #2 from akabiru/feature/list
Browse files Browse the repository at this point in the history
Add `fakerbot list` Command
  • Loading branch information
akabiru authored Aug 10, 2018
2 parents 2db523a + f9c9840 commit a8609a3
Show file tree
Hide file tree
Showing 12 changed files with 230 additions and 38 deletions.
2 changes: 1 addition & 1 deletion Gemfile.lock
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
PATH
remote: .
specs:
fakerbot (0.2.4)
fakerbot (0.3.0)
faker
pastel (~> 0.7.2)
thor (~> 0.20.0)
Expand Down
31 changes: 23 additions & 8 deletions lib/fakerbot/bot.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,37 +20,52 @@ def self.my_singleton_methods
end
end

attr_reader :matching_descendants, :query
attr_reader :descendants_with_methods, :query

def initialize(query)
@matching_descendants = Hash.new { |h, k| h[k] = [] }
def initialize(query = nil)
@descendants_with_methods = Hash.new { |h, k| h[k] = [] }
@query = query
end

class << self
def find(query)
new(query).find
end

def list(verbose: false)
new.list(verbose)
end
end

def find
search_descendants_matching_query
matching_descendants
descendants_with_methods
end

def list(verbose)
verbose ? all_descendants_with_methods : faker_descendants
end

private

def all_descendants_with_methods
faker_descendants.each do |faker|
store(faker, faker.my_singleton_methods)
end
descendants_with_methods
end

def search_descendants_matching_query
faker_descendants.each do |faker|
methods = faker.my_singleton_methods
matching = methods.select { |m| m.match?(/#{query}/i) }
save_matching(faker, matching)
store(faker, matching)
end
end

def save_matching(descendant, matching)
return if matching.empty?
matching_descendants[descendant].concat(matching)
def store(descendant, methods)
return if methods.empty?
descendants_with_methods[descendant].concat(methods)
end

def faker_descendants
Expand Down
16 changes: 15 additions & 1 deletion lib/fakerbot/cli.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
require 'thor'
require 'fakerbot/cli'
require 'fakerbot/version'
require 'fakerbot/commands/list'
require 'fakerbot/commands/search'

module FakerBot
Expand All @@ -16,11 +17,24 @@ def 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 :verbose, aliases: '-v', type: :boolean,
desc: 'Display Faker constants with methods'
def list(*)
if options[:help]
invoke :help, ['list']
else
FakerBot::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 :verbose, aliases: '-v', type: :boolean,
desc: 'Display Faker classes with methods'
desc: 'Display Faker constants methods with examples'
def search(query)
if options[:help]
invoke :help, ['search']
Expand Down
43 changes: 43 additions & 0 deletions lib/fakerbot/command.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# frozen_string_literal: true

require 'forwardable'
require 'pastel'
require 'tty/pager'
require 'tty/tree'

module FakerBot
class Command
extend Forwardable

def_delegators :command, :run

def pager
TTY::Pager.new(command: 'less -R')
end

def screen
TTY::Screen
end

def tree(input)
TTY::Tree.new do
input.each do |faker, methods|
node Pastel.new.green(faker.to_s) do
methods&.each { |m| leaf Pastel.new.cyan(m.to_s) }
end
end
end
end

def render(result, output = $stdout)
result_tree = tree(result)
view = result_tree.render
if screen.height < result_tree.nodes.size
# paginate when attached to terminal
output.tty? ? pager.page(view) : output.puts(view)
else
output.puts view
end
end
end
end
17 changes: 17 additions & 0 deletions lib/fakerbot/commands/list.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# frozen_string_literal: true

require_relative '../command'

module FakerBot
module Commands
class List < FakerBot::Command
def initialize(options)
@options = options
end

def execute(output: $stdout)
render FakerBot::Bot.list(verbose: @options[:verbose]), output
end
end
end
end
33 changes: 6 additions & 27 deletions lib/fakerbot/commands/search.rb
Original file line number Diff line number Diff line change
@@ -1,45 +1,24 @@
# frozen_string_literal: true

require 'pastel'
require 'tty/pager'
require 'tty/tree'
require 'fakerbot/bot'
require_relative '../command'

module FakerBot
module Commands
class Search
class Search < FakerBot::Command
def initialize(options)
@options = options
@pager = TTY::Pager.new(command: 'less -R')
@screen = TTY::Screen
end

def execute(input)
render FakerBot::Bot.find(input)
def execute(input, output: $stdout)
render FakerBot::Bot.find(input), output
end

private

attr_reader :screen, :pager

def render(result)
def render(result, output)
return not_found if result.empty?
output = tree(result)
if screen.height < output.nodes.size
pager.page output.render
else
puts output.render
end
end

def tree(input)
TTY::Tree.new do
input.each do |faker, methods|
node Pastel.new.green(faker.to_s) do
methods.each { |m| leaf Pastel.new.cyan(m.to_s) }
end
end
end
super(result, output)
end

def not_found
Expand Down
1 change: 1 addition & 0 deletions lib/fakerbot/templates/list/.gitkeep
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#
2 changes: 1 addition & 1 deletion lib/fakerbot/version.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
module FakerBot
VERSION = '0.2.4'.freeze
VERSION = '0.3.0'.freeze
end
30 changes: 30 additions & 0 deletions spec/integration/list_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# frozen_string_literal: true

RSpec.describe '`fakerbot list` command', type: :cli do
it 'executes `fakerbot help list` command successfully' do
output = `fakerbot help list`
expected_output = <<~OUT
Usage:
fakerbot list
Options:
-h, [--help], [--no-help] # Display usage information
-v, [--verbose], [--no-verbose] # Display Faker constants with methods
List all Faker constants
OUT

expect(output).to eq(expected_output)
end

it 'executes `fakerbot list` command successfully' do
output = `fakerbot list`
expect(output).to match(/Faker::/)
end

it 'executes `fakerbot list -v` command successfully' do
output = `fakerbot list -v`
expect(output).to match(/Faker::/)
expect(output).to match(/└──/)
end
end
34 changes: 34 additions & 0 deletions spec/integration/search_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
# frozen_string_literal: true

RSpec.describe '`fakerbot search` command', type: :cli do
it 'executes `fakerbot help search` command successfully' do
output = `fakerbot help search`
expected_output = <<~OUT
Usage:
fakerbot search [Faker]
Options:
-h, [--help], [--no-help] # Display usage information
-v, [--verbose], [--no-verbose] # Display Faker constants methods with examples
Search Faker method(s)
OUT

expect(output).to eq(expected_output)
end

context 'when search query exists' do
it 'returns results' do
output = `fakerbot search name`
expect(output).to match(/Faker::/)
expect(output).to match(/└──/)
end
end

context 'when search query does not exist' do
it 'returns a not found message' do
output = `fakerbot search asdasdhk`
expect(output).to match(/Sorry, we couldn't find a match/)
end
end
end
31 changes: 31 additions & 0 deletions spec/unit/list_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
require 'fakerbot/commands/list'

RSpec.describe FakerBot::Commands::List do
let(:output) { StringIO.new }
let(:options) { {} }
let(:command) { FakerBot::Commands::List.new(options) }

before do
command.execute(output: output)
end

context 'when single `list` command' do
it 'executes successfully' do
expect(output.string).to match(/Faker/)
expect(output.string.lines.size).to be_positive
end
end

context 'when `list -v` verbose command' do
let(:options) { { verbose: true } }

it 'executes successfully' do
constant = output.string.lines[0]
method = output.string.lines[1]

expect(constant).to match(/Faker::/)
expect(method).not_to match(/Faker::/)
expect(method).to match(/└──/)
end
end
end
28 changes: 28 additions & 0 deletions spec/unit/search_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
require 'fakerbot/commands/search'

RSpec.describe FakerBot::Commands::Search do
let(:output) { StringIO.new }
let(:options) { {} }
let(:command) { described_class.new(options) }

context 'when query object exists' do
before do
command.execute('image', output: output)
end

it 'returns results' do
expect(output.string).to match(/Faker/)
expect(output.string.lines.size).to be_positive
end
end

context 'when query object does not exist' do
before do
command.execute('hasjdhaksjd', output: output)
end

it 'returns nil' do
expect(output.string).to be_empty
end
end
end

0 comments on commit a8609a3

Please sign in to comment.