ppl 0.3.0 → 0.9.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (97) hide show
  1. data/.gitignore +1 -0
  2. data/Gemfile +2 -0
  3. data/Gemfile.lock +4 -0
  4. data/README.md +1 -3
  5. data/lib/ppl/adapter/storage/disk.rb +27 -7
  6. data/lib/ppl/adapter/storage/factory.rb +26 -0
  7. data/lib/ppl/adapter/storage/git.rb +101 -0
  8. data/lib/ppl/adapter/storage.rb +4 -0
  9. data/lib/ppl/adapter/vcard/vpim.rb +16 -0
  10. data/lib/ppl/application/bootstrap.rb +23 -10
  11. data/lib/ppl/application/command.rb +3 -0
  12. data/lib/ppl/application/command_suite.rb +8 -0
  13. data/lib/ppl/application/configuration.rb +50 -0
  14. data/lib/ppl/application/output.rb +1 -0
  15. data/lib/ppl/application/shell.rb +21 -0
  16. data/lib/ppl/command/add.rb +34 -0
  17. data/lib/ppl/command/bday.rb +72 -0
  18. data/lib/ppl/command/email.rb +55 -0
  19. data/lib/ppl/command/help.rb +43 -0
  20. data/lib/ppl/command/init.rb +26 -0
  21. data/lib/ppl/command/ls.rb +26 -0
  22. data/lib/ppl/command/mv.rb +42 -0
  23. data/lib/ppl/command/name.rb +54 -0
  24. data/lib/ppl/command/org.rb +55 -0
  25. data/lib/ppl/command/phone.rb +55 -0
  26. data/lib/ppl/command/rm.rb +26 -0
  27. data/lib/ppl/command/show.rb +31 -0
  28. data/lib/ppl/entity/contact.rb +2 -0
  29. data/lib/ppl/format/address_book/birthdays.rb +34 -0
  30. data/lib/ppl/format/address_book/email_addresses.rb +34 -0
  31. data/lib/ppl/format/address_book/names.rb +34 -0
  32. data/lib/ppl/format/address_book/one_line.rb +34 -0
  33. data/lib/ppl/format/address_book/organizations.rb +34 -0
  34. data/lib/ppl/format/address_book/phone_numbers.rb +34 -0
  35. data/lib/ppl/format/address_book.rb +9 -0
  36. data/lib/ppl/format/contact/birthday.rb +13 -0
  37. data/lib/ppl/format/contact/email_address.rb +13 -0
  38. data/lib/ppl/format/contact/full.rb +55 -0
  39. data/lib/ppl/format/contact/name.rb +15 -0
  40. data/lib/ppl/format/contact/organization.rb +13 -0
  41. data/lib/ppl/format/contact/phone_number.rb +13 -0
  42. data/lib/ppl/format/contact.rb +9 -0
  43. data/lib/ppl/format/table.rb +48 -0
  44. data/lib/ppl.rb +33 -11
  45. data/ppl.gemspec +1 -1
  46. data/spec/ppl/adapter/storage/disk_spec.rb +57 -10
  47. data/spec/ppl/adapter/storage/factory_spec.rb +34 -0
  48. data/spec/ppl/adapter/storage/git_spec.rb +114 -0
  49. data/spec/ppl/adapter/storage_spec.rb +6 -0
  50. data/spec/ppl/adapter/vcard/vpim_spec.rb +34 -0
  51. data/spec/ppl/application/bootstrap_spec.rb +42 -4
  52. data/spec/ppl/application/command_suite_spec.rb +8 -0
  53. data/spec/ppl/application/configuration_spec.rb +32 -0
  54. data/spec/ppl/application/shell_spec.rb +4 -0
  55. data/spec/ppl/command/{contact_add_spec.rb → add_spec.rb} +2 -2
  56. data/spec/ppl/command/bday_spec.rb +56 -0
  57. data/spec/ppl/command/email_spec.rb +56 -0
  58. data/spec/ppl/command/help_spec.rb +79 -0
  59. data/spec/ppl/command/init_spec.rb +40 -0
  60. data/spec/ppl/command/ls_spec.rb +32 -0
  61. data/spec/ppl/command/mv_spec.rb +62 -0
  62. data/spec/ppl/command/name_spec.rb +59 -0
  63. data/spec/ppl/command/org_spec.rb +57 -0
  64. data/spec/ppl/command/phone_spec.rb +55 -0
  65. data/spec/ppl/command/{contact_delete_spec.rb → rm_spec.rb} +8 -2
  66. data/spec/ppl/command/{contact_show_spec.rb → show_spec.rb} +12 -6
  67. data/spec/ppl/format/address_book/birthdays_spec.rb +38 -0
  68. data/spec/ppl/format/address_book/email_addresses_spec.rb +38 -0
  69. data/spec/ppl/format/address_book/names_spec.rb +38 -0
  70. data/spec/ppl/format/address_book/one_line_spec.rb +41 -0
  71. data/spec/ppl/format/address_book/organizations_spec.rb +38 -0
  72. data/spec/ppl/format/address_book/phone_numbers_spec.rb +38 -0
  73. data/spec/ppl/format/address_book_spec.rb +18 -0
  74. data/spec/ppl/format/contact/birthday_spec.rb +23 -0
  75. data/spec/ppl/format/contact/email_address_spec.rb +23 -0
  76. data/spec/ppl/format/contact/full_spec.rb +44 -0
  77. data/spec/ppl/format/contact/name_spec.rb +23 -0
  78. data/spec/ppl/format/contact/organization_spec.rb +23 -0
  79. data/spec/ppl/format/contact/phone_number_spec.rb +23 -0
  80. data/spec/ppl/format/contact_spec.rb +17 -0
  81. data/spec/ppl/format/table_spec.rb +72 -0
  82. metadata +61 -19
  83. data/lib/ppl/command/command_list.rb +0 -21
  84. data/lib/ppl/command/contact_add.rb +0 -26
  85. data/lib/ppl/command/contact_delete.rb +0 -16
  86. data/lib/ppl/command/contact_list.rb +0 -24
  87. data/lib/ppl/command/contact_rename.rb +0 -23
  88. data/lib/ppl/command/contact_show.rb +0 -20
  89. data/lib/ppl/command/set_birthday.rb +0 -30
  90. data/lib/ppl/command/set_email.rb +0 -23
  91. data/lib/ppl/command/set_name.rb +0 -28
  92. data/spec/ppl/command/command_list_spec.rb +0 -37
  93. data/spec/ppl/command/contact_list_spec.rb +0 -15
  94. data/spec/ppl/command/contact_rename_spec.rb +0 -42
  95. data/spec/ppl/command/set_birthday_spec.rb +0 -50
  96. data/spec/ppl/command/set_email_spec.rb +0 -38
  97. data/spec/ppl/command/set_name_spec.rb +0 -45
@@ -0,0 +1,48 @@
1
+
2
+ class Ppl::Format::Table
3
+
4
+ attr_accessor :columns
5
+ attr_accessor :rows
6
+
7
+ def initialize(columns=[])
8
+ @columns = columns
9
+ @rows = []
10
+
11
+ @column_widths = {}
12
+ @columns.each { |c| @column_widths[c] = 0 }
13
+ end
14
+
15
+ def add_row(row={})
16
+ row.each do |column, value|
17
+ width = sprintf("%s", value).length
18
+ max_width = @column_widths[column]
19
+ if width > max_width
20
+ @column_widths[column] = width
21
+ end
22
+ end
23
+ @rows.push(row)
24
+ end
25
+
26
+ def to_s
27
+ string = ""
28
+ @rows.each { |row| string += format_row(row).strip + "\n" }
29
+ string.strip
30
+ end
31
+
32
+
33
+ private
34
+
35
+ def format_row(row)
36
+ string = ""
37
+ @columns.each { |column| string += format_cell(row, column) }
38
+ return string
39
+ end
40
+
41
+ def format_cell(row, column)
42
+ width = @column_widths[column]
43
+ string = sprintf("%-#{width}s ", row[column])
44
+ return string
45
+ end
46
+
47
+ end
48
+
data/lib/ppl.rb CHANGED
@@ -1,7 +1,7 @@
1
1
 
2
2
  module Ppl
3
3
 
4
- Version = "0.3.0"
4
+ Version = "0.9.0"
5
5
 
6
6
  module Adapter
7
7
  end
@@ -18,7 +18,7 @@ module Ppl
18
18
  module Error
19
19
  end
20
20
 
21
- module Factory
21
+ module Format
22
22
  end
23
23
 
24
24
  end
@@ -26,26 +26,32 @@ end
26
26
 
27
27
  require "ppl/adapter/storage"
28
28
  require "ppl/adapter/storage/disk"
29
+ require "ppl/adapter/storage/factory"
30
+ require "ppl/adapter/storage/git"
29
31
  require "ppl/adapter/vcard"
30
32
  require "ppl/adapter/vcard/vpim"
31
33
 
32
34
  require "ppl/application/bootstrap"
33
35
  require "ppl/application/command"
34
36
  require "ppl/application/command_suite"
37
+ require "ppl/application/configuration"
35
38
  require "ppl/application/input"
36
39
  require "ppl/application/output"
37
40
  require "ppl/application/router"
38
41
  require "ppl/application/shell"
39
42
 
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
- require "ppl/command/set_birthday"
47
- require "ppl/command/set_email"
48
- require "ppl/command/set_name"
43
+ require "ppl/command/init"
44
+ require "ppl/command/bday"
45
+ require "ppl/command/ls"
46
+ require "ppl/command/add"
47
+ require "ppl/command/rm"
48
+ require "ppl/command/help"
49
+ require "ppl/command/show"
50
+ require "ppl/command/mv"
51
+ require "ppl/command/name"
52
+ require "ppl/command/email"
53
+ require "ppl/command/org"
54
+ require "ppl/command/phone"
49
55
 
50
56
  require "ppl/entity/address_book"
51
57
  require "ppl/entity/contact"
@@ -53,6 +59,22 @@ require "ppl/entity/contact"
53
59
  require "ppl/error/contact_not_found"
54
60
  require "ppl/error/incorrect_usage"
55
61
 
62
+ require "ppl/format/address_book"
63
+ require "ppl/format/address_book/birthdays"
64
+ require "ppl/format/address_book/email_addresses"
65
+ require "ppl/format/address_book/names"
66
+ require "ppl/format/address_book/one_line"
67
+ require "ppl/format/address_book/organizations"
68
+ require "ppl/format/address_book/phone_numbers"
69
+ require "ppl/format/contact"
70
+ require "ppl/format/contact/birthday"
71
+ require "ppl/format/contact/email_address"
72
+ require "ppl/format/contact/full"
73
+ require "ppl/format/contact/name"
74
+ require "ppl/format/contact/organization"
75
+ require "ppl/format/contact/phone_number"
76
+ require "ppl/format/table"
77
+
56
78
  class String
57
79
  alias_method :each, :each_line
58
80
  end
data/ppl.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
  Gem::Specification.new do |spec|
3
3
 
4
4
  spec.name = "ppl"
5
- spec.version = "0.3.0"
5
+ spec.version = "0.9.0"
6
6
  spec.date = "2012-11-23"
7
7
 
8
8
  spec.summary = "CLI Address Book"
@@ -1,9 +1,35 @@
1
1
 
2
+ describe Ppl::Adapter::Storage::Disk, "#create_address_book" do
3
+
4
+ before(:each) do
5
+ FakeFS.activate!
6
+ end
7
+
8
+ after(:each) do
9
+ FakeFS.deactivate!
10
+ end
11
+
12
+ describe "#create_address_book" do
13
+ it "should create the directory if it doesn't exist yet" do
14
+ Ppl::Adapter::Storage::Disk.create_address_book("/contacts")
15
+ Dir.exists?("/contacts").should eq true
16
+ FileUtils.rm_rf("/contacts")
17
+ end
18
+ it "should return a Ppl::Adapter::Storage::Disk" do
19
+ disk = Ppl::Adapter::Storage::Disk.create_address_book("/contacts")
20
+ FileUtils.rm_rf("/contacts")
21
+ disk.should be_a(Ppl::Adapter::Storage::Disk)
22
+ end
23
+ end
24
+
25
+ end
26
+
2
27
  describe Ppl::Adapter::Storage::Disk, "#initialize" do
3
28
 
4
- it "should accept a path" do
5
- @storage = Ppl::Adapter::Storage::Disk.new("/tmp")
6
- @storage.path.should eq "/tmp"
29
+ it "should accept a Dir object" do
30
+ directory = Dir.new("/tmp")
31
+ @storage = Ppl::Adapter::Storage::Disk.new(directory)
32
+ @storage.directory.should be directory
7
33
  end
8
34
 
9
35
  end
@@ -27,13 +53,15 @@ end
27
53
  describe Ppl::Adapter::Storage::Disk do
28
54
 
29
55
  before(:each) do
30
- @storage = Ppl::Adapter::Storage::Disk.new("/contacts")
56
+ FakeFS.activate!
57
+
58
+ Dir.mkdir "/contacts"
59
+ directory = Dir.new("/contacts")
60
+
61
+ @storage = Ppl::Adapter::Storage::Disk.new(directory)
31
62
  @adapter = double(Ppl::Adapter::Vcard)
32
63
  @contact = Ppl::Entity::Contact.new
33
64
  @storage.vcard_adapter = @adapter
34
-
35
- FakeFS.activate!
36
- Dir.mkdir "/contacts"
37
65
  end
38
66
 
39
67
  after(:each) do
@@ -81,9 +109,6 @@ describe Ppl::Adapter::Storage::Disk do
81
109
 
82
110
  describe "#save_contact" do
83
111
 
84
- before(:each) do
85
- end
86
-
87
112
  it "should write the contact to disk" do
88
113
  @adapter.should_receive(:encode).with(@contact).and_return("asdfg")
89
114
 
@@ -95,5 +120,27 @@ describe Ppl::Adapter::Storage::Disk do
95
120
 
96
121
  end
97
122
 
123
+ describe "#delete_contact" do
124
+ it "should remove the the contact from the disk" do
125
+ FileUtils.touch "/contacts/test.vcf"
126
+ @contact.id = "test"
127
+ @storage.delete_contact(@contact)
128
+ File.exists?("/contacts/test.vcf").should eq false
129
+ end
130
+ end
131
+
132
+ describe "#filename_for_contact" do
133
+ it "should base the filename on the contact's id" do
134
+ @contact.id = "test"
135
+ @storage.filename_for_contact(@contact).should eq "/contacts/test.vcf"
136
+ end
137
+ end
138
+
139
+ describe "#filename_for_contact_id" do
140
+ it "should base the filename on the directory path" do
141
+ @storage.filename_for_contact_id("test").should eq "/contacts/test.vcf"
142
+ end
143
+ end
144
+
98
145
  end
99
146
 
@@ -0,0 +1,34 @@
1
+
2
+ describe Ppl::Adapter::Storage::Factory do
3
+
4
+ before(:each) do
5
+ FakeFS.activate!
6
+ Dir.mkdir "/contacts"
7
+
8
+ @factory = Ppl::Adapter::Storage::Factory.new(nil)
9
+ @directory = Dir.new("/contacts")
10
+ @repo = double(Rugged::Repository)
11
+
12
+ Rugged::Repository.stub(:new).and_return(@repo)
13
+ end
14
+
15
+ after(:each) do
16
+ FileUtils.rm_rf "/contacts"
17
+ FakeFS.deactivate!
18
+ end
19
+
20
+ describe "#load_adapter" do
21
+
22
+ it "should return a disk adapter by default" do
23
+ @factory.load_adapter(@directory).should be_a(Ppl::Adapter::Storage::Disk)
24
+ end
25
+
26
+ it "should return a git adapter if the directory is a git repository" do
27
+ Dir.mkdir "/contacts/.git"
28
+ @factory.load_adapter(@directory).should be_a(Ppl::Adapter::Storage::Git)
29
+ end
30
+
31
+ end
32
+
33
+ end
34
+
@@ -0,0 +1,114 @@
1
+
2
+ require "ostruct"
3
+
4
+ describe Ppl::Adapter::Storage::Git, "#initialize" do
5
+
6
+ before(:each) do
7
+ FakeFS.activate!
8
+ Dir.mkdir "/contacts"
9
+
10
+ @disk = double(Ppl::Adapter::Storage::Disk)
11
+ @contact = double(Ppl::Entity::Contact)
12
+ @repo = double(Rugged::Repository)
13
+ @commit = double(Rugged::Commit)
14
+ @vcard = double(Ppl::Adapter::Vcard)
15
+
16
+ Rugged::Repository.stub(:new).and_return(@repo)
17
+
18
+ @disk.stub(:directory).and_return(Dir.new("/contacts"))
19
+ @contact.stub(:id).and_return("test")
20
+
21
+ @git = Ppl::Adapter::Storage::Git.new(@disk)
22
+ @git.vcard_adapter = @vcard
23
+ end
24
+
25
+ after(:each) do
26
+ FileUtils.rm_rf "/contacts"
27
+ FakeFS.deactivate!
28
+ end
29
+
30
+ describe "#initialize" do
31
+ it "should accept a disk storage adapter" do
32
+ @git.disk.should be @disk
33
+ end
34
+ it "should instantiate rugged" do
35
+ @git.repository.should be @repo
36
+ end
37
+ end
38
+
39
+ describe "#load_address_book" do
40
+
41
+ before(:each) do
42
+ @head = double(Rugged::Reference)
43
+
44
+ @files = [{:name => "test.vcf"}]
45
+
46
+ @commit.should_receive(:target)
47
+ @repo.should_receive(:lookup).and_return(@head)
48
+ @repo.should_receive(:head).and_return(@commit)
49
+
50
+ @git.stub(:load_contact) do |id|
51
+ contact = Ppl::Entity::Contact.new
52
+ contact.id = id
53
+ contact
54
+ end
55
+
56
+ end
57
+
58
+ it "should return an address book" do
59
+ @head.should_receive(:tree).and_return(@files)
60
+ @git.load_address_book.should be_a(Ppl::Entity::AddressBook)
61
+ end
62
+
63
+ it "should not put anything except contacts in the address book" do
64
+ @files = [{:name => "poop.vcf"}, {:name => ".ppl"}]
65
+ @head.should_receive(:tree).and_return(@files)
66
+
67
+ address_book = @git.load_address_book
68
+ address_book.each do |contact|
69
+ contact.should be_a(Ppl::Entity::Contact)
70
+ end
71
+ end
72
+
73
+ end
74
+
75
+ describe "#load_contact" do
76
+
77
+ it "should return a contact" do
78
+ head = OpenStruct.new
79
+ head.target = "asdfg"
80
+
81
+ @repo.should_receive(:head).and_return(head)
82
+ @repo.should_receive(:file_at).and_return("vcard contents")
83
+ @vcard.should_receive(:decode).and_return(@contact)
84
+ @contact.should_receive(:id=).with("test")
85
+
86
+ contact = @git.load_contact("test")
87
+ end
88
+
89
+ end
90
+
91
+ describe "#save_contact" do
92
+
93
+ it "should save the contact to disk" do
94
+ @disk.should_receive(:save_contact).with(@contact)
95
+ @git.stub(:add)
96
+ @git.stub(:commit)
97
+ @git.save_contact(@contact)
98
+ end
99
+
100
+ it "should commit the changes" do
101
+ @disk.should_receive(:save_contact)
102
+ @git.stub(:add) do |file|
103
+ file.should eq "test.vcf"
104
+ end
105
+ @git.stub(:commit) do |message|
106
+ message.should eq "save_contact(test)"
107
+ end
108
+ @git.save_contact(@contact)
109
+ end
110
+
111
+ end
112
+
113
+ end
114
+
@@ -5,6 +5,12 @@ describe Ppl::Adapter::Storage do
5
5
  @storage = Ppl::Adapter::Storage.new
6
6
  end
7
7
 
8
+ describe "#create_address_book" do
9
+ it "should raise not implemented error" do
10
+ expect{Ppl::Adapter::Storage.create_address_book(nil)}.to raise_error(NotImplementedError)
11
+ end
12
+ end
13
+
8
14
  describe "#delete_contact" do
9
15
  it "should raise not implemented error" do
10
16
  expect{@storage.delete_contact(nil)}.to raise_error(NotImplementedError)
@@ -22,6 +22,16 @@ describe Ppl::Adapter::Vcard::Vpim, "#encode" do
22
22
  @adapter.encode(@contact).should include("EMAIL:john@example.org")
23
23
  end
24
24
 
25
+ it "should encode the contact's phone number" do
26
+ @contact.phone_number = "01234567890"
27
+ @adapter.encode(@contact).should include("TEL:01234567890")
28
+ end
29
+
30
+ it "should encode the contact's organization" do
31
+ @contact.organization = "Example Ltd"
32
+ @adapter.encode(@contact).should include("ORG:Example Ltd")
33
+ end
34
+
25
35
  end
26
36
 
27
37
 
@@ -78,5 +88,29 @@ describe Ppl::Adapter::Vcard::Vpim, "#decode" do
78
88
  contact.email_address.should eq "home@example.org"
79
89
  end
80
90
 
91
+ it "should decode the contact's phone number" do
92
+ vcard = [
93
+ "BEGIN:VCARD",
94
+ "N:,test",
95
+ "VERSION:3.0",
96
+ "TEL:01234567890",
97
+ "END:VCARD",
98
+ ].join("\n")
99
+ contact = @adapter.decode(vcard)
100
+ contact.phone_number.should eq "01234567890"
101
+ end
102
+
103
+ it "should decode the contact's organization" do
104
+ vcard = [
105
+ "BEGIN:VCARD",
106
+ "N:,test",
107
+ "VERSION:3.0",
108
+ "ORG:Example Ltd",
109
+ "END:VCARD",
110
+ ].join("\n")
111
+ contact = @adapter.decode(vcard)
112
+ contact.organization.should eq "Example Ltd"
113
+ end
114
+
81
115
  end
82
116
 
@@ -6,6 +6,9 @@ describe Ppl::Application::Bootstrap do
6
6
  end
7
7
 
8
8
  describe "#commands" do
9
+ before(:each) do
10
+ @bootstrap.stub(:storage_adapter).and_return(Ppl::Adapter::Storage.new)
11
+ end
9
12
  it "should return an array" do
10
13
  @bootstrap.commands.should be_an(Array)
11
14
  end
@@ -22,18 +25,26 @@ describe Ppl::Application::Bootstrap do
22
25
  end
23
26
 
24
27
  describe "#command_suite" do
28
+
29
+ before(:each) do
30
+ @bootstrap.stub(:storage_adapter)
31
+ end
32
+
25
33
  it "should return a Ppl::Application::CommandSuite" do
26
34
  @bootstrap.command_suite.should be_a(Ppl::Application::CommandSuite)
27
35
  end
28
36
  it "should contain the 'add' command" do
29
37
  @bootstrap.command_suite.find_command("add").should_not be nil
30
38
  end
31
- it "should contain the 'birthday' command" do
32
- @bootstrap.command_suite.find_command("birthday").should_not be nil
39
+ it "should contain the 'bday' command" do
40
+ @bootstrap.command_suite.find_command("bday").should_not be nil
33
41
  end
34
42
  it "should contain the 'email' command" do
35
43
  @bootstrap.command_suite.find_command("email").should_not be nil
36
44
  end
45
+ it "should contain the 'init' command" do
46
+ @bootstrap.command_suite.find_command("init").should_not be nil
47
+ end
37
48
  it "should contain the 'ls' command" do
38
49
  @bootstrap.command_suite.find_command("ls").should_not be nil
39
50
  end
@@ -43,6 +54,12 @@ describe Ppl::Application::Bootstrap do
43
54
  it "should contain the 'name' command" do
44
55
  @bootstrap.command_suite.find_command("name").should_not be nil
45
56
  end
57
+ it "should contain the 'org' command" do
58
+ @bootstrap.command_suite.find_command("org").should_not be nil
59
+ end
60
+ it "should contain the 'phone' command" do
61
+ @bootstrap.command_suite.find_command("phone").should_not be nil
62
+ end
46
63
  it "should contain the 'rm' command" do
47
64
  @bootstrap.command_suite.find_command("rm").should_not be nil
48
65
  end
@@ -54,6 +71,12 @@ describe Ppl::Application::Bootstrap do
54
71
  end
55
72
  end
56
73
 
74
+ describe "#configuration" do
75
+ it "should return a Ppl::Application::Configuration" do
76
+ @bootstrap.configuration.should be_a(Ppl::Application::Configuration)
77
+ end
78
+ end
79
+
57
80
  describe "#input" do
58
81
  it "should return a Ppl::Application::Input" do
59
82
  @bootstrap.input.should be_a(Ppl::Application::Input)
@@ -67,6 +90,9 @@ describe Ppl::Application::Bootstrap do
67
90
  end
68
91
 
69
92
  describe "#router" do
93
+ before(:each) do
94
+ @bootstrap.stub(:storage_adapter)
95
+ end
70
96
  it "should return a Ppl::Application::Router" do
71
97
  @bootstrap.router.should be_a(Ppl::Application::Router)
72
98
  end
@@ -76,14 +102,26 @@ describe Ppl::Application::Bootstrap do
76
102
  end
77
103
 
78
104
  describe "#shell" do
105
+ before(:each) do
106
+ @bootstrap.stub(:storage_adapter)
107
+ end
79
108
  it "should return a Ppl::Application::Shell" do
80
109
  @bootstrap.shell.should be_a(Ppl::Application::Shell)
81
110
  end
82
111
  end
83
112
 
84
113
  describe "#storage_adapter" do
85
- it "should return a Ppl::Adapter::Storage::Disk" do
86
- @bootstrap.storage_adapter.should be_a(Ppl::Adapter::Storage::Disk)
114
+ before(:each) do
115
+ @config = double(Ppl::Application::Configuration)
116
+ @factory = double(Ppl::Adapter::Storage::Factory)
117
+ @bootstrap.stub(:configuration).and_return(@config)
118
+ Ppl::Adapter::Storage::Factory.stub(:new).and_return(@factory)
119
+
120
+ @config.should_receive(:address_book_path).and_return("/tmp")
121
+ @factory.should_receive(:load_adapter).and_return(Ppl::Adapter::Storage::Disk.new(nil))
122
+ end
123
+ it "should return a Ppl::Adapter::Storage" do
124
+ @bootstrap.storage_adapter.should be_a(Ppl::Adapter::Storage)
87
125
  end
88
126
  end
89
127
 
@@ -40,5 +40,13 @@ describe Ppl::Application::CommandSuite do
40
40
  end
41
41
  end
42
42
 
43
+ describe "#sort_by_name" do
44
+ it "should sort the commands alphabetically by name" do
45
+ @command_suite.sort_by_name
46
+ @command_suite[0].name.should eq "bar"
47
+ @command_suite[1].name.should eq "foo"
48
+ end
49
+ end
50
+
43
51
  end
44
52
 
@@ -0,0 +1,32 @@
1
+
2
+ describe Ppl::Application::Configuration do
3
+
4
+ before(:each) do
5
+ FakeFS.activate!
6
+ @config = Ppl::Application::Configuration.new
7
+ end
8
+
9
+ after(:each) do
10
+ FakeFS.deactivate!
11
+ end
12
+
13
+ describe "#address_book_path" do
14
+ it "should default to the current working directory" do
15
+ @config.address_book_path.should eq Dir.pwd
16
+ end
17
+ it "should be configurable by the user's config file" do
18
+ @config.stub(:user_configuration) do
19
+ {"address book" => {"path" => "/contacts"}}
20
+ end
21
+ @config.address_book_path.should eq "/contacts"
22
+ end
23
+ end
24
+
25
+ describe "#aliases" do
26
+ it "should return a hash" do
27
+ @config.aliases.should be_a(Hash)
28
+ end
29
+ end
30
+
31
+ end
32
+
@@ -30,6 +30,7 @@ describe Ppl::Application::Shell do
30
30
  .with("foo")
31
31
  .and_return(@command)
32
32
 
33
+ @command.should_receive(:options)
33
34
  @command
34
35
  .should_receive(:execute)
35
36
  .and_return(true)
@@ -44,6 +45,7 @@ describe Ppl::Application::Shell do
44
45
  .with("mv")
45
46
  .and_return(@command)
46
47
 
48
+ @command.should_receive(:options)
47
49
  @command.should_receive(:execute) do |input, output|
48
50
  input.arguments.should eq ["foo", "bar"]
49
51
  end
@@ -51,6 +53,7 @@ describe Ppl::Application::Shell do
51
53
  end
52
54
 
53
55
  it "should return false if the command throws an exception" do
56
+ @command.should_receive(:options)
54
57
  @command
55
58
  .should_receive(:execute)
56
59
  .and_raise(StandardError)
@@ -65,6 +68,7 @@ describe Ppl::Application::Shell do
65
68
  end
66
69
 
67
70
  it "should send exception messages to stderr" do
71
+ @command.should_receive(:options)
68
72
  @command.should_receive(:execute) { raise "Pool's Closed" }
69
73
  @router.should_receive(:route).and_return(@command)
70
74
 
@@ -1,8 +1,8 @@
1
1
 
2
- describe Ppl::Command::ContactAdd do
2
+ describe Ppl::Command::Add do
3
3
 
4
4
  before(:each) do
5
- @command = Ppl::Command::ContactAdd.new
5
+ @command = Ppl::Command::Add.new
6
6
  @input = Ppl::Application::Input.new
7
7
  @storage = double(Ppl::Adapter::Storage)
8
8
 
@@ -0,0 +1,56 @@
1
+
2
+ describe Ppl::Command::Bday do
3
+
4
+ before(:each) do
5
+ @input = Ppl::Application::Input.new
6
+ @output = Ppl::Application::Output.new(nil, nil)
7
+ @contact = Ppl::Entity::Contact.new
8
+ @command = Ppl::Command::Bday.new
9
+ @storage = double(Ppl::Adapter::Storage)
10
+ @show_format = double(Ppl::Format::Contact)
11
+
12
+ @command.storage = @storage
13
+ @command.show_format = @show_format
14
+ @contact.id = "jim"
15
+ end
16
+
17
+ describe "#name" do
18
+ it "should be 'bday'" do
19
+ @command.name.should eq "bday"
20
+ end
21
+ end
22
+
23
+ describe "#execute" do
24
+
25
+ it "should list all birthdays if no contact is specified" do
26
+ #@input.arguments = []
27
+ #@command.execute(@input, @output)
28
+ end
29
+
30
+ it "should raise an error if the date given isn't a valid date" do
31
+ @storage.should_receive(:require_contact).and_return(@contact)
32
+ @input.arguments = ["jim", "poiuytrewq"]
33
+ expect{@command.execute(@input, @output)}.to raise_error(Ppl::Error::IncorrectUsage)
34
+ end
35
+
36
+ it "should show the contact's birthday if no date is given" do
37
+ @storage.should_receive(:require_contact).and_return(@contact)
38
+ @show_format.should_receive(:process).and_return("1970-01-01")
39
+ @output.should_receive(:line).with("1970-01-01")
40
+ @input.arguments = ["jim"]
41
+ @command.execute(@input, @output)
42
+ end
43
+
44
+ it "should change the contact's birthday if a date is given" do
45
+ @storage.should_receive(:require_contact).and_return(@contact)
46
+ @storage.should_receive(:save_contact) do |contact|
47
+ contact.birthday.strftime.should eq "1980-01-01"
48
+ end
49
+ @input.arguments = ["jim", "1980-01-01"]
50
+ @command.execute(@input, @output)
51
+ end
52
+
53
+ end
54
+
55
+ end
56
+