bell 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -0
- data/.rvmrc +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +47 -0
- data/MIT-LICENSE +20 -0
- data/README.org +128 -0
- data/Rakefile +16 -0
- data/bell.gemspec +30 -0
- data/bin/bell +5 -0
- data/features/create_user.feature +16 -0
- data/features/full_report.feature +84 -0
- data/features/import_public_contacts.feature +20 -0
- data/features/import_user_contacts.feature +43 -0
- data/features/list_all_contacts.feature +19 -0
- data/features/list_user_contacts.feature +27 -0
- data/features/list_users.feature +22 -0
- data/features/remove_user.feature +21 -0
- data/features/rename_user.feature +25 -0
- data/features/step_definitions/cli_steps.rb +59 -0
- data/features/step_definitions/contact_steps.rb +104 -0
- data/features/step_definitions/database_steps.rb +3 -0
- data/features/step_definitions/report_steps.rb +17 -0
- data/features/step_definitions/user_steps.rb +71 -0
- data/features/support/env.rb +65 -0
- data/features/user_report.feature +67 -0
- data/lib/bell/cli.rb +12 -0
- data/lib/bell/commands/command.rb +58 -0
- data/lib/bell/commands/contact_command.rb +91 -0
- data/lib/bell/commands/implosion_command.rb +14 -0
- data/lib/bell/commands/report_command.rb +69 -0
- data/lib/bell/commands/user_command.rb +74 -0
- data/lib/bell/commands.rb +5 -0
- data/lib/bell/csv_parser.rb +52 -0
- data/lib/bell/dispatcher.rb +13 -0
- data/lib/bell/displayable.rb +13 -0
- data/lib/bell/full_report.rb +145 -0
- data/lib/bell/handlers/contacts_handler.rb +79 -0
- data/lib/bell/handlers/implosions_handler.rb +9 -0
- data/lib/bell/handlers/reports_handler.rb +41 -0
- data/lib/bell/handlers/users_handler.rb +50 -0
- data/lib/bell/handlers.rb +4 -0
- data/lib/bell/message.rb +115 -0
- data/lib/bell/public_contact.rb +17 -0
- data/lib/bell/user.rb +16 -0
- data/lib/bell/user_contact.rb +18 -0
- data/lib/bell/user_report.rb +88 -0
- data/lib/bell/util.rb +31 -0
- data/lib/bell.rb +157 -0
- data/spec/bell/cli_spec.rb +4 -0
- data/spec/bell/commands/command_spec.rb +59 -0
- data/spec/bell/commands/contact_command_spec.rb +112 -0
- data/spec/bell/commands/implosion_command_spec.rb +31 -0
- data/spec/bell/commands/report_command_spec.rb +71 -0
- data/spec/bell/commands/user_command_spec.rb +128 -0
- data/spec/bell/csv_parser_spec.rb +167 -0
- data/spec/bell/dispatcher_spec.rb +4 -0
- data/spec/bell/full_report_spec.rb +4 -0
- data/spec/bell/handlers/contacts_handler_spec.rb +160 -0
- data/spec/bell/handlers/implosions_handler_spec.rb +11 -0
- data/spec/bell/handlers/reports_handler_spec.rb +183 -0
- data/spec/bell/handlers/users_handler_spec.rb +94 -0
- data/spec/bell/public_contact_spec.rb +4 -0
- data/spec/bell/user_contact_spec.rb +4 -0
- data/spec/bell/user_report_spec.rb +4 -0
- data/spec/bell/user_spec.rb +4 -0
- data/spec/spec_helper.rb +21 -0
- metadata +230 -0
data/lib/bell/util.rb
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
module Bell
|
2
|
+
module Util
|
3
|
+
module String
|
4
|
+
def self.included(base)
|
5
|
+
base.send(:extend, Util::String)
|
6
|
+
end
|
7
|
+
|
8
|
+
def camelize(lower_case_and_underscored_word, first_letter_in_uppercase = true)
|
9
|
+
if first_letter_in_uppercase
|
10
|
+
lower_case_and_underscored_word.
|
11
|
+
to_s.
|
12
|
+
gsub(/\/(.?)/) { "::#{$1.upcase}" }.
|
13
|
+
gsub(/(?:^|_)(.)/) { $1.upcase }
|
14
|
+
else
|
15
|
+
lower_case_and_underscored_word.
|
16
|
+
to_s[0].
|
17
|
+
chr.
|
18
|
+
downcase + camelize(lower_case_and_underscored_word)[1..-1]
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
def sanitize(string)
|
23
|
+
string.unpack("C*").pack("U*")
|
24
|
+
end
|
25
|
+
|
26
|
+
def multibyte_length(string)
|
27
|
+
RUBY_VERSION < '1.9' ? string.jsize : string.size
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/bell.rb
ADDED
@@ -0,0 +1,157 @@
|
|
1
|
+
%w[embratel sequel sqlite3].each do |gem|
|
2
|
+
begin
|
3
|
+
require gem
|
4
|
+
rescue LoadError
|
5
|
+
$stderr.puts $!
|
6
|
+
exit 1
|
7
|
+
end
|
8
|
+
end
|
9
|
+
|
10
|
+
require 'fileutils'
|
11
|
+
|
12
|
+
module Bell
|
13
|
+
extend self
|
14
|
+
|
15
|
+
VERSION = '0.0.1'
|
16
|
+
|
17
|
+
class InvalidContacts < StandardError; end
|
18
|
+
|
19
|
+
def testing?
|
20
|
+
defined?(Spec) || defined?(Cucumber)
|
21
|
+
end
|
22
|
+
|
23
|
+
def environment
|
24
|
+
testing? ? 'test' : 'runtime'
|
25
|
+
end
|
26
|
+
|
27
|
+
def database
|
28
|
+
@database ||= Database.new(:environment => environment)
|
29
|
+
end
|
30
|
+
|
31
|
+
def database_connection
|
32
|
+
@database_connection ||= database.connect
|
33
|
+
end
|
34
|
+
|
35
|
+
def bootstrapped?
|
36
|
+
Directory.created? && database.created?
|
37
|
+
end
|
38
|
+
|
39
|
+
def bootstrap
|
40
|
+
Directory.create unless Directory.created?
|
41
|
+
database.create_tables?
|
42
|
+
end
|
43
|
+
|
44
|
+
def implode!
|
45
|
+
[User, UserContact, PublicContact].each(&:delete)
|
46
|
+
FileUtils.rm_rf(Directory.path)
|
47
|
+
end
|
48
|
+
|
49
|
+
def output
|
50
|
+
@output ||= Output.new
|
51
|
+
end
|
52
|
+
|
53
|
+
class Output
|
54
|
+
def initialize
|
55
|
+
@outputter = Bell.testing? ? StringIO.new : $stdout
|
56
|
+
end
|
57
|
+
|
58
|
+
def puts(text)
|
59
|
+
@outputter.puts(text)
|
60
|
+
end
|
61
|
+
|
62
|
+
def string
|
63
|
+
@outputter.string
|
64
|
+
end
|
65
|
+
|
66
|
+
def reopen
|
67
|
+
@outputter.reopen if Bell.testing?
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
module Directory
|
72
|
+
extend self
|
73
|
+
|
74
|
+
def path
|
75
|
+
File.join(ENV['HOME'], '.bell')
|
76
|
+
end
|
77
|
+
|
78
|
+
def created?
|
79
|
+
File.exists?(path)
|
80
|
+
end
|
81
|
+
|
82
|
+
def create
|
83
|
+
FileUtils.mkdir(path)
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
class Database
|
88
|
+
def initialize(options = {})
|
89
|
+
@environment = options[:environment]
|
90
|
+
end
|
91
|
+
|
92
|
+
def path
|
93
|
+
File.join(Directory.path, "bell_#{@environment}.db")
|
94
|
+
end
|
95
|
+
|
96
|
+
def created?
|
97
|
+
File.exists?(path)
|
98
|
+
end
|
99
|
+
|
100
|
+
def create_tables?
|
101
|
+
Sequel.sqlite(path) do |database|
|
102
|
+
database.create_table?(:users) do
|
103
|
+
primary_key :id
|
104
|
+
String :name, :unique => true, :null => false
|
105
|
+
end
|
106
|
+
database.create_table?(:user_contacts) do
|
107
|
+
primary_key :id
|
108
|
+
foreign_key :user_id, :null => false
|
109
|
+
String :name, :null => false
|
110
|
+
String :number, :unique => true, :null => false
|
111
|
+
end
|
112
|
+
database.create_table?(:public_contacts) do
|
113
|
+
primary_key :id
|
114
|
+
String :name, :null => false
|
115
|
+
String :number, :unique => true, :null => false
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def connect
|
121
|
+
Sequel.sqlite(path)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
DB = Bell.database_connection
|
127
|
+
Bell.bootstrap unless Bell.bootstrapped?
|
128
|
+
|
129
|
+
if RUBY_VERSION < '1.9'
|
130
|
+
begin
|
131
|
+
require 'fastercsv'
|
132
|
+
rescue LoadError
|
133
|
+
$stderr.puts $!
|
134
|
+
exit 1
|
135
|
+
else
|
136
|
+
Bell::CSV = FasterCSV
|
137
|
+
require 'jcode'
|
138
|
+
$KCODE = "UTF8"
|
139
|
+
end
|
140
|
+
else
|
141
|
+
require 'csv'
|
142
|
+
Bell::CSV = CSV
|
143
|
+
end
|
144
|
+
|
145
|
+
%w[util
|
146
|
+
message
|
147
|
+
displayable
|
148
|
+
commands
|
149
|
+
dispatcher
|
150
|
+
cli
|
151
|
+
csv_parser
|
152
|
+
handlers
|
153
|
+
full_report
|
154
|
+
user_report
|
155
|
+
user_contact
|
156
|
+
public_contact
|
157
|
+
user].each { |f| require File.expand_path("../bell/#{f}", __FILE__) }
|
@@ -0,0 +1,59 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) << '/../../spec_helper')
|
2
|
+
|
3
|
+
describe Bell::Commands::Command do
|
4
|
+
context "when parsing" do
|
5
|
+
context "a user command" do
|
6
|
+
let(:args) { %w[user] }
|
7
|
+
let(:user_command) { mock(Bell::Commands::UserCommand) }
|
8
|
+
|
9
|
+
it "instantiates a user command and parses it" do
|
10
|
+
Bell::Commands::UserCommand.should_receive(:new).and_return(user_command)
|
11
|
+
user_command.should_receive(:parse)
|
12
|
+
described_class.new(args).parse
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "a contact command" do
|
17
|
+
let(:args) { %w[contact] }
|
18
|
+
let(:contact_command) { mock(Bell::Commands::ContactCommand) }
|
19
|
+
|
20
|
+
it "instantiates a contact command and parses it" do
|
21
|
+
Bell::Commands::ContactCommand.should_receive(:new).and_return(contact_command)
|
22
|
+
contact_command.should_receive(:parse)
|
23
|
+
described_class.new(args).parse
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
context "a report command" do
|
28
|
+
let(:args) { %w[report] }
|
29
|
+
let(:report_command) { mock(Bell::Commands::ReportCommand) }
|
30
|
+
|
31
|
+
it "instantiates a report command and parses it" do
|
32
|
+
Bell::Commands::ReportCommand.should_receive(:new).and_return(report_command)
|
33
|
+
report_command.should_receive(:parse)
|
34
|
+
described_class.new(args).parse
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "an implosion command" do
|
39
|
+
let(:args) { %w[implode] }
|
40
|
+
let(:implosion_command) { mock(Bell::Commands::ImplosionCommand) }
|
41
|
+
|
42
|
+
it "instantiates an implosion command and parses it" do
|
43
|
+
Bell::Commands::ImplosionCommand.should_receive(:new).and_return(implosion_command)
|
44
|
+
implosion_command.should_receive(:parse)
|
45
|
+
described_class.new(args).parse
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
context "an unknown command" do
|
50
|
+
let(:args) { %w[foo] }
|
51
|
+
let(:contact_command) { mock(Bell::Commands::ContactCommand) }
|
52
|
+
|
53
|
+
it "instantiates an implosion command and parses it" do
|
54
|
+
lambda { described_class.new(args).parse }.
|
55
|
+
should raise_error(ArgumentError, described_class::USAGE)
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -0,0 +1,112 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) << '/../../spec_helper')
|
2
|
+
|
3
|
+
describe Bell::Commands::ContactCommand do
|
4
|
+
describe ".initialize" do
|
5
|
+
def contact_command_route(action)
|
6
|
+
{ :handler => 'contacts_handler', :action => action, :params => {} }
|
7
|
+
end
|
8
|
+
|
9
|
+
context "when given invalid actions" do
|
10
|
+
it "raises ArgumentError" do
|
11
|
+
lambda { described_class.new(%w[foo]).parse }.
|
12
|
+
should raise_error(ArgumentError, described_class::USAGE)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
context "when giver valid actions" do
|
17
|
+
it "sets the handler route key" do
|
18
|
+
%w[import list].each do |action|
|
19
|
+
contact_command = described_class.new([action])
|
20
|
+
contact_command.route.should == contact_command_route(action)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe ".import" do
|
27
|
+
context "when given no additional arguments" do
|
28
|
+
it "raises ArgumentError" do
|
29
|
+
lambda { described_class.new(%w[import]).parse }.
|
30
|
+
should raise_error(ArgumentError, described_class::IMPORT_USAGE)
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
context "when given valid arguments" do
|
35
|
+
let(:path) { 'path/to/contacts_file.csv' }
|
36
|
+
let(:user_name) { 'john' }
|
37
|
+
let(:contact_command_route) do
|
38
|
+
{ :handler => 'contacts_handler',
|
39
|
+
:action => 'import',
|
40
|
+
:params => { :path => path, :user => { :name => user_name } } }
|
41
|
+
end
|
42
|
+
|
43
|
+
it "assembles the right route" do
|
44
|
+
%w[-u --user].each do |user_name_flag|
|
45
|
+
described_class.
|
46
|
+
new(['import', path, user_name_flag, user_name]).
|
47
|
+
parse.
|
48
|
+
route.should == contact_command_route
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
context "parsing 'list' commands" do
|
55
|
+
context "without additional arguments" do
|
56
|
+
let(:contact_command_route) do
|
57
|
+
{ :handler => 'contacts_handler',
|
58
|
+
:action => 'list',
|
59
|
+
:params => {} }
|
60
|
+
end
|
61
|
+
|
62
|
+
it "assembles the right route" do
|
63
|
+
described_class.new(%w[list]).parse.route.should == contact_command_route
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "when given valid user arguments" do
|
68
|
+
context "when not asking for CSV" do
|
69
|
+
let(:user_name) { 'john' }
|
70
|
+
let(:contact_command_route) do
|
71
|
+
{ :handler => 'contacts_handler',
|
72
|
+
:action => 'list',
|
73
|
+
:params => { :user => { :name => user_name } } }
|
74
|
+
end
|
75
|
+
|
76
|
+
it "assembles the right route" do
|
77
|
+
%w[-u --user].each do |user_name_flag|
|
78
|
+
described_class.
|
79
|
+
new(['list', user_name_flag, user_name]).
|
80
|
+
parse.
|
81
|
+
route.should == contact_command_route
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
context "when asking for CSV" do
|
87
|
+
let(:user_name) { 'john' }
|
88
|
+
let(:contact_command_route) do
|
89
|
+
{ :handler => 'contacts_handler',
|
90
|
+
:action => 'list',
|
91
|
+
:params => { :user => { :name => user_name }, :csv => true } }
|
92
|
+
end
|
93
|
+
|
94
|
+
it "assembles the right route" do
|
95
|
+
%w[-u --user].each do |user_name_flag|
|
96
|
+
described_class.
|
97
|
+
new(['list', user_name_flag, user_name, '--csv']).
|
98
|
+
parse.
|
99
|
+
route.should == contact_command_route
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context "parsing unknown commands" do
|
107
|
+
it "raises ArgumentError" do
|
108
|
+
lambda { described_class.new(%w[foo]).parse }.
|
109
|
+
should raise_error(ArgumentError, described_class::USAGE)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) << '/../../spec_helper')
|
2
|
+
|
3
|
+
describe Bell::Commands::ImplosionCommand do
|
4
|
+
context "when initialized" do
|
5
|
+
let(:implosion_command_route) do
|
6
|
+
{ :handler => 'implosions_handler', :action => nil, :params => {} }
|
7
|
+
end
|
8
|
+
|
9
|
+
it "has default values" do
|
10
|
+
implosion_command = described_class.new
|
11
|
+
implosion_command.route.should == implosion_command_route
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "parsing" do
|
16
|
+
context "without additional arguments" do
|
17
|
+
let(:args) { %w[path/to/fatura.csv] }
|
18
|
+
let(:implosion_command_route) do
|
19
|
+
{ :handler => 'implosions_handler',
|
20
|
+
:action => 'implode',
|
21
|
+
:params => {} }
|
22
|
+
end
|
23
|
+
|
24
|
+
it "assembles the right route" do
|
25
|
+
implosion_command = described_class.new(args)
|
26
|
+
implosion_command.parse
|
27
|
+
implosion_command.route.should == implosion_command_route
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) << '/../../spec_helper')
|
2
|
+
|
3
|
+
describe Bell::Commands::ReportCommand do
|
4
|
+
context "when initialized" do
|
5
|
+
let(:report_command_route) do
|
6
|
+
{ :handler => 'reports_handler', :action => nil, :params => {} }
|
7
|
+
end
|
8
|
+
|
9
|
+
it "has default values" do
|
10
|
+
report_command = described_class.new
|
11
|
+
report_command.route.should == report_command_route
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "parsing 'full_report' commands" do
|
16
|
+
context "with additional arguments" do
|
17
|
+
let(:args) { %w[fatura.csv] }
|
18
|
+
let(:report_command_route) do
|
19
|
+
{ :handler => 'reports_handler',
|
20
|
+
:action => 'full_report',
|
21
|
+
:params => { :path => args[0] } }
|
22
|
+
end
|
23
|
+
|
24
|
+
it "assembles the right route" do
|
25
|
+
report_command = described_class.new(args)
|
26
|
+
report_command.parse
|
27
|
+
report_command.route.should == report_command_route
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
context "without additional arguments" do
|
32
|
+
let(:args) { %w[] }
|
33
|
+
|
34
|
+
it "raises ArgumentError" do
|
35
|
+
lambda { described_class.new(args).parse }.
|
36
|
+
should raise_error(ArgumentError, described_class::FULL_REPORT_USAGE)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "parsing 'user_report' commands" do
|
42
|
+
context "when given all necessary arguments" do
|
43
|
+
let(:args) { %w[fatura.csv -u bob] }
|
44
|
+
let(:report_command_route) do
|
45
|
+
{ :handler => 'reports_handler',
|
46
|
+
:action => 'user_report',
|
47
|
+
:params => { :path => args[0], :user => { :name => args[2] } } }
|
48
|
+
end
|
49
|
+
|
50
|
+
it "assembles the right route" do
|
51
|
+
report_command = described_class.new(args)
|
52
|
+
report_command.parse
|
53
|
+
report_command.route.should == report_command_route
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
context "with one missing argument" do
|
58
|
+
let(:args) { %w[-u bob] }
|
59
|
+
let(:args_with_one_missing_array) do
|
60
|
+
args.dup.inject([]) { |args_with_one_missing, arg|
|
61
|
+
args_with_one_missing << args.reject { |a| a == arg }
|
62
|
+
}.each { |array| array.unshift('fatura.csv') }
|
63
|
+
end
|
64
|
+
|
65
|
+
it "raises ArgumentError" do
|
66
|
+
lambda { described_class.new(args).parse }.
|
67
|
+
should raise_error(ArgumentError, described_class::USER_REPORT_USAGE)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
@@ -0,0 +1,128 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__) << '/../../spec_helper')
|
2
|
+
|
3
|
+
describe Bell::Commands::UserCommand do
|
4
|
+
context "when initialized" do
|
5
|
+
let(:user_command_route) do
|
6
|
+
{ :handler => 'users_handler', :action => nil, :params => {} }
|
7
|
+
end
|
8
|
+
|
9
|
+
it "has default values" do
|
10
|
+
user_command = described_class.new
|
11
|
+
user_command.route.should == user_command_route
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "parsing 'create' commands" do
|
16
|
+
context "without additional arguments" do
|
17
|
+
let(:args) { %w[create] }
|
18
|
+
|
19
|
+
it "raises ArgumentError" do
|
20
|
+
lambda { described_class.new(args).parse }.
|
21
|
+
should raise_error(ArgumentError, described_class::CREATE_USAGE)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "with one additional argument" do
|
26
|
+
let(:args) { %w[create bob] }
|
27
|
+
let(:user_command_route) do
|
28
|
+
{ :handler => 'users_handler',
|
29
|
+
:action => 'create',
|
30
|
+
:params => { :user => { :name => args.last } } }
|
31
|
+
end
|
32
|
+
|
33
|
+
it "assembles the right route" do
|
34
|
+
user_command = described_class.new(args)
|
35
|
+
user_command.parse
|
36
|
+
user_command.route.should == user_command_route
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
context "parsing 'rename' commands" do
|
42
|
+
context "without additional arguments" do
|
43
|
+
let(:args) { %w[rename] }
|
44
|
+
|
45
|
+
it "raises ArgumentError" do
|
46
|
+
lambda { described_class.new(args).parse }.
|
47
|
+
should raise_error(ArgumentError, described_class::RENAME_USAGE)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
context "with one additional argument" do
|
52
|
+
let(:args) { %w[rename bob] }
|
53
|
+
|
54
|
+
it "raises ArgumentError" do
|
55
|
+
lambda { described_class.new(args).parse }.
|
56
|
+
should raise_error(ArgumentError, described_class::RENAME_USAGE)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
context "with two additional arguments" do
|
61
|
+
let(:args) { %w[rename bob robert] }
|
62
|
+
let(:user_command_route) do
|
63
|
+
{ :handler => 'users_handler',
|
64
|
+
:action => 'rename',
|
65
|
+
:params => { :user => { :source_name => args[1],
|
66
|
+
:target_name => args[2] } } }
|
67
|
+
end
|
68
|
+
|
69
|
+
it "assembles the right route" do
|
70
|
+
user_command = described_class.new(args)
|
71
|
+
user_command.parse
|
72
|
+
user_command.route.should == user_command_route
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
context "parsing 'list' commands" do
|
78
|
+
context "without additional arguments" do
|
79
|
+
let(:args) { %w[list] }
|
80
|
+
let(:user_command_route) do
|
81
|
+
{ :handler => 'users_handler',
|
82
|
+
:action => 'list',
|
83
|
+
:params => {} }
|
84
|
+
end
|
85
|
+
|
86
|
+
it "assembles the right route" do
|
87
|
+
user_command = described_class.new(args)
|
88
|
+
user_command.parse
|
89
|
+
user_command.route.should == user_command_route
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
context "parsing 'remove' commands" do
|
95
|
+
context "without additional arguments" do
|
96
|
+
let(:args) { %w[remove] }
|
97
|
+
|
98
|
+
it "raises ArgumentError" do
|
99
|
+
lambda { described_class.new(args).parse }.
|
100
|
+
should raise_error(ArgumentError, described_class::REMOVE_USAGE)
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
context "with one additional argument" do
|
105
|
+
let(:args) { %w[remove bob] }
|
106
|
+
let(:user_command_route) do
|
107
|
+
{ :handler => 'users_handler',
|
108
|
+
:action => 'remove',
|
109
|
+
:params => { :user => { :name => args.last } } }
|
110
|
+
end
|
111
|
+
|
112
|
+
it "assembles the right route" do
|
113
|
+
user_command = described_class.new(args)
|
114
|
+
user_command.parse
|
115
|
+
user_command.route.should == user_command_route
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
context "parsing unknown commands" do
|
121
|
+
let(:args) { %w[foo] }
|
122
|
+
|
123
|
+
it "raises ArgumentError" do
|
124
|
+
lambda { described_class.new(args).parse }.
|
125
|
+
should raise_error(ArgumentError, described_class::USAGE)
|
126
|
+
end
|
127
|
+
end
|
128
|
+
end
|