ppl 0.3.0 → 0.9.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/Gemfile +2 -0
- data/Gemfile.lock +4 -0
- data/README.md +1 -3
- data/lib/ppl/adapter/storage/disk.rb +27 -7
- data/lib/ppl/adapter/storage/factory.rb +26 -0
- data/lib/ppl/adapter/storage/git.rb +101 -0
- data/lib/ppl/adapter/storage.rb +4 -0
- data/lib/ppl/adapter/vcard/vpim.rb +16 -0
- data/lib/ppl/application/bootstrap.rb +23 -10
- data/lib/ppl/application/command.rb +3 -0
- data/lib/ppl/application/command_suite.rb +8 -0
- data/lib/ppl/application/configuration.rb +50 -0
- data/lib/ppl/application/output.rb +1 -0
- data/lib/ppl/application/shell.rb +21 -0
- data/lib/ppl/command/add.rb +34 -0
- data/lib/ppl/command/bday.rb +72 -0
- data/lib/ppl/command/email.rb +55 -0
- data/lib/ppl/command/help.rb +43 -0
- data/lib/ppl/command/init.rb +26 -0
- data/lib/ppl/command/ls.rb +26 -0
- data/lib/ppl/command/mv.rb +42 -0
- data/lib/ppl/command/name.rb +54 -0
- data/lib/ppl/command/org.rb +55 -0
- data/lib/ppl/command/phone.rb +55 -0
- data/lib/ppl/command/rm.rb +26 -0
- data/lib/ppl/command/show.rb +31 -0
- data/lib/ppl/entity/contact.rb +2 -0
- data/lib/ppl/format/address_book/birthdays.rb +34 -0
- data/lib/ppl/format/address_book/email_addresses.rb +34 -0
- data/lib/ppl/format/address_book/names.rb +34 -0
- data/lib/ppl/format/address_book/one_line.rb +34 -0
- data/lib/ppl/format/address_book/organizations.rb +34 -0
- data/lib/ppl/format/address_book/phone_numbers.rb +34 -0
- data/lib/ppl/format/address_book.rb +9 -0
- data/lib/ppl/format/contact/birthday.rb +13 -0
- data/lib/ppl/format/contact/email_address.rb +13 -0
- data/lib/ppl/format/contact/full.rb +55 -0
- data/lib/ppl/format/contact/name.rb +15 -0
- data/lib/ppl/format/contact/organization.rb +13 -0
- data/lib/ppl/format/contact/phone_number.rb +13 -0
- data/lib/ppl/format/contact.rb +9 -0
- data/lib/ppl/format/table.rb +48 -0
- data/lib/ppl.rb +33 -11
- data/ppl.gemspec +1 -1
- data/spec/ppl/adapter/storage/disk_spec.rb +57 -10
- data/spec/ppl/adapter/storage/factory_spec.rb +34 -0
- data/spec/ppl/adapter/storage/git_spec.rb +114 -0
- data/spec/ppl/adapter/storage_spec.rb +6 -0
- data/spec/ppl/adapter/vcard/vpim_spec.rb +34 -0
- data/spec/ppl/application/bootstrap_spec.rb +42 -4
- data/spec/ppl/application/command_suite_spec.rb +8 -0
- data/spec/ppl/application/configuration_spec.rb +32 -0
- data/spec/ppl/application/shell_spec.rb +4 -0
- data/spec/ppl/command/{contact_add_spec.rb → add_spec.rb} +2 -2
- data/spec/ppl/command/bday_spec.rb +56 -0
- data/spec/ppl/command/email_spec.rb +56 -0
- data/spec/ppl/command/help_spec.rb +79 -0
- data/spec/ppl/command/init_spec.rb +40 -0
- data/spec/ppl/command/ls_spec.rb +32 -0
- data/spec/ppl/command/mv_spec.rb +62 -0
- data/spec/ppl/command/name_spec.rb +59 -0
- data/spec/ppl/command/org_spec.rb +57 -0
- data/spec/ppl/command/phone_spec.rb +55 -0
- data/spec/ppl/command/{contact_delete_spec.rb → rm_spec.rb} +8 -2
- data/spec/ppl/command/{contact_show_spec.rb → show_spec.rb} +12 -6
- data/spec/ppl/format/address_book/birthdays_spec.rb +38 -0
- data/spec/ppl/format/address_book/email_addresses_spec.rb +38 -0
- data/spec/ppl/format/address_book/names_spec.rb +38 -0
- data/spec/ppl/format/address_book/one_line_spec.rb +41 -0
- data/spec/ppl/format/address_book/organizations_spec.rb +38 -0
- data/spec/ppl/format/address_book/phone_numbers_spec.rb +38 -0
- data/spec/ppl/format/address_book_spec.rb +18 -0
- data/spec/ppl/format/contact/birthday_spec.rb +23 -0
- data/spec/ppl/format/contact/email_address_spec.rb +23 -0
- data/spec/ppl/format/contact/full_spec.rb +44 -0
- data/spec/ppl/format/contact/name_spec.rb +23 -0
- data/spec/ppl/format/contact/organization_spec.rb +23 -0
- data/spec/ppl/format/contact/phone_number_spec.rb +23 -0
- data/spec/ppl/format/contact_spec.rb +17 -0
- data/spec/ppl/format/table_spec.rb +72 -0
- metadata +61 -19
- data/lib/ppl/command/command_list.rb +0 -21
- data/lib/ppl/command/contact_add.rb +0 -26
- data/lib/ppl/command/contact_delete.rb +0 -16
- data/lib/ppl/command/contact_list.rb +0 -24
- data/lib/ppl/command/contact_rename.rb +0 -23
- data/lib/ppl/command/contact_show.rb +0 -20
- data/lib/ppl/command/set_birthday.rb +0 -30
- data/lib/ppl/command/set_email.rb +0 -23
- data/lib/ppl/command/set_name.rb +0 -28
- data/spec/ppl/command/command_list_spec.rb +0 -37
- data/spec/ppl/command/contact_list_spec.rb +0 -15
- data/spec/ppl/command/contact_rename_spec.rb +0 -42
- data/spec/ppl/command/set_birthday_spec.rb +0 -50
- data/spec/ppl/command/set_email_spec.rb +0 -38
- 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.
|
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
|
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/
|
41
|
-
require "ppl/command/
|
42
|
-
require "ppl/command/
|
43
|
-
require "ppl/command/
|
44
|
-
require "ppl/command/
|
45
|
-
require "ppl/command/
|
46
|
-
require "ppl/command/
|
47
|
-
require "ppl/command/
|
48
|
-
require "ppl/command/
|
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
@@ -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
|
5
|
-
|
6
|
-
@storage
|
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
|
-
|
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 '
|
32
|
-
@bootstrap.command_suite.find_command("
|
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
|
-
|
86
|
-
@
|
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
|
|
@@ -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
|
+
|