pug-bot 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/Gemfile +3 -0
- data/LICENSE +21 -0
- data/README.md +135 -0
- data/Rakefile +29 -0
- data/lib/pug/action/controller.rb +65 -0
- data/lib/pug/action/enumerator.rb +33 -0
- data/lib/pug/action/input.rb +26 -0
- data/lib/pug/action/output.rb +21 -0
- data/lib/pug/bot.rb +53 -0
- data/lib/pug/clients/factory.rb +23 -0
- data/lib/pug/configuration.rb +43 -0
- data/lib/pug/interfaces/action.rb +35 -0
- data/lib/pug/interfaces/client.rb +22 -0
- data/lib/pug/keyword_handler.rb +59 -0
- data/lib/pug/message_handler.rb +76 -0
- data/lib/pug/number_parser.rb +22 -0
- data/lib/pug/results.rb +26 -0
- data/lib/pug/strings.rb +38 -0
- data/lib/pug/telegram_client.rb +72 -0
- data/lib/pug/terminal_client.rb +33 -0
- data/lib/pug/types/result.rb +57 -0
- data/lib/pug/version.rb +5 -0
- data/lib/pug.rb +41 -0
- data/pug-bot.gemspec +23 -0
- data/spec/lib/pug/action/controller_spec.rb +138 -0
- data/spec/lib/pug/action/enumerator_spec.rb +104 -0
- data/spec/lib/pug/bot_spec.rb +78 -0
- data/spec/lib/pug/clients/factory_spec.rb +24 -0
- data/spec/lib/pug/configuration_spec.rb +52 -0
- data/spec/lib/pug/keyword_handler_spec.rb +53 -0
- data/spec/lib/pug/message_handler_spec.rb +78 -0
- data/spec/lib/pug/number_parser_spec.rb +44 -0
- data/spec/lib/pug/types/result_spec.rb +32 -0
- data/spec/lib/spec_helpers/mock_action.rb +39 -0
- data/spec/lib/spec_helpers/mock_client.rb +32 -0
- metadata +169 -0
data/lib/pug/results.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pug
|
4
|
+
# Convenience methods for common Results
|
5
|
+
class Results
|
6
|
+
def self.unknown_input
|
7
|
+
Types::Result.error(Strings.unknown_input)
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.missing_actions
|
11
|
+
Types::Result.error(Strings.no_actions)
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.invalid_index(index)
|
15
|
+
Types::Result.error(Strings.unable_to_start_action(index))
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.enter_inputs(action_name)
|
19
|
+
Types::Result.info(Strings.enter_inputs(action_name))
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.no_action_running
|
23
|
+
Types::Result.error(Strings.no_action_running)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/pug/strings.rb
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pug
|
4
|
+
# Convenience methods for user facing strings
|
5
|
+
class Strings
|
6
|
+
def self.no_action_running
|
7
|
+
'There is no action currently running.'
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.error_occurred
|
11
|
+
'An error occurred acting on your action'
|
12
|
+
end
|
13
|
+
|
14
|
+
def self.finished_running(action_name)
|
15
|
+
"Finished running #{action_name}"
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.unable_to_start_action(index)
|
19
|
+
"Unable to start action at index: #{index}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.enter_inputs(action_name)
|
23
|
+
"Enter inputs for #{action_name}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.unknown_input
|
27
|
+
"Sorry, I don't understand that input."
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.no_actions
|
31
|
+
'There are no actions available to run. Did you set some up?'
|
32
|
+
end
|
33
|
+
|
34
|
+
def self.help(commands)
|
35
|
+
"These are available commands:\n#{commands}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'telegram/bot'
|
4
|
+
|
5
|
+
module Pug
|
6
|
+
# The client for Telegram interactions
|
7
|
+
class TelegramClient < Interfaces::Client
|
8
|
+
# @param token [String] API token for Telegram bot
|
9
|
+
# @param chat_id [String] Chat id for Telegram bot
|
10
|
+
def initialize(token, chat_id)
|
11
|
+
@token = token
|
12
|
+
@chat_id = chat_id
|
13
|
+
end
|
14
|
+
|
15
|
+
# Configures keyboard with provided markup
|
16
|
+
# This can be useful to make shortcuts for Commands
|
17
|
+
# @param keyboard_markup [Array<Array<String>>]
|
18
|
+
# A 2D array of strings used to populate on the keyboard
|
19
|
+
def configure_keyboard(keyboard_markup)
|
20
|
+
@keyboard_markup = keyboard_markup || []
|
21
|
+
end
|
22
|
+
|
23
|
+
# Override of {Interfaces::Client#listen}
|
24
|
+
# @yieldparam [String] text
|
25
|
+
def listen
|
26
|
+
perform_with_bot do |bot|
|
27
|
+
bot.listen do |message|
|
28
|
+
next if message.nil?
|
29
|
+
text = message.text
|
30
|
+
next if text.nil?
|
31
|
+
yield text
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
# Override of {Interfaces::Client#send_message}
|
37
|
+
# @return [void]
|
38
|
+
def send_message(message)
|
39
|
+
return if message.to_s.empty?
|
40
|
+
send_telegram_message(message)
|
41
|
+
end
|
42
|
+
|
43
|
+
private
|
44
|
+
|
45
|
+
def send_telegram_message(message)
|
46
|
+
reply_markup = Telegram::Bot::Types::ReplyKeyboardMarkup.new(
|
47
|
+
keyboard: @keyboard_markup || []
|
48
|
+
)
|
49
|
+
perform_with_bot do |bot|
|
50
|
+
bot.api.send_message(
|
51
|
+
chat_id: @chat_id,
|
52
|
+
text: message,
|
53
|
+
reply_markup: reply_markup
|
54
|
+
)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def client
|
59
|
+
return @client if @client
|
60
|
+
raise 'No Telegram token provided' if @token.to_s.empty?
|
61
|
+
@client = Telegram::Bot::Client.new(@token)
|
62
|
+
end
|
63
|
+
|
64
|
+
def perform_with_bot
|
65
|
+
yield client
|
66
|
+
rescue StandardError => ex
|
67
|
+
puts 'Error performing task with Telegram'
|
68
|
+
puts ex
|
69
|
+
puts ex.backtrace
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pug
|
4
|
+
# The client for Terminal interactions
|
5
|
+
class TerminalClient < Interfaces::Client
|
6
|
+
# Override of {Interfaces::Client#listen}
|
7
|
+
# @yieldparam [String] text
|
8
|
+
def listen
|
9
|
+
loop do
|
10
|
+
message = gets
|
11
|
+
yield message.chomp
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# Override of {Interfaces::Client#send_message}
|
16
|
+
# @return [void]
|
17
|
+
def send_message(message)
|
18
|
+
return if message.to_s.empty?
|
19
|
+
puts message.green
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# Helper class used to spice up Terminal output
|
25
|
+
class String
|
26
|
+
def colorize(color_code)
|
27
|
+
"\e[#{color_code}m#{self}\e[0m"
|
28
|
+
end
|
29
|
+
|
30
|
+
def green
|
31
|
+
colorize(32)
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Pug
|
4
|
+
module Types
|
5
|
+
# Encapsulates a sucess/failure result
|
6
|
+
# @!attribute type
|
7
|
+
# @return [Integer] the type of the Result
|
8
|
+
# @see Result::SUCCESS
|
9
|
+
# @see Result::INFO
|
10
|
+
# @see Result::ERROR
|
11
|
+
# @!attribute value
|
12
|
+
# @return [String] the value of the Result
|
13
|
+
# @note exists only for SUCCESS and INFO types
|
14
|
+
# @!attribute error
|
15
|
+
# @return [String] the output of the Action
|
16
|
+
# @note exists only for ERROR type
|
17
|
+
class Result
|
18
|
+
attr_reader :type, :value, :error
|
19
|
+
private_class_method :new
|
20
|
+
|
21
|
+
# @!group Types
|
22
|
+
SUCCESS = 0
|
23
|
+
INFO = 1
|
24
|
+
ERROR = 2
|
25
|
+
# @!endgroup
|
26
|
+
|
27
|
+
# @!visibility private
|
28
|
+
def initialize(type, value, error)
|
29
|
+
raise 'Invalid type' unless [SUCCESS, INFO, ERROR].include?(type)
|
30
|
+
@type = type
|
31
|
+
@value = value
|
32
|
+
@error = error
|
33
|
+
end
|
34
|
+
|
35
|
+
# Defines a SUCCESS Result
|
36
|
+
# @param value [String] value for Result
|
37
|
+
# @return [Result] with value and no error
|
38
|
+
def self.success(value)
|
39
|
+
new(SUCCESS, value, nil)
|
40
|
+
end
|
41
|
+
|
42
|
+
# Defines an INFO Result
|
43
|
+
# @param value [String] value for Result
|
44
|
+
# @return [Result] with value and no error
|
45
|
+
def self.info(value)
|
46
|
+
new(INFO, value, nil)
|
47
|
+
end
|
48
|
+
|
49
|
+
# Defines an ERROR Result
|
50
|
+
# @param error [String] error for Result
|
51
|
+
# @return [Result] with error and no value
|
52
|
+
def self.error(error)
|
53
|
+
new(ERROR, nil, error)
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
data/lib/pug/version.rb
ADDED
data/lib/pug.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pug/action/controller'
|
4
|
+
require 'pug/action/enumerator'
|
5
|
+
require 'pug/action/input'
|
6
|
+
require 'pug/action/output'
|
7
|
+
require 'pug/clients/factory'
|
8
|
+
require 'pug/interfaces/action'
|
9
|
+
require 'pug/interfaces/client'
|
10
|
+
require 'pug/types/result'
|
11
|
+
require 'pug/bot'
|
12
|
+
require 'pug/configuration'
|
13
|
+
require 'pug/keyword_handler'
|
14
|
+
require 'pug/message_handler'
|
15
|
+
require 'pug/number_parser'
|
16
|
+
require 'pug/results'
|
17
|
+
require 'pug/strings'
|
18
|
+
require 'pug/telegram_client'
|
19
|
+
require 'pug/terminal_client'
|
20
|
+
require 'pug/version'
|
21
|
+
|
22
|
+
# An automation framework for repetitive dev tasks
|
23
|
+
# @!attribute configuration
|
24
|
+
# @return [Configuration] the Pug config object
|
25
|
+
module Pug # :nodoc:
|
26
|
+
class << self
|
27
|
+
attr_writer :configuration
|
28
|
+
end
|
29
|
+
|
30
|
+
# Grabs the current Pug configuration
|
31
|
+
# @return [Configuration] the Pug config object
|
32
|
+
def self.configuration
|
33
|
+
default_type = Configuration::TELEGRAM
|
34
|
+
@configuration ||= Configuration.new(default_type)
|
35
|
+
end
|
36
|
+
|
37
|
+
# @yieldparam [Configuration] configuration
|
38
|
+
def self.configure
|
39
|
+
yield(configuration)
|
40
|
+
end
|
41
|
+
end
|
data/pug-bot.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'pug/version'
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'pug-bot'
|
5
|
+
s.version = Pug::VERSION
|
6
|
+
s.authors = ['Alex Figueroa']
|
7
|
+
s.email = 'alexjfigueroa [ at ] gmail [ dot ] com'
|
8
|
+
|
9
|
+
s.summary = 'An automation framework for repetitive dev tasks'
|
10
|
+
s.homepage = 'https://github.com/ajfigueroa/pug-bot'
|
11
|
+
s.license = 'MIT'
|
12
|
+
|
13
|
+
s.files = Dir['lib/**/*'] + %w(Gemfile LICENSE README.md Rakefile pug-bot.gemspec)
|
14
|
+
s.test_files = Dir['spec/**/*']
|
15
|
+
s.require_paths = ['lib']
|
16
|
+
s.required_ruby_version = '>= 2.3'
|
17
|
+
|
18
|
+
s.add_runtime_dependency 'telegram-bot-ruby', '~> 0.8.6', '>= 0.8.6'
|
19
|
+
|
20
|
+
s.add_development_dependency 'rspec', '~> 3.7.0', '>= 3.7.0'
|
21
|
+
s.add_development_dependency 'rubocop', '~> 0.53.0', '>= 0.53.0'
|
22
|
+
s.add_development_dependency 'yard', '~> 0.9.2', '>= 0.9.2'
|
23
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pug'
|
4
|
+
require_relative '../../spec_helpers/mock_action'
|
5
|
+
|
6
|
+
describe Pug::Action::Controller do
|
7
|
+
describe 'actions?' do
|
8
|
+
it 'should return false for nil actions' do
|
9
|
+
controller = Pug::Action::Controller.new(nil)
|
10
|
+
expect(controller.actions?).to be false
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should return false for empty actions' do
|
14
|
+
controller = Pug::Action::Controller.new([])
|
15
|
+
expect(controller.actions?).to be false
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should return true for any actions' do
|
19
|
+
action = MockAction.new('Command')
|
20
|
+
controller = Pug::Action::Controller.new([action])
|
21
|
+
expect(controller.actions?).to be true
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
describe 'running_action?' do
|
26
|
+
it 'should return false when not running a action' do
|
27
|
+
action = MockAction.new('Command')
|
28
|
+
controller = Pug::Action::Controller.new([action])
|
29
|
+
expect(controller.running_action?).to be false
|
30
|
+
end
|
31
|
+
|
32
|
+
it 'should return true when running a action' do
|
33
|
+
action = MockAction.new('Command')
|
34
|
+
controller = Pug::Action::Controller.new([action])
|
35
|
+
controller.start_action(0)
|
36
|
+
expect(controller.running_action?).to be true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
describe 'action_input' do
|
41
|
+
it 'should raise an error when not running a action' do
|
42
|
+
action = MockAction.new('Command')
|
43
|
+
controller = Pug::Action::Controller.new([action])
|
44
|
+
expect { controller.action_input }.to raise_error(RuntimeError)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should indicate false when running action requires no inputs' do
|
48
|
+
action = MockAction.new('Command', false)
|
49
|
+
controller = Pug::Action::Controller.new([action])
|
50
|
+
controller.start_action(0)
|
51
|
+
input = controller.action_input
|
52
|
+
expect(input.required?).to be false
|
53
|
+
end
|
54
|
+
|
55
|
+
it 'should indicate true when running action requires inputs' do
|
56
|
+
action = MockAction.new('Command', true)
|
57
|
+
controller = Pug::Action::Controller.new([action])
|
58
|
+
controller.start_action(0)
|
59
|
+
input = controller.action_input
|
60
|
+
expect(input.required?).to be true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
describe 'can_start_action?' do
|
65
|
+
it 'should return false for out of bounds index' do
|
66
|
+
action = MockAction.new('Command')
|
67
|
+
controller = Pug::Action::Controller.new([action])
|
68
|
+
expect(controller.can_start_action?(-1)).to be false
|
69
|
+
expect(controller.can_start_action?(1)).to be false
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should return false if there is already a running action' do
|
73
|
+
action = MockAction.new('Command')
|
74
|
+
controller = Pug::Action::Controller.new([action])
|
75
|
+
controller.start_action(0)
|
76
|
+
expect(controller.can_start_action?(0)).to be false
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'should return true if there is no already running action' do
|
80
|
+
action = MockAction.new('Command')
|
81
|
+
controller = Pug::Action::Controller.new([action])
|
82
|
+
expect(controller.can_start_action?(0)).to be true
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
describe 'start_action' do
|
87
|
+
it 'should not start running a action if it can not start action' do
|
88
|
+
action = MockAction.new('Command')
|
89
|
+
controller = Pug::Action::Controller.new([action])
|
90
|
+
controller.start_action(10)
|
91
|
+
expect(controller.running_action?).to be false
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should start running a action if it can start action' do
|
95
|
+
action = MockAction.new('Command')
|
96
|
+
controller = Pug::Action::Controller.new([action])
|
97
|
+
controller.start_action(0)
|
98
|
+
expect(controller.running_action?).to be true
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
describe 'run_action' do
|
103
|
+
it 'should return an error result if not running action' do
|
104
|
+
action = MockAction.new('Command')
|
105
|
+
controller = Pug::Action::Controller.new([action])
|
106
|
+
allow(action).to receive(:requires_inputs?) { true }
|
107
|
+
result = controller.run_action('')
|
108
|
+
expect(result.type).to eq(Pug::Types::Result::ERROR)
|
109
|
+
expect(result.error).to eq(Pug::Strings.no_action_running)
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'should return success with empty string if action has no output' do
|
113
|
+
action = MockAction.new('Command', true, nil)
|
114
|
+
controller = Pug::Action::Controller.new([action])
|
115
|
+
controller.start_action(0)
|
116
|
+
result = controller.run_action('')
|
117
|
+
expect(result.type).to eq(Pug::Types::Result::SUCCESS)
|
118
|
+
expect(result.value.value).to be_empty
|
119
|
+
end
|
120
|
+
|
121
|
+
it 'should return success with output if action has an output' do
|
122
|
+
action = MockAction.new('Command', true, 'Output')
|
123
|
+
controller = Pug::Action::Controller.new([action])
|
124
|
+
controller.start_action(0)
|
125
|
+
result = controller.run_action('')
|
126
|
+
expect(result.type).to eq(Pug::Types::Result::SUCCESS)
|
127
|
+
expect(result.value.value).to eq('Output')
|
128
|
+
end
|
129
|
+
|
130
|
+
it 'should clear the running action' do
|
131
|
+
action = MockAction.new('Command', true, 'Output')
|
132
|
+
controller = Pug::Action::Controller.new([action])
|
133
|
+
controller.start_action(0)
|
134
|
+
controller.run_action('')
|
135
|
+
expect(controller.running_action?).to be false
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pug'
|
4
|
+
require_relative '../../spec_helpers/mock_action'
|
5
|
+
|
6
|
+
describe Pug::Action::Enumerator do
|
7
|
+
describe 'names' do
|
8
|
+
it 'should return an empty array for nil actions' do
|
9
|
+
enumerator = Pug::Action::Enumerator.new
|
10
|
+
expect(enumerator.names(nil)).to be_empty
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'should return an empty array for empty actions' do
|
14
|
+
enumerator = Pug::Action::Enumerator.new
|
15
|
+
expect(enumerator.names([])).to be_empty
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should return a single enumeration for a single action' do
|
19
|
+
action = MockAction.new('Command')
|
20
|
+
enumerator = Pug::Action::Enumerator.new
|
21
|
+
expect(enumerator.names([action])).to eq(['0: Command'])
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'should return multiple enumerations for multiple actions' do
|
25
|
+
action0 = MockAction.new('Command0')
|
26
|
+
action1 = MockAction.new('Command1')
|
27
|
+
action2 = MockAction.new('Command2')
|
28
|
+
actions = [action0, action1, action2]
|
29
|
+
enumerator = Pug::Action::Enumerator.new
|
30
|
+
expected = ['0: Command0', '1: Command1', '2: Command2']
|
31
|
+
expect(enumerator.names(actions)).to eq(expected)
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'should not show the description if it is nil' do
|
35
|
+
action = MockAction.new('Command')
|
36
|
+
action.mock_description = nil
|
37
|
+
enumerator = Pug::Action::Enumerator.new
|
38
|
+
expect(enumerator.names([action], true)).to eq(['0: Command'])
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'should not show the description if it is empty' do
|
42
|
+
action = MockAction.new('Command')
|
43
|
+
enumerator = Pug::Action::Enumerator.new
|
44
|
+
expect(enumerator.names([action], true)).to eq(['0: Command'])
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'should show the description if it is valid' do
|
48
|
+
action = MockAction.new('Command')
|
49
|
+
action.mock_description = 'ABOUT'
|
50
|
+
enumerator = Pug::Action::Enumerator.new
|
51
|
+
expect(enumerator.names([action], true)).to eq(['0: Command # ABOUT'])
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
describe 'grouped_names' do
|
56
|
+
it 'should return an empty array for nil actions' do
|
57
|
+
enumerator = Pug::Action::Enumerator.new
|
58
|
+
expect(enumerator.grouped_names(nil)).to be_empty
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'should return an empty array for a negative group size' do
|
62
|
+
action = MockAction.new('Command')
|
63
|
+
enumerator = Pug::Action::Enumerator.new
|
64
|
+
expect(enumerator.grouped_names([action], -10)).to eq([])
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'should return an empty array for a group size of 0' do
|
68
|
+
action = MockAction.new('Command')
|
69
|
+
enumerator = Pug::Action::Enumerator.new
|
70
|
+
expect(enumerator.grouped_names([action], 0)).to eq([])
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'should return an empty array for empty actions' do
|
74
|
+
enumerator = Pug::Action::Enumerator.new
|
75
|
+
expect(enumerator.grouped_names([])).to be_empty
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'should return a subarray when less actions than group size' do
|
79
|
+
action = MockAction.new('Command')
|
80
|
+
enumerator = Pug::Action::Enumerator.new
|
81
|
+
expected = [['0: Command']]
|
82
|
+
expect(enumerator.grouped_names([action], 10)).to eq(expected)
|
83
|
+
end
|
84
|
+
|
85
|
+
it 'should return a subarray when equal actions to group size' do
|
86
|
+
action0 = MockAction.new('Command0')
|
87
|
+
action1 = MockAction.new('Command1')
|
88
|
+
actions = [action0, action1]
|
89
|
+
enumerator = Pug::Action::Enumerator.new
|
90
|
+
expected = [['0: Command0', '1: Command1']]
|
91
|
+
expect(enumerator.grouped_names(actions, 2)).to eq(expected)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'should return multiple subarrays when more actions than group size' do
|
95
|
+
action0 = MockAction.new('Command0')
|
96
|
+
action1 = MockAction.new('Command1')
|
97
|
+
action2 = MockAction.new('Command2')
|
98
|
+
actions = [action0, action1, action2]
|
99
|
+
enumerator = Pug::Action::Enumerator.new
|
100
|
+
expected = [['0: Command0', '1: Command1'], ['2: Command2']]
|
101
|
+
expect(enumerator.grouped_names(actions, 2)).to eq(expected)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pug'
|
4
|
+
require_relative '../spec_helpers/mock_action'
|
5
|
+
require_relative '../spec_helpers/mock_client'
|
6
|
+
|
7
|
+
describe Pug::Bot do
|
8
|
+
describe 'start' do
|
9
|
+
before(:each) do
|
10
|
+
@client = MockClient.new
|
11
|
+
action0 = MockAction.new('Action0', false, 'Output0')
|
12
|
+
action1 = MockAction.new('Action1', true, 'Output1')
|
13
|
+
@bot = Pug::Bot.new(@client, [action0, action1])
|
14
|
+
end
|
15
|
+
|
16
|
+
it 'should respond to "help" command' do
|
17
|
+
@client.enqueue_message('help')
|
18
|
+
expected = Pug::Strings.help('list')
|
19
|
+
@bot.start
|
20
|
+
expect(@client.last_sent_message).to eq(expected)
|
21
|
+
end
|
22
|
+
|
23
|
+
it 'should respond to "list" command' do
|
24
|
+
@client.enqueue_message('list')
|
25
|
+
expected = "0: Action0\n1: Action1"
|
26
|
+
@bot.start
|
27
|
+
expect(@client.last_sent_message).to eq(expected)
|
28
|
+
end
|
29
|
+
|
30
|
+
describe 'when there are no commands' do
|
31
|
+
it 'should indicate there are no commands' do
|
32
|
+
client = MockClient.new
|
33
|
+
client.enqueue_message('0')
|
34
|
+
bot = Pug::Bot.new(client, [])
|
35
|
+
expected = Pug::Strings.no_actions
|
36
|
+
bot.start
|
37
|
+
expect(client.last_sent_message).to eq(expected)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe 'when a command is not running' do
|
42
|
+
it 'should respond to an unknown input' do
|
43
|
+
@client.enqueue_message('asdfadf')
|
44
|
+
expected = Pug::Strings.unknown_input
|
45
|
+
@bot.start
|
46
|
+
expect(@client.last_sent_message).to eq(expected)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'should respond to an action call with no inputs required' do
|
50
|
+
@client.enqueue_message('0')
|
51
|
+
expected0 = 'Output0'
|
52
|
+
expected1 = Pug::Strings.finished_running('Action0')
|
53
|
+
@bot.start
|
54
|
+
expect(@client.sent_messages).to eq([expected0, expected1])
|
55
|
+
end
|
56
|
+
|
57
|
+
it 'should respond to an action call with inputs required' do
|
58
|
+
@client.enqueue_message('1')
|
59
|
+
expected = Pug::Strings.enter_inputs('Action1')
|
60
|
+
@bot.start
|
61
|
+
expect(@client.last_sent_message).to eq(expected)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
describe 'when a command is running' do
|
66
|
+
it 'should pass the input and run the command awaiting input' do
|
67
|
+
@client.enqueue_message('1')
|
68
|
+
@client.enqueue_message('Input')
|
69
|
+
expected0 = Pug::Strings.enter_inputs('Action1')
|
70
|
+
expected1 = 'Output1'
|
71
|
+
expected2 = Pug::Strings.finished_running('Action1')
|
72
|
+
expected = [expected0, expected1, expected2]
|
73
|
+
@bot.start
|
74
|
+
expect(@client.sent_messages).to eq(expected)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'pug'
|
4
|
+
|
5
|
+
describe Pug::Clients::Factory do
|
6
|
+
describe 'client_for_config' do
|
7
|
+
it 'should return terminal for a nil config' do
|
8
|
+
client = Pug::Clients::Factory.client_for_config(nil)
|
9
|
+
expect(client).to be_an_instance_of(Pug::TerminalClient)
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'should return terminal for a terminal config' do
|
13
|
+
config = Pug::Configuration.new(Pug::Configuration::TERMINAL)
|
14
|
+
client = Pug::Clients::Factory.client_for_config(config)
|
15
|
+
expect(client).to be_an_instance_of(Pug::TerminalClient)
|
16
|
+
end
|
17
|
+
|
18
|
+
it 'should return telegram for a telegram config' do
|
19
|
+
config = Pug::Configuration.new(Pug::Configuration::TELEGRAM)
|
20
|
+
client = Pug::Clients::Factory.client_for_config(config)
|
21
|
+
expect(client).to be_an_instance_of(Pug::TelegramClient)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|