ppl 0.0.5 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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,37 @@
1
+
2
+ describe Ppl::Command::CommandList do
3
+
4
+ before(:each) do
5
+ @command = Ppl::Command::CommandList.new
6
+ @output = double(Ppl::Application::Output)
7
+ end
8
+
9
+ describe "#command_suite=" do
10
+ it "should accept a value" do
11
+ suite = Object.new
12
+ @command.command_suite = suite
13
+ @command.command_suite.should be suite
14
+ end
15
+ end
16
+
17
+ describe "#name" do
18
+ it "should be 'help'" do
19
+ @command.name.should eq "help"
20
+ end
21
+ end
22
+
23
+ describe "#execute" do
24
+ it "should list available commands" do
25
+ command = double(Ppl::Application::Command)
26
+ command.should_receive(:name).and_return("one")
27
+ command.should_receive(:description).and_return("The first command")
28
+ @command.command_suite = [command]
29
+
30
+ @output.should_receive(:line).with("one: The first command")
31
+
32
+ @command.execute(nil, @output)
33
+ end
34
+ end
35
+
36
+ end
37
+
@@ -0,0 +1,41 @@
1
+
2
+ describe Ppl::Command::ContactAdd do
3
+
4
+ before(:each) do
5
+ @command = Ppl::Command::ContactAdd.new
6
+ @input = Ppl::Application::Input.new
7
+ @storage = double(Ppl::Adapter::Storage)
8
+
9
+ @command.storage = @storage
10
+ end
11
+
12
+ describe "#name" do
13
+ it "should be 'add'" do
14
+ @command.name.should eq "add"
15
+ end
16
+ end
17
+
18
+ describe "#execute" do
19
+
20
+ it "should raise a Ppl::Error::IncorrectUsage if no id is given" do
21
+ expect{@command.execute(@input, nil)}.to raise_error(Ppl::Error::IncorrectUsage)
22
+ end
23
+
24
+ it "should raise a Ppl::Error::IncorrectUsage if no name is given" do
25
+ @input.arguments = ["some_id"]
26
+ expect{@command.execute(@input, nil)}.to raise_error(Ppl::Error::IncorrectUsage)
27
+ end
28
+
29
+ it "should save a new contact" do
30
+ @storage.should_receive(:save_contact) do |contact|
31
+ contact.id.should eq "john"
32
+ contact.name.should eq "John Doe"
33
+ end
34
+ @input.arguments = ["john", "John Doe"]
35
+ @command.execute(@input, nil)
36
+ end
37
+
38
+ end
39
+
40
+ end
41
+
@@ -0,0 +1,31 @@
1
+
2
+ describe Ppl::Command::ContactDelete 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::ContactDelete.new
9
+ @storage = double(Ppl::Adapter::Storage)
10
+
11
+ @command.storage = @storage
12
+ end
13
+
14
+ describe "#name" do
15
+ it "should be 'rm'" do
16
+ @command.name.should eq "rm"
17
+ end
18
+ end
19
+
20
+ describe "#execute" do
21
+
22
+ it "should delete the given contact" do
23
+ @storage.should_receive(:require_contact).and_return(@contact)
24
+ @storage.should_receive(:delete_contact).with(@contact)
25
+ @command.execute(@input, @output)
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+
@@ -0,0 +1,15 @@
1
+
2
+ describe Ppl::Command::ContactList do
3
+
4
+ before(:each) do
5
+ @command = Ppl::Command::ContactList.new
6
+ end
7
+
8
+ describe "#name" do
9
+ it "should be 'ls'" do
10
+ @command.name.should eq "ls"
11
+ end
12
+ end
13
+
14
+ end
15
+
@@ -0,0 +1,42 @@
1
+
2
+ describe Ppl::Command::ContactRename 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::ContactRename.new
9
+ @storage = double(Ppl::Adapter::Storage)
10
+
11
+ @command.storage = @storage
12
+ @contact.id = "old"
13
+ end
14
+
15
+ describe "#name" do
16
+ it "should be 'mv'" do
17
+ @command.name.should eq "mv"
18
+ end
19
+ end
20
+
21
+ describe "#execute" do
22
+
23
+ it "should rename the given contact" do
24
+ @storage.should_receive(:require_contact).and_return(@contact)
25
+
26
+ @storage.should_receive(:delete_contact).with(@contact) do |contact|
27
+ contact.id.should eq "old"
28
+ end
29
+
30
+ @storage.should_receive(:save_contact).with(@contact) do |contact|
31
+ contact.id.should eq "new"
32
+ end
33
+
34
+ @input.arguments = ["old", "new"]
35
+
36
+ @command.execute(@input, @output)
37
+ end
38
+
39
+ end
40
+
41
+ end
42
+
@@ -0,0 +1,35 @@
1
+
2
+ describe Ppl::Command::ContactShow do
3
+
4
+ before(:each) do
5
+ @command = Ppl::Command::ContactShow.new
6
+ @input = Ppl::Application::Input.new
7
+ @output = double(Ppl::Application::Output)
8
+ @contact = Ppl::Entity::Contact.new
9
+ @storage = double(Ppl::Adapter::Storage)
10
+
11
+ @command.storage = @storage
12
+ end
13
+
14
+ describe "#name" do
15
+ it "should be 'show'" do
16
+ @command.name.should eq "show"
17
+ end
18
+ end
19
+
20
+ describe "#execute" do
21
+ it "should show the contact's name" do
22
+ @storage.should_receive(:require_contact).and_return(@contact)
23
+
24
+ @contact.name = "John Doe"
25
+ @contact.email_address = "johndoe@example.org"
26
+
27
+ @output.should_receive(:line).with("John Doe")
28
+ @output.should_receive(:line).with("johndoe@example.org")
29
+
30
+ @command.execute(@input, @output)
31
+ end
32
+ end
33
+
34
+ end
35
+
@@ -0,0 +1,26 @@
1
+
2
+ describe Ppl::Entity::AddressBook do
3
+
4
+ before(:each) do
5
+ @address_book = Ppl::Entity::AddressBook.new
6
+ end
7
+
8
+ describe "#add_contact" do
9
+ it "should accept a contact" do
10
+ @address_book.add_contact(double(Ppl::Entity::Contact))
11
+ @address_book.count.should be 1
12
+ end
13
+ end
14
+
15
+ describe "#each" do
16
+ it "should yield contacts" do
17
+ contact = double(Ppl::Entity::Contact)
18
+ @address_book.add_contact(contact)
19
+ @address_book.each do |c|
20
+ c.should be contact
21
+ end
22
+ end
23
+ end
24
+
25
+ end
26
+
@@ -0,0 +1,34 @@
1
+
2
+ describe Ppl::Entity::Contact do
3
+
4
+ before(:each) do
5
+ @contact = Ppl::Entity::Contact.new
6
+ end
7
+
8
+ describe "#id" do
9
+ it "should return a value" do
10
+ @contact.id.should be nil
11
+ end
12
+ end
13
+
14
+ describe "#id=" do
15
+ it "should accept a value" do
16
+ @contact.id = "john"
17
+ @contact.id.should eq "john"
18
+ end
19
+ end
20
+
21
+ describe "#email_address" do
22
+ it "should return a value" do
23
+ @contact.email_address.should eq nil
24
+ end
25
+ end
26
+
27
+ describe "#birthday" do
28
+ it "should return a value" do
29
+ @contact.birthday.should eq nil
30
+ end
31
+ end
32
+
33
+ end
34
+
@@ -0,0 +1,9 @@
1
+
2
+ require "fakefs/safe"
3
+ require "pathname"
4
+
5
+ bin_file = Pathname.new(__FILE__).realpath
6
+ $:.unshift File.expand_path("../../lib", bin_file)
7
+
8
+ require "ppl"
9
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ppl
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.5
4
+ version: 0.2.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,33 +9,66 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-11-13 00:00:00.000000000 Z
12
+ date: 2012-11-23 00:00:00.000000000 Z
13
13
  dependencies: []
14
- description: Command-line driven address book
14
+ description: CLI Address Book
15
15
  email: henry@henrysmith.org
16
16
  executables:
17
17
  - ppl
18
18
  extensions: []
19
19
  extra_rdoc_files: []
20
20
  files:
21
+ - .gitignore
22
+ - .rspec
23
+ - .travis.yml
21
24
  - COPYING
22
25
  - Gemfile
23
26
  - Gemfile.lock
24
27
  - README.md
25
28
  - bin/ppl
26
29
  - lib/ppl.rb
27
- - lib/ppl/address_book.rb
28
- - lib/ppl/cli.rb
29
- - lib/ppl/command.rb
30
- - lib/ppl/command/add.rb
31
- - lib/ppl/command/birthdays.rb
32
- - lib/ppl/command/help.rb
33
- - lib/ppl/command/list.rb
34
- - lib/ppl/command/rm.rb
35
- - lib/ppl/command/set.rb
36
- - lib/ppl/command/show.rb
37
- - lib/ppl/contact.rb
30
+ - lib/ppl/adapter/storage.rb
31
+ - lib/ppl/adapter/storage/disk.rb
32
+ - lib/ppl/adapter/vcard.rb
33
+ - lib/ppl/adapter/vcard/vpim.rb
34
+ - lib/ppl/application/bootstrap.rb
35
+ - lib/ppl/application/command.rb
36
+ - lib/ppl/application/command_suite.rb
37
+ - lib/ppl/application/input.rb
38
+ - lib/ppl/application/output.rb
39
+ - lib/ppl/application/router.rb
40
+ - lib/ppl/application/shell.rb
41
+ - lib/ppl/command/command_list.rb
42
+ - lib/ppl/command/contact_add.rb
43
+ - lib/ppl/command/contact_delete.rb
44
+ - lib/ppl/command/contact_list.rb
45
+ - lib/ppl/command/contact_rename.rb
46
+ - lib/ppl/command/contact_show.rb
47
+ - lib/ppl/entity/address_book.rb
48
+ - lib/ppl/entity/contact.rb
49
+ - lib/ppl/error/contact_not_found.rb
50
+ - lib/ppl/error/incorrect_usage.rb
38
51
  - ppl.gemspec
52
+ - spec/ppl/adapter/output_spec.rb
53
+ - spec/ppl/adapter/storage/disk_spec.rb
54
+ - spec/ppl/adapter/storage_spec.rb
55
+ - spec/ppl/adapter/vcard/vpim_spec.rb
56
+ - spec/ppl/adapter/vcard_spec.rb
57
+ - spec/ppl/application/bootstrap_spec.rb
58
+ - spec/ppl/application/command_spec.rb
59
+ - spec/ppl/application/command_suite_spec.rb
60
+ - spec/ppl/application/input_spec.rb
61
+ - spec/ppl/application/router_spec.rb
62
+ - spec/ppl/application/shell_spec.rb
63
+ - spec/ppl/command/command_list_spec.rb
64
+ - spec/ppl/command/contact_add_spec.rb
65
+ - spec/ppl/command/contact_delete_spec.rb
66
+ - spec/ppl/command/contact_list_spec.rb
67
+ - spec/ppl/command/contact_rename_spec.rb
68
+ - spec/ppl/command/contact_show_spec.rb
69
+ - spec/ppl/entity/address_book_spec.rb
70
+ - spec/ppl/entity/contact_spec.rb
71
+ - spec/spec_helper.rb
39
72
  homepage: https://github.com/h2s/ppl
40
73
  licenses:
41
74
  - GPL-2
@@ -1,74 +0,0 @@
1
-
2
- require "vpim/vcard"
3
- require "enumerator"
4
-
5
- class Ppl::Address_Book
6
-
7
- include Enumerable
8
-
9
- def initialize(path)
10
- @path = path
11
- end
12
-
13
- def contact(id)
14
- filename = File.join @path, id + ".vcard"
15
- if !File.exists? filename
16
- return nil
17
- end
18
-
19
- vcard = IO.read filename
20
- vcard = Vpim::Vcard.decode(vcard).first
21
- contact = Ppl::Contact.new(id, vcard)
22
- end
23
-
24
- def contacts
25
- pattern = File.join @path, "*.vcard"
26
- filenames = Dir.glob pattern
27
- contacts = []
28
-
29
- filenames.each do |filename|
30
- id = File.basename(filename).slice(0..-7)
31
- contacts.push self.contact(id);
32
- end
33
- contacts
34
-
35
- end
36
-
37
- def each
38
- self.contacts.each { |c| yield c }
39
- end
40
-
41
- def with_birthday
42
- self.find_all { |contact| contact.birthday.nil? == false }
43
- end
44
-
45
- def create_contact(id, full_name)
46
-
47
- vcard = Vpim::Vcard::Maker.make2 do |maker|
48
- maker.add_name do |name|
49
- name.given = full_name
50
- end
51
- end
52
-
53
- contact = Ppl::Contact.new(id, vcard)
54
- self.save_contact contact
55
- contact
56
- end
57
-
58
- def delete_contact(id)
59
- filename = File.join @path, id + ".vcard"
60
- if !File.exists? filename
61
- return false
62
- end
63
- File.delete filename
64
- end
65
-
66
- def save_contact(contact)
67
- filename = File.join @path, contact.id + ".vcard"
68
- File.open(filename, "w") do |file|
69
- file.write contact.to_s
70
- end
71
- end
72
-
73
- end
74
-
data/lib/ppl/cli.rb DELETED
@@ -1,49 +0,0 @@
1
-
2
- require "ppl"
3
- require "optparse"
4
-
5
- class Ppl::CLI
6
-
7
- def initialize
8
- @address_book = Ppl::Address_Book.new("/home/h2s/doc/contacts")
9
- @commands = commands
10
-
11
- find_command("help").commands = @commands
12
- end
13
-
14
- def run(argv)
15
- command_name = argv.shift
16
- command = find_command command_name
17
-
18
- if command.nil?
19
- command = find_command "help"
20
- end
21
-
22
- command.run argv
23
- end
24
-
25
-
26
- private
27
-
28
- def commands
29
- @commands = []
30
- Ppl::Command.constants.each do |name|
31
- constant = Ppl::Command.const_get(name)
32
- @commands.push constant.new
33
- end
34
- @commands.sort! { |a,b| a.name <=> b.name }
35
-
36
- @commands.each do |command|
37
- command.address_book = @address_book
38
- command.commands = @commands
39
- end
40
- end
41
-
42
- def find_command(name)
43
- matches = @commands.select { |command| command.name == name }
44
- matches.first
45
- end
46
-
47
-
48
- end
49
-
@@ -1,40 +0,0 @@
1
-
2
- class Ppl::Command::Add < Ppl::Command
3
-
4
- def name
5
- "add"
6
- end
7
-
8
- def summary
9
- "Add a new contact"
10
- end
11
-
12
- def banner
13
- "Usage: ppl add <contact> <name>"
14
- end
15
-
16
- def options(parser)
17
- end
18
-
19
- def execute(argv, options)
20
-
21
- contact_id = argv.shift
22
- name = argv.shift
23
-
24
- if contact_id.nil? || name.nil?
25
- $stderr.puts @option_parser
26
- return false
27
- end
28
-
29
- contact = @address_book.contact contact_id
30
- if !contact.nil?
31
- raise "contact '#{contact_id}' already exists"
32
- end
33
-
34
- contact = @address_book.create_contact contact_id, name
35
- puts contact
36
-
37
- end
38
-
39
- end
40
-
@@ -1,34 +0,0 @@
1
-
2
- class Ppl::Command::Birthdays < Ppl::Command
3
-
4
- def name
5
- "birthdays"
6
- end
7
-
8
- def summary
9
- "Show a list of upcoming birthdays"
10
- end
11
-
12
- def banner
13
- "Usage: ppl birthdays"
14
- end
15
-
16
- def options(parser)
17
- end
18
-
19
- def execute(argv, options)
20
- today = Date.today
21
-
22
- @address_book.with_birthday.each do |contact|
23
- puts(
24
- sprintf("%-20s", contact.id) +
25
- sprintf("%-20s", contact.name) +
26
- sprintf("%-20s", contact.birthday) +
27
- sprintf("%d days", contact.until_birthday(today))
28
- )
29
- end
30
-
31
- end
32
-
33
- end
34
-
@@ -1,32 +0,0 @@
1
-
2
- class Ppl::Command::Help < Ppl::Command
3
-
4
- def name
5
- "help"
6
- end
7
-
8
- def summary
9
- "Show a list of available commands"
10
- end
11
-
12
- def banner
13
- "Usage: ppl <command> [options]"
14
- end
15
-
16
- def options(parser)
17
- end
18
-
19
- def execute(argv, options)
20
- puts @option_parser
21
- puts
22
- @commands.each do |command|
23
- puts(
24
- sprintf(" %-10s", command.name) +
25
- sprintf("%s", command.summary)
26
- )
27
- end
28
- puts
29
- end
30
-
31
- end
32
-
@@ -1,31 +0,0 @@
1
-
2
- class Ppl::Command::List < Ppl::Command
3
-
4
- def name
5
- "list"
6
- end
7
-
8
- def summary
9
- "Show a list of all contacts"
10
- end
11
-
12
- def banner
13
- "Usage: ppl list"
14
- end
15
-
16
- def options(parser)
17
- end
18
-
19
- def execute(argv, options)
20
- @address_book.each do |contact|
21
- puts(
22
- sprintf("%-10s", contact.id + ":") +
23
- sprintf("%s ", contact.name) +
24
- sprintf("%-20s", "<" + contact.email + ">")
25
- )
26
- end
27
- return true
28
- end
29
-
30
- end
31
-
@@ -1,38 +0,0 @@
1
-
2
- class Ppl::Command::Rm < Ppl::Command
3
-
4
- def name
5
- "rm"
6
- end
7
-
8
- def summary
9
- "Delete a contact"
10
- end
11
-
12
- def banner
13
- "Usage: ppl rm <contact>"
14
- end
15
-
16
- def options(parser)
17
- end
18
-
19
- def execute(argv, options)
20
-
21
- contact_id = argv.first
22
-
23
- if contact_id.nil?
24
- $stderr.puts @option_parser
25
- return false
26
- end
27
-
28
- contact = @address_book.contact contact_id
29
- if contact.nil?
30
- raise "contact '#{contact_id}' not found"
31
- end
32
-
33
- @address_book.delete_contact contact_id
34
-
35
- end
36
-
37
- end
38
-