Skip to content

Commit

Permalink
Merge pull request #39 from GhostGroup/feature/20-add-list-matcher
Browse files Browse the repository at this point in the history
Allow list to accept filter and match on class name
  • Loading branch information
akabiru authored Jul 31, 2019
2 parents a5ebe64 + a721311 commit 39668ee
Show file tree
Hide file tree
Showing 6 changed files with 128 additions and 13 deletions.
2 changes: 1 addition & 1 deletion .ruby-version
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.4.0
2.5.3
5 changes: 3 additions & 2 deletions lib/faker/bot.rb
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,12 @@ def version
desc: 'Display Faker constants with methods'
method_option :verbose, aliases: '-v', type: :boolean,
desc: 'Include sample Faker output'
def list(*)
def list(filter = nil)
if options[:help]
invoke :help, ['list']
else
Faker::Bot::Commands::List.new(options).execute
filter_options = options.merge(filter: filter)
Faker::Bot::Commands::List.new(filter_options).execute
end
end

Expand Down
13 changes: 13 additions & 0 deletions lib/faker/bot/commands/list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,19 @@ def execute(output: $stdout)
result = Reflectors::List.call(options)
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, that class doesn't exist 😢", "\n",
'Try something like `Faker::Beer` or `Beer`.', "\n"
end
end
end
end
Expand Down
22 changes: 18 additions & 4 deletions lib/faker/bot/reflectors/list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,43 @@ module Reflectors
# @api private
#
class List < Reflector
attr_reader :filter
attr_reader :show_methods

def self.call(options)
new(options).call
end

def initialize(options = {})
@filter = options[:filter]
@show_methods = options[:show_methods]

super
end

def call
show_methods ? all_descendants_with_methods : faker_descendants
show_methods ? list_descendants_with_methods : list_descendants
end

private

def all_descendants_with_methods
def list_descendants_with_methods
list_descendants
descendants_with_methods
end

def list_descendants
faker_descendants.each do |descendant|
store(descendant, descendant.my_singleton_methods)
if filter_matches_class_name?(descendant.to_s)
store(descendant, descendant.my_singleton_methods)
end
end
descendants_with_methods
descendants_with_methods.keys
end

def filter_matches_class_name?(class_name)
return true unless filter
class_name.match(/#{filter}/)
end
end
end
Expand Down
30 changes: 25 additions & 5 deletions spec/faker/bot/commands/list_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,23 +7,43 @@
let(:options) { {} }
let(:command) { Faker::Bot::Commands::List.new(options) }

before do
command.execute(output: output)
end

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

context 'when passing a filter option' do
let(:options) { super().merge(filter: filter) }

context 'when the filter matches' do
let(:filter) { 'Cannabis' }

it 'executes successfully' do
command.execute(output: output)
expect(output.string).to match(/Faker/)
expect(output.string.lines.size).to be_positive
end
end

context 'when the filter does not match' do
let(:filter) { 'foobar' }

it 'returns a not found message' do
command.execute(output: output)
expect(output.string).to match(/Sorry, that class doesn't exist/)
end
end
end
end

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

it 'executes successfully' do
command.execute(output: output)
constant = output.string.lines[0]

expect(constant).to match(/Faker::/)
end
end
Expand Down
69 changes: 68 additions & 1 deletion spec/faker/bot/reflectors/list_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,44 @@
expect(sample_result_value).to be_a(Array)
expect(sample_result_value).not_to be_empty
end

context 'when passing a filter' do
context 'when filtering by full class name' do
it 'returns filtered descendants and their methods' do
options = { show_methods: true, filter: 'Faker::Beer' }

reflector = described_class.new(options)
result = reflector.call

sample_result = result.first
sample_result_key = sample_result.first.to_s
sample_result_value = sample_result.last

expect(result).to be_a(Hash)
expect(sample_result_key).to eq('Faker::Beer')
expect(sample_result_value).to be_a(Array)
expect(sample_result_value).not_to be_empty
end
end

context 'when filtering by partial class name' do
it 'returns filtered descendants and their methods' do
options = { show_methods: true, filter: 'Beer' }

reflector = described_class.new(options)
result = reflector.call

sample_result = result.first
sample_result_key = sample_result.first.to_s
sample_result_value = sample_result.last

expect(result).to be_a(Hash)
expect(sample_result_key).to eq('Faker::Beer')
expect(sample_result_value).to be_a(Array)
expect(sample_result_value).not_to be_empty
end
end
end
end

context 'when show methods is disabled' do
Expand All @@ -28,13 +66,42 @@

reflector = described_class.new(options)
result = reflector.call

sample_result = result.first.to_s

expect(result).to be_a(Array)
expect(result).not_to be_empty
expect(sample_result).to match(/Faker::/)
end

context 'when passing a filter' do
context 'when filtering by full class name' do
it 'returns filtered descendants and their methods' do
options = { show_methods: false, filter: 'Faker::Beer' }

reflector = described_class.new(options)
result = reflector.call
sample_result = result.first.to_s

expect(result).to be_a(Array)
expect(result).not_to be_empty
expect(sample_result).to eq('Faker::Beer')
end
end

context 'when filtering by partial class name' do
it 'returns filtered descendants and their methods' do
options = { show_methods: false, filter: 'Beer' }

reflector = described_class.new(options)
result = reflector.call
sample_result = result.first.to_s

expect(result).to be_a(Array)
expect(result).not_to be_empty
expect(sample_result).to eq('Faker::Beer')
end
end
end
end
end
end

0 comments on commit 39668ee

Please sign in to comment.