Skip to content

Commit

Permalink
Merge pull request #35 from akabiru/chore/documentation
Browse files Browse the repository at this point in the history
chore(docs): Add Code Level YARD Documentation 📖
  • Loading branch information
akabiru authored Aug 9, 2019
2 parents ce167be + 4d29fd2 commit ba70ce2
Show file tree
Hide file tree
Showing 8 changed files with 333 additions and 30 deletions.
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@
![faker-bot-demo](https://user-images.githubusercontent.com/17295175/62558993-c57be080-b882-11e9-972e-7588408d45c3.gif)

:book: [Code Documentation](https://www.rubydoc.info/github/faker-ruby/faker-bot)

## Installation

```bash
Expand Down
27 changes: 27 additions & 0 deletions lib/faker/bot/command.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,43 @@

module Faker
module Bot
# @abstract interface for [Command] objects
#
# @api private
#
class Command
extend Forwardable

def_delegators :command, :run

# [Command] options
#
# @return [Hash<Symbol, String => String, Boolean>]
#
# @api private
#
attr_reader :options

# Initialize the command
#
# @param options [Hash<Symbol, String => String, Boolean>]
# The command options
#
# @api public
#
def initialize(options)
@options = options
end

# Render the command result into [IO]
#
# @param result {Hash} the render tree
# @param output [IO]
#
# @return [IO]
#
# @api private
#
def render(result, output)
Renderer.call(result, options, output)
end
Expand Down
28 changes: 28 additions & 0 deletions lib/faker/bot/commands/list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,48 @@
module Faker
module Bot
module Commands
# Lists all [Faker<Base>] constants
#
# @api private
#
class List < Command
# Execute the `list` command
#
# @return [IO]
#
# @api private
#
def execute(output: $stdout)
result = Reflectors::List.call(options)
render(result, output)
end

private

# Render the search results
# * Return #not_found when there're no matching results
#
# @param result [Hash] the render tree
# @param output [IO]
#
# @return [IO]
#
# @api private
#
def render(result, output)
return not_found(output) if result.empty?

super(result, output)
end

# Render a bespoke "not found" message
#
# @param output [IO]
#
# @return [IO]
#
# @api private
#
def not_found(output)
output.puts "\nSorry, that class doesn't exist 😢", "\n",
'Try something like `Faker::Beer` or `Beer`.', "\n"
Expand Down
28 changes: 28 additions & 0 deletions lib/faker/bot/commands/search.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,48 @@
module Faker
module Bot
module Commands
# Runs a search against [Faker<Base>] methods and returns matching results
#
# @api private
#
class Search < Command
# Execute the `search` command
#
# @return [IO]
#
# @api private
#
def execute(input, output: $stdout)
result = Reflectors::Search.call(input)
render(result, output)
end

private

# Render the search results
# * Return #not_found when there're no matching results
#
# @param result [Hash] the render tree
# @param output [IO]
#
# @return [IO]
#
# @api private
#
def render(result, output)
return not_found(output) if result.empty?

super(result, output)
end

# Render a bespoke "not found" message
#
# @param output [IO]
#
# @return [IO]
#
# @api private
#
def not_found(output)
output.puts "\nSorry, we couldn't find a match 😢", "\n"
end
Expand Down
55 changes: 50 additions & 5 deletions lib/faker/bot/reflector.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,45 +4,90 @@

module Faker
module Bot
# Abstract `Faker` Reflector - introspects the `Faker` module
# @abstract `Faker::Base` Reflection object
# * Introspects the `Faker::Base` class and it's descendants
#
# @api private
# @abstract
#
class Reflector
Faker::Base.class_eval do
# Skip default deprecation warning output; the CLI will display that.
Gem::Deprecate.skip = true

# Select `Faker` subclasses
# @return [Array] `Faker::Base` sub classes
# Select [Faker<Base>] subclasses
#
# @return [Array<Class>] `Faker::Base` subclasses
#
# @api private
#
def self.descendants
@descendants ||= ObjectSpace.each_object(Class).select do |klass|
klass < self
end
end

# Select public class methods
# @return [Array] public methods
#
# @return [Array] singleton public methods
#
# @api private
#
def self.my_singleton_methods
singleton_methods(false).select { |m| respond_to?(m) }
end
end

# @example Faker::Base subclasses with their methods
# { Faker::Marketing => [:buzzwords], Faker::Artist => [:name] }
#
# @return [Hash[Class => [Array<Symbol>]]
#
# @api private
#
attr_reader :descendants_with_methods

# Alternate constructor
#
# @see #initialize
# @see #call
#
# @api public
#
def self.call(*args)
new(*args).call
end

# Initialize the reflector
#
# @api public
#
def initialize(*)
@descendants_with_methods = Hash.new { |h, k| h[k] = [] }
end

protected

# Adds a `Faker::Base` descendant methods to the method list
#
# @param descendant [Class] The `Faker::Base` subclass
# @param methods [Array<Symbol>] The `Faker::Base` subclass methods
#
# @return [Array<Symbol>]
#
# @api private
#
def store(descendant, methods)
return if methods.empty?

descendants_with_methods[descendant].concat(methods)
end

# Get all `Faker::Base` subclasses
#
# @return [Array<Class>]
#
# @api public
#
def faker_descendants
@faker_descendants ||= Faker::Base.descendants
end
Expand Down
60 changes: 53 additions & 7 deletions lib/faker/bot/reflectors/list.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,35 +5,74 @@
module Faker
module Bot
module Reflectors
# List command reflector
# Reflection object that lists all `Faker::Base` subclasses
#
# @api private
#
class List < Reflector
# Output filter
#
# @return [String, nil]
#
# @api private
#
attr_reader :filter
# Boolean flag on whether to list methods or not
#
# @return [Boolean, nil]
#
# @api private
#
attr_reader :show_methods

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

# Initialize list reflector
#
# @param options [Hash{Symbol => Boolean, nil}] Reflector options
# @option options [Boolean, nil] :show_method
# Show methods in listing boolean flag
#
# @api public
#
def initialize(options = {})
@filter = options[:filter]
@show_methods = options[:show_methods]

super
end

# List `Faker::Base` subclasses
#
# @return [Hash<Class => <Array<Symbol>>] when #show_methods is truthy
#
# @api private
#
def call
show_methods ? list_descendants_with_methods : list_descendants
if show_methods
list_descendants_with_methods
else
list_descendants
end
end

private

# List `Faker::Base` subclasses with methods
#
# @return [Hash{Class => <Array<Symbol>}]
#
# @api private
#
def list_descendants_with_methods
list_descendants
descendants_with_methods
end

# List `Faker::Base` subclasses
#
# @return [Array<Class>]
#
# @api private
#
def list_descendants
faker_descendants.each do |descendant|
if filter_matches_class_name?(descendant.to_s)
Expand All @@ -43,9 +82,16 @@ def list_descendants
descendants_with_methods.keys
end

# Match against class name when filter is defined
#
# @return [Boolean]
#
# @api private
#
def filter_matches_class_name?(class_name)
return true unless filter
class_name.match(/#{filter}/)

class_name.match(/#{filter}/i)
end
end
end
Expand Down
Loading

0 comments on commit ba70ce2

Please sign in to comment.