Skip to content

Commit

Permalink
Add support for Custom value parsers in the router
Browse files Browse the repository at this point in the history
  • Loading branch information
dougedey-shopify committed Sep 5, 2020
1 parent c414751 commit fed1a5c
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 3 deletions.
1 change: 1 addition & 0 deletions .rubocop.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Style/ClassVars:
Enabled: true
Exclude:
- lib/slackify/handlers/base.rb
- lib/slackify/parameter.rb

AllCops:
TargetRubyVersion: 2.6
Expand Down
1 change: 1 addition & 0 deletions lib/slackify.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
require 'slackify/engine'
require 'slackify/exceptions'
require 'slackify/handlers'
require 'slackify/parameter'
require 'slackify/router'

module Slackify
Expand Down
5 changes: 5 additions & 0 deletions lib/slackify/handlers/validator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,11 @@ def validate_parameters(parameters)

next if VALID_PARAMETER_TYPES.include?(type.to_sym)

type.constantize
next if Slackify::Parameter.supported_parameters.include?(type)

errors << "Invalid parameter type for: #{key}, '#{type}'."
rescue NameError
errors << "Invalid parameter type for: #{key}, '#{type}'."
end
errors
Expand Down
22 changes: 22 additions & 0 deletions lib/slackify/parameter.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# frozen_string_literal: true

module Slackify
# Base parameter class that any user defined parameters must inherit from
class Parameter
@@supported_parameters = []

class << self
# Any class inheriting from Slackify::Parameter will be added to
# the list of supported parameters
def inherited(subclass)
@@supported_parameters.push(subclass.to_s)
end

# Show a list of the parameters supported by the app. Since we do
# metaprogramming, we want to ensure we can only call defined parameter
def supported_parameters
@@supported_parameters
end
end
end
end
9 changes: 6 additions & 3 deletions lib/slackify/router.rb
Original file line number Diff line number Diff line change
Expand Up @@ -80,15 +80,18 @@ def parse_by_spec(spec, raw_arguments)
processed_spec = {}
spec.each do |key, value|
# coerce to the expected type
processed_spec[key] = case value.fetch(:type, 'string')
type = value.fetch(:type, 'string')
processed_spec[key] = case type
when :int
processed_args[key].to_i
when :float
processed_args[key].to_f
when :bool
when :boolean
ActiveModel::Type::Boolean.new.cast(processed_args[key])
else
when :string
processed_args[key]
else
Object.const_get(type).new(processed_args[key]).parse
end
end

Expand Down
5 changes: 5 additions & 0 deletions test/dummy/app/handlers/dummy_handler.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,5 +44,10 @@ def method_3_command(params)
"string: #{params[:command_arguments][:string_param]}, "\
"float: #{params[:command_arguments][:float_param]}"
end

def method_4_command(params)
puts "this takes a user arg; "\
"user: #{params[:command_arguments][:user_param]}"
end
end
end
15 changes: 15 additions & 0 deletions test/dummy/app/models/user_param.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# frozen_string_literal: true

class UserParam < Slackify::Parameter
def initialize(value)
@value = value
end

def parse
if @value == 'W12345TG'
"Doug Edey"
else
"Foo"
end
end
end
7 changes: 7 additions & 0 deletions test/dummy/config/handlers.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,3 +17,10 @@
- bool_param: boolean
action: method_3_command
name: method 3

- description: method 4 with a custom parsed parameter
base_command: "method4"
parameters:
- user_param: UserParam
action: method_4_command
name: method 4
6 changes: 6 additions & 0 deletions test/unit/router_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,12 @@ class RouterTest < ActiveSupport::TestCase
end
end

test "parameters can be processed by a custom parser" do
assert_output(/this takes a user arg; user: Doug Edey/) do
Slackify::Router.call_command('method4 user_param=W12345TG', {})
end
end

test "Only one command gets called in the event of two regex match. Only the first match is called" do
assert_output(/cool_command called/) do
Slackify::Router.call_command('wazza foo', {})
Expand Down

0 comments on commit fed1a5c

Please sign in to comment.