ppl 0.0.5 → 0.2.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.
Files changed (62) hide show
  1. data/.gitignore +2 -0
  2. data/.rspec +3 -0
  3. data/.travis.yml +5 -0
  4. data/Gemfile +7 -3
  5. data/Gemfile.lock +15 -7
  6. data/README.md +47 -34
  7. data/bin/ppl +7 -6
  8. data/lib/ppl/adapter/storage/disk.rb +40 -0
  9. data/lib/ppl/adapter/storage.rb +28 -0
  10. data/lib/ppl/adapter/vcard/vpim.rb +45 -0
  11. data/lib/ppl/adapter/vcard.rb +13 -0
  12. data/lib/ppl/application/bootstrap.rb +62 -0
  13. data/lib/ppl/application/command.rb +13 -0
  14. data/lib/ppl/application/command_suite.rb +25 -0
  15. data/lib/ppl/application/input.rb +13 -0
  16. data/lib/ppl/application/output.rb +21 -0
  17. data/lib/ppl/application/router.rb +19 -0
  18. data/lib/ppl/application/shell.rb +34 -0
  19. data/lib/ppl/command/command_list.rb +21 -0
  20. data/lib/ppl/command/contact_add.rb +26 -0
  21. data/lib/ppl/command/contact_delete.rb +16 -0
  22. data/lib/ppl/command/contact_list.rb +24 -0
  23. data/lib/ppl/command/contact_rename.rb +23 -0
  24. data/lib/ppl/command/contact_show.rb +20 -0
  25. data/lib/ppl/entity/address_book.rb +21 -0
  26. data/lib/ppl/entity/contact.rb +10 -0
  27. data/lib/ppl/error/contact_not_found.rb +4 -0
  28. data/lib/ppl/error/incorrect_usage.rb +4 -0
  29. data/lib/ppl.rb +51 -11
  30. data/ppl.gemspec +3 -3
  31. data/spec/ppl/adapter/output_spec.rb +43 -0
  32. data/spec/ppl/adapter/storage/disk_spec.rb +83 -0
  33. data/spec/ppl/adapter/storage_spec.rb +46 -0
  34. data/spec/ppl/adapter/vcard/vpim_spec.rb +77 -0
  35. data/spec/ppl/adapter/vcard_spec.rb +24 -0
  36. data/spec/ppl/application/bootstrap_spec.rb +88 -0
  37. data/spec/ppl/application/command_spec.rb +19 -0
  38. data/spec/ppl/application/command_suite_spec.rb +44 -0
  39. data/spec/ppl/application/input_spec.rb +21 -0
  40. data/spec/ppl/application/router_spec.rb +43 -0
  41. data/spec/ppl/application/shell_spec.rb +79 -0
  42. data/spec/ppl/command/command_list_spec.rb +37 -0
  43. data/spec/ppl/command/contact_add_spec.rb +41 -0
  44. data/spec/ppl/command/contact_delete_spec.rb +31 -0
  45. data/spec/ppl/command/contact_list_spec.rb +15 -0
  46. data/spec/ppl/command/contact_rename_spec.rb +42 -0
  47. data/spec/ppl/command/contact_show_spec.rb +35 -0
  48. data/spec/ppl/entity/address_book_spec.rb +26 -0
  49. data/spec/ppl/entity/contact_spec.rb +34 -0
  50. data/spec/spec_helper.rb +9 -0
  51. metadata +47 -14
  52. data/lib/ppl/address_book.rb +0 -74
  53. data/lib/ppl/cli.rb +0 -49
  54. data/lib/ppl/command/add.rb +0 -40
  55. data/lib/ppl/command/birthdays.rb +0 -34
  56. data/lib/ppl/command/help.rb +0 -32
  57. data/lib/ppl/command/list.rb +0 -31
  58. data/lib/ppl/command/rm.rb +0 -38
  59. data/lib/ppl/command/set.rb +0 -49
  60. data/lib/ppl/command/show.rb +0 -43
  61. data/lib/ppl/command.rb +0 -55
  62. data/lib/ppl/contact.rb +0 -43
@@ -0,0 +1,10 @@
1
+
2
+ class Ppl::Entity::Contact
3
+
4
+ attr_accessor :id
5
+ attr_accessor :name
6
+ attr_accessor :email_address
7
+ attr_accessor :birthday
8
+
9
+ end
10
+
@@ -0,0 +1,4 @@
1
+
2
+ class Ppl::Error::ContactNotFound < StandardError
3
+ end
4
+
@@ -0,0 +1,4 @@
1
+
2
+ class Ppl::Error::IncorrectUsage < StandardError
3
+ end
4
+
data/lib/ppl.rb CHANGED
@@ -1,16 +1,56 @@
1
1
 
2
2
  module Ppl
3
+
4
+ Version = "0.2.0"
5
+
6
+ module Adapter
7
+ end
8
+
9
+ module Application
10
+ end
11
+
12
+ module Command
13
+ end
14
+
15
+ module Entity
16
+ end
17
+
18
+ module Error
19
+ end
20
+
21
+ module Factory
22
+ end
23
+
3
24
  end
4
25
 
5
- require "ppl/address_book"
6
- require "ppl/contact"
7
- require "ppl/cli"
8
- require "ppl/command"
9
- require "ppl/command/add"
10
- require "ppl/command/birthdays"
11
- require "ppl/command/help"
12
- require "ppl/command/list"
13
- require "ppl/command/rm"
14
- require "ppl/command/set"
15
- require "ppl/command/show"
26
+
27
+ require "ppl/adapter/storage"
28
+ require "ppl/adapter/storage/disk"
29
+ require "ppl/adapter/vcard"
30
+ require "ppl/adapter/vcard/vpim"
31
+
32
+ require "ppl/application/bootstrap"
33
+ require "ppl/application/command"
34
+ require "ppl/application/command_suite"
35
+ require "ppl/application/input"
36
+ require "ppl/application/output"
37
+ require "ppl/application/router"
38
+ require "ppl/application/shell"
39
+
40
+ require "ppl/command/command_list"
41
+ require "ppl/command/contact_add"
42
+ require "ppl/command/contact_delete"
43
+ require "ppl/command/contact_list"
44
+ require "ppl/command/contact_show"
45
+ require "ppl/command/contact_rename"
46
+
47
+ require "ppl/entity/address_book"
48
+ require "ppl/entity/contact"
49
+
50
+ require "ppl/error/contact_not_found"
51
+ require "ppl/error/incorrect_usage"
52
+
53
+ class String
54
+ alias_method :each, :each_line
55
+ end
16
56
 
data/ppl.gemspec CHANGED
@@ -2,11 +2,11 @@
2
2
  Gem::Specification.new do |spec|
3
3
 
4
4
  spec.name = "ppl"
5
- spec.version = "0.0.5"
6
- spec.date = "2012-11-13"
5
+ spec.version = "0.2.0"
6
+ spec.date = "2012-11-23"
7
7
 
8
8
  spec.summary = "CLI Address Book"
9
- spec.description = "Command-line driven address book"
9
+ spec.description = "CLI Address Book"
10
10
  spec.license = "GPL-2"
11
11
 
12
12
  spec.authors = ["Henry Smith"]
@@ -0,0 +1,43 @@
1
+
2
+ describe Ppl::Application::Output, "#initialize" do
3
+
4
+ it "should accept stdout" do
5
+ stdout = Object.new
6
+ @output = Ppl::Application::Output.new(stdout, nil)
7
+ @output.stdout.should be stdout
8
+ end
9
+
10
+ it "should accept stderr" do
11
+ stderr = Object.new
12
+ @output = Ppl::Application::Output.new(nil, stderr)
13
+ @output.stderr.should be stderr
14
+ end
15
+
16
+ end
17
+
18
+ describe Ppl::Application::Output do
19
+
20
+ before(:each) do
21
+ @stderr = double(IO)
22
+ @stdout = double(IO)
23
+ @output = Ppl::Application::Output.new(@stdout, @stderr)
24
+ end
25
+
26
+ describe "#error" do
27
+ it "should delegate to stderr's puts method" do
28
+ string = "COMPUTER OVER. VIRUS = VERY YES"
29
+ @stderr.should_receive(:puts).with(string)
30
+ @output.error(string)
31
+ end
32
+ end
33
+
34
+ describe "#line" do
35
+ it "should delegate to stdout's puts method" do
36
+ string = "The quick brown fox"
37
+ @stdout.should_receive(:puts).with(string)
38
+ @output.line(string)
39
+ end
40
+ end
41
+
42
+ end
43
+
@@ -0,0 +1,83 @@
1
+
2
+ describe Ppl::Adapter::Storage::Disk, "#initialize" do
3
+
4
+ it "should accept a path" do
5
+ @storage = Ppl::Adapter::Storage::Disk.new("/tmp")
6
+ @storage.path.should eq "/tmp"
7
+ end
8
+
9
+ end
10
+
11
+ describe Ppl::Adapter::Storage::Disk do
12
+
13
+ before(:each) do
14
+ @storage = Ppl::Adapter::Storage::Disk.new(nil)
15
+ end
16
+
17
+ describe "#vcard_adapter=" do
18
+ it "should accept a vcard adapter" do
19
+ adapter = double(Ppl::Adapter::Vcard)
20
+ @storage.vcard_adapter = adapter
21
+ @storage.vcard_adapter.should be adapter
22
+ end
23
+ end
24
+
25
+ end
26
+
27
+ describe Ppl::Adapter::Storage::Disk do
28
+
29
+ before(:each) do
30
+ @storage = Ppl::Adapter::Storage::Disk.new("/contacts")
31
+ @adapter = double(Ppl::Adapter::Vcard)
32
+ @contact = Ppl::Entity::Contact.new
33
+ @storage.vcard_adapter = @adapter
34
+
35
+ FakeFS.activate!
36
+ Dir.mkdir "/contacts"
37
+ end
38
+
39
+ after(:each) do
40
+ FileUtils.rm_rf "/contacts"
41
+ FakeFS.deactivate!
42
+ end
43
+
44
+ describe "#load_address_book" do
45
+
46
+ it "should return a Ppl::Entity::AddressBook" do
47
+ @storage.load_address_book.should be_a(Ppl::Entity::AddressBook)
48
+ end
49
+
50
+ it "should fill the address book with the contacts in the directory" do
51
+ FileUtils.touch "/contacts/one.vcf"
52
+ FileUtils.touch "/contacts/two.vcf"
53
+
54
+ @adapter.should_receive(:decode).twice
55
+
56
+ address_book = @storage.load_address_book
57
+ address_book.count.should eq 2
58
+ end
59
+
60
+ end
61
+
62
+ describe "#load_contact" do
63
+
64
+ it "should return nil if the given contact doesn't exist" do
65
+ @storage.load_contact("xyz").should be nil
66
+ end
67
+
68
+ it "should return a Ppl::Entity::Contact" do
69
+ FileUtils.touch "/contacts/one.vcf"
70
+ @adapter.should_receive(:decode).once.and_return(@contact)
71
+ @storage.load_contact("one").should be_a(Ppl::Entity::Contact)
72
+ end
73
+
74
+ it "should populate the contact's id" do
75
+ FileUtils.touch "/contacts/one.vcf"
76
+ @adapter.should_receive(:decode).once.and_return(@contact)
77
+ @storage.load_contact("one").id.should eq "one"
78
+ end
79
+
80
+ end
81
+
82
+ end
83
+
@@ -0,0 +1,46 @@
1
+
2
+ describe Ppl::Adapter::Storage do
3
+
4
+ before(:each) do
5
+ @storage = Ppl::Adapter::Storage.new
6
+ end
7
+
8
+ describe "#delete_contact" do
9
+ it "should raise not implemented error" do
10
+ expect{@storage.delete_contact(nil)}.to raise_error(NotImplementedError)
11
+ end
12
+ end
13
+
14
+ describe "#load_address_book" do
15
+ it "should raise not implemented error" do
16
+ expect{@storage.load_address_book}.to raise_error(NotImplementedError)
17
+ end
18
+ end
19
+
20
+ describe "#load_contact" do
21
+ it "should raise not implemented error" do
22
+ expect{@storage.load_contact(nil)}.to raise_error(NotImplementedError)
23
+ end
24
+ end
25
+
26
+ describe "#require_contact" do
27
+
28
+ it "should raise Ppl::Error::ContactNotFound if load fails" do
29
+ @storage.stub(:load_contact) do |id| end
30
+ expect{@storage.require_contact("joe")}.to raise_error(Ppl::Error::ContactNotFound)
31
+ end
32
+
33
+ it "should return the loaded contact" do
34
+ @storage.stub(:load_contact) do |id| Object.new end
35
+ @storage.require_contact("joe").should be_an(Object)
36
+ end
37
+ end
38
+
39
+ describe "#save_contact" do
40
+ it "should raise not implemented error" do
41
+ expect{@storage.save_contact(nil)}.to raise_error(NotImplementedError)
42
+ end
43
+ end
44
+
45
+ end
46
+
@@ -0,0 +1,77 @@
1
+
2
+ describe Ppl::Adapter::Vcard::Vpim, "#encode" do
3
+
4
+ before(:each) do
5
+ @adapter = Ppl::Adapter::Vcard::Vpim.new
6
+ @contact = Ppl::Entity::Contact.new
7
+ @contact.id = "test"
8
+ end
9
+
10
+ it "should encode the contact's birthday" do
11
+ @contact.birthday = Date.parse "2000-01-01"
12
+ @adapter.encode(@contact).should include("BDAY:20000101")
13
+ end
14
+
15
+ it "should encode the contact's name" do
16
+ @contact.name = "John Doe"
17
+ @adapter.encode(@contact).should include("FN:John Doe")
18
+ end
19
+
20
+ end
21
+
22
+
23
+ describe Ppl::Adapter::Vcard::Vpim, "#decode" do
24
+
25
+ before(:each) do
26
+ @adapter = Ppl::Adapter::Vcard::Vpim.new
27
+ end
28
+
29
+ it "should return a Ppl::Entity::Contact" do
30
+ vcard = [
31
+ "BEGIN:VCARD",
32
+ "VERSION:3.0",
33
+ "N:,test",
34
+ "END:VCARD",
35
+ ].join("\n")
36
+ @adapter.decode(vcard).should be_a(Ppl::Entity::Contact)
37
+ end
38
+
39
+ it "should decode the contact's birthday" do
40
+ vcard = [
41
+ "BEGIN:VCARD",
42
+ "VERSION:3.0",
43
+ "N:,test",
44
+ "BDAY:20120102",
45
+ "END:VCARD",
46
+ ].join("\n")
47
+ @adapter.decode(vcard).birthday.strftime('%Y-%m-%d').should eq "2012-01-02"
48
+ end
49
+
50
+ it "should decode the contact's name" do
51
+
52
+ vcard = [
53
+ "BEGIN:VCARD",
54
+ "VERSION:3.0",
55
+ "N:,test",
56
+ "FN:John Doe",
57
+ "END:VCARD",
58
+ ].join("\n")
59
+ contact = @adapter.decode(vcard)
60
+
61
+ contact.name.should eq "John Doe"
62
+ end
63
+
64
+ it "should decode the contact's email address" do
65
+ vcard = [
66
+ "BEGIN:VCARD",
67
+ "N:,test",
68
+ "VERSION:3.0",
69
+ "EMAIL;TYPE=home:home@example.org",
70
+ "END:VCARD",
71
+ ].join("\n")
72
+ contact = @adapter.decode(vcard)
73
+ contact.email_address.should eq "home@example.org"
74
+ end
75
+
76
+ end
77
+
@@ -0,0 +1,24 @@
1
+
2
+ describe Ppl::Adapter::Vcard, "#encode" do
3
+
4
+ describe "#encode" do
5
+ before(:each) do
6
+ @adapter = Ppl::Adapter::Vcard.new
7
+ end
8
+ it "should raise not implemented error" do
9
+ expect{@adapter.encode(nil)}.to raise_error(NotImplementedError)
10
+ end
11
+ end
12
+
13
+
14
+ describe "#decode" do
15
+ before(:each) do
16
+ @adapter = Ppl::Adapter::Vcard.new
17
+ end
18
+ it "should raise not implemented error" do
19
+ expect{@adapter.decode(nil)}.to raise_error(NotImplementedError)
20
+ end
21
+ end
22
+
23
+ end
24
+
@@ -0,0 +1,88 @@
1
+
2
+ describe Ppl::Application::Bootstrap do
3
+
4
+ before(:each) do
5
+ @bootstrap = Ppl::Application::Bootstrap.new
6
+ end
7
+
8
+ describe "#commands" do
9
+ it "should return an array" do
10
+ @bootstrap.commands.should be_an(Array)
11
+ end
12
+ it "should return commands" do
13
+ @bootstrap.commands.each do |command|
14
+ command.should be_a(Ppl::Application::Command)
15
+ end
16
+ end
17
+ it "should inject a storage adapter into each command" do
18
+ @bootstrap.commands.each do |command|
19
+ command.storage.should be_a(Ppl::Adapter::Storage)
20
+ end
21
+ end
22
+ end
23
+
24
+ describe "#command_suite" do
25
+ it "should return a Ppl::Application::CommandSuite" do
26
+ @bootstrap.command_suite.should be_a(Ppl::Application::CommandSuite)
27
+ end
28
+ it "should contain the 'add' command" do
29
+ @bootstrap.command_suite.find_command("add").should_not be nil
30
+ end
31
+ it "should contain the 'ls' command" do
32
+ @bootstrap.command_suite.find_command("ls").should_not be nil
33
+ end
34
+ it "should contain the 'mv' command" do
35
+ @bootstrap.command_suite.find_command("mv").should_not be nil
36
+ end
37
+ it "should contain the 'rm' command" do
38
+ @bootstrap.command_suite.find_command("rm").should_not be nil
39
+ end
40
+ it "should contain the 'show' command" do
41
+ @bootstrap.command_suite.find_command("show").should_not be nil
42
+ end
43
+ it "should contain the 'help' command" do
44
+ @bootstrap.command_suite.find_command("help").should_not be nil
45
+ end
46
+ end
47
+
48
+ describe "#input" do
49
+ it "should return a Ppl::Application::Input" do
50
+ @bootstrap.input.should be_a(Ppl::Application::Input)
51
+ end
52
+ end
53
+
54
+ describe "#output" do
55
+ it "should return a Ppl::Application::Output" do
56
+ @bootstrap.output.should be_a(Ppl::Application::Output)
57
+ end
58
+ end
59
+
60
+ describe "#router" do
61
+ it "should return a Ppl::Application::Router" do
62
+ @bootstrap.router.should be_a(Ppl::Application::Router)
63
+ end
64
+ it "should set the 'help' command as the default" do
65
+ @bootstrap.router.default.should eq "help"
66
+ end
67
+ end
68
+
69
+ describe "#shell" do
70
+ it "should return a Ppl::Application::Shell" do
71
+ @bootstrap.shell.should be_a(Ppl::Application::Shell)
72
+ end
73
+ end
74
+
75
+ describe "#storage_adapter" do
76
+ it "should return a Ppl::Adapter::Storage::Disk" do
77
+ @bootstrap.storage_adapter.should be_a(Ppl::Adapter::Storage::Disk)
78
+ end
79
+ end
80
+
81
+ describe "#vcard_adapter" do
82
+ it "should return a Ppl::Adapter::Vcard::Vpim" do
83
+ @bootstrap.vcard_adapter.should be_a(Ppl::Adapter::Vcard::Vpim)
84
+ end
85
+ end
86
+
87
+ end
88
+
@@ -0,0 +1,19 @@
1
+
2
+ describe Ppl::Application::Command, "#execute" do
3
+
4
+ before(:each) do
5
+ @command = Ppl::Application::Command.new
6
+ end
7
+
8
+ it "should raise not implemented error" do
9
+ expect{@command.execute(nil, nil)}.to raise_error(NotImplementedError)
10
+ end
11
+
12
+ it "should accept a storage adapter" do
13
+ storage = double(Ppl::Adapter::Storage)
14
+ @command.storage = storage
15
+ @command.storage.should be storage
16
+ end
17
+
18
+ end
19
+
@@ -0,0 +1,44 @@
1
+
2
+ describe Ppl::Application::CommandSuite do
3
+
4
+ before(:each) do
5
+ @command_suite = Ppl::Application::CommandSuite.new
6
+
7
+ @foo_command = Ppl::Application::Command.new
8
+ @foo_command.name = "foo"
9
+
10
+ @bar_command = Ppl::Application::Command.new
11
+ @bar_command.name = "bar"
12
+
13
+ @command_suite.add_command(@foo_command)
14
+ @command_suite.add_command(@bar_command)
15
+ end
16
+
17
+ describe "#add_command" do
18
+ it "should accept a command" do
19
+ @command_suite.add_command(Ppl::Application::Command.new)
20
+ @command_suite.count.should be 3
21
+ end
22
+ end
23
+
24
+ describe "#find_command" do
25
+ it "should find a command matching the given name" do
26
+ @command_suite.find_command("foo").should be @foo_command
27
+ end
28
+ it "should return nil if no commands match the given name" do
29
+ @command_suite.find_command("baz").should be nil
30
+ end
31
+ end
32
+
33
+ describe "#each" do
34
+ it "should yield commands" do
35
+ @command_suite
36
+ .should_receive(:each)
37
+ .and_yield(@foo_command)
38
+ .and_yield(@bar_command)
39
+ @command_suite.each do |c| end
40
+ end
41
+ end
42
+
43
+ end
44
+
@@ -0,0 +1,21 @@
1
+
2
+ describe Ppl::Application::Input do
3
+
4
+ before(:each) do
5
+ @input = Ppl::Application::Input.new
6
+ end
7
+
8
+ describe "#arguments" do
9
+ it "should be an array" do
10
+ @input.arguments.should be_an(Array)
11
+ end
12
+ end
13
+
14
+ describe "#options" do
15
+ it "should be a hash" do
16
+ @input.options.should be_a(Hash)
17
+ end
18
+ end
19
+
20
+ end
21
+
@@ -0,0 +1,43 @@
1
+
2
+ describe Ppl::Application::Router do
3
+
4
+ before(:each) do
5
+ @suite = Ppl::Application::CommandSuite.new
6
+ @router = Ppl::Application::Router.new(@suite)
7
+
8
+ @cmd_one = Ppl::Application::Command.new
9
+ @cmd_one.name = "one"
10
+
11
+ @cmd_two = Ppl::Application::Command.new
12
+ @cmd_two.name = "two"
13
+
14
+ @suite.add_command(@cmd_one)
15
+ @suite.add_command(@cmd_two)
16
+ end
17
+
18
+ describe "#default=" do
19
+ it "should accept the name of the default command" do
20
+ @router.default = "one"
21
+ @router.default.should eq "one"
22
+ end
23
+ end
24
+
25
+ describe "#route" do
26
+
27
+ it "should return the command whose name matches the given argument" do
28
+ @router.route("two").should be @cmd_two
29
+ end
30
+
31
+ it "should return nil if no matching command can be found" do
32
+ @router.route("three").should be nil
33
+ end
34
+
35
+ it "should fall back to the default command if the given one isn't found" do
36
+ @router.default = "one"
37
+ @router.route("three").should be @cmd_one
38
+ end
39
+
40
+ end
41
+
42
+ end
43
+
@@ -0,0 +1,79 @@
1
+
2
+ describe Ppl::Application::Shell do
3
+
4
+ before(:each) do
5
+ @shell = Ppl::Application::Shell.new
6
+ @input = Ppl::Application::Input.new
7
+ @output = double(Ppl::Application::Output)
8
+
9
+ @router = double(Ppl::Application::Router)
10
+ @command = double(Ppl::Application::Command)
11
+
12
+ @shell.router = @router
13
+ end
14
+
15
+ describe "#run" do
16
+
17
+ it "should return false if the given command isn't found" do
18
+ @input.arguments = ["foo"]
19
+ @router
20
+ .should_receive(:route)
21
+ .with("foo")
22
+ .and_return(nil)
23
+ @shell.run(@input, @output).should eq false
24
+ end
25
+
26
+ it "should execute the given command" do
27
+ @input.arguments = ["foo"]
28
+ @router
29
+ .should_receive(:route)
30
+ .with("foo")
31
+ .and_return(@command)
32
+
33
+ @command
34
+ .should_receive(:execute)
35
+ .and_return(true)
36
+
37
+ @shell.run(@input, @output).should eq true
38
+ end
39
+
40
+ it "should not pass the command name in the input to the command itself" do
41
+ @input.arguments = ["mv", "foo", "bar"]
42
+ @router
43
+ .should_receive(:route)
44
+ .with("mv")
45
+ .and_return(@command)
46
+
47
+ @command.should_receive(:execute) do |input, output|
48
+ input.arguments.should eq ["foo", "bar"]
49
+ end
50
+ @shell.run(@input, @output)
51
+ end
52
+
53
+ it "should return false if the command throws an exception" do
54
+ @command
55
+ .should_receive(:execute)
56
+ .and_raise(StandardError)
57
+
58
+ @router
59
+ .should_receive(:route)
60
+ .and_return(@command)
61
+
62
+ @output.should_receive(:error)
63
+
64
+ @shell.run(@input, @output)
65
+ end
66
+
67
+ it "should send exception messages to stderr" do
68
+ @command.should_receive(:execute) { raise "Pool's Closed" }
69
+ @router.should_receive(:route).and_return(@command)
70
+
71
+ @output.should_receive(:error).with("ppl: Pool's Closed")
72
+
73
+ @shell.run(@input, @output)
74
+ end
75
+
76
+ end
77
+
78
+ end
79
+