things-rb 0.3.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.
- data/.gitignore +4 -0
- data/CHANGELOG +8 -0
- data/LICENSE +19 -0
- data/README.markdown +110 -0
- data/Rakefile +26 -0
- data/VERSION +1 -0
- data/bin/things +52 -0
- data/lib/things/document.rb +39 -0
- data/lib/things/focus.rb +63 -0
- data/lib/things/task.rb +162 -0
- data/lib/things/version.rb +9 -0
- data/lib/things.rb +34 -0
- data/test/fixtures/Database.xml +1343 -0
- data/test/test_document.rb +59 -0
- data/test/test_focus.rb +96 -0
- data/test/test_helper.rb +26 -0
- data/test/test_task.rb +163 -0
- data/things-rb.gemspec +66 -0
- metadata +85 -0
@@ -0,0 +1,59 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class DocumentTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@things = @@things ||= Things.new(:database => DATABASE_FIXTURE_PATH)
|
6
|
+
end
|
7
|
+
|
8
|
+
test "should use the specified database if any" do
|
9
|
+
IO.expects(:read).with('/path/to/database.xml').returns("foo").at_least_once
|
10
|
+
things = Things.new(:database => '/path/to/database.xml')
|
11
|
+
assert_equal('/path/to/database.xml', things.database_file)
|
12
|
+
end
|
13
|
+
|
14
|
+
test "should use default database unless other is specified" do
|
15
|
+
default_db = ENV['HOME'] + '/Library/Application Support/Cultured Code/Things/Database.xml'
|
16
|
+
IO.expects(:read).with(default_db).returns("foo").at_least_once
|
17
|
+
assert_equal(default_db, Things.new.database_file)
|
18
|
+
end
|
19
|
+
|
20
|
+
test "should return a parsed Hpricot document" do
|
21
|
+
IO.expects(:read).with('/my/db.xml').returns("foo").at_least_once
|
22
|
+
things = Things.new(:database => '/my/db.xml')
|
23
|
+
assert_equal("Hpricot::Doc", things.database.class.to_s)
|
24
|
+
assert_equal "foo", things.database.to_s
|
25
|
+
end
|
26
|
+
|
27
|
+
[:today, :inbox, :trash, :logbook, :next, :scheduled].each do |type|
|
28
|
+
test "should create a Focus instance for type #{type}" do
|
29
|
+
focus = @things.focus(type)
|
30
|
+
assert_instance_of(Things::Focus, focus)
|
31
|
+
end
|
32
|
+
|
33
|
+
test "should only create one Focus instance for #{type}" do
|
34
|
+
focus = @things.focus(type)
|
35
|
+
2.times { |i| assert_equal(focus, @things.focus(type)) }
|
36
|
+
end
|
37
|
+
|
38
|
+
test %Q{should have a shortcuts to the Focus "#{type}"} do
|
39
|
+
Things::Focus.any_instance.stubs(:tasks).returns(%[foo bar baz])
|
40
|
+
assert_equal(@things.focus(type).tasks, @things.send(type))
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
test %Q{Should allow to send options to the focus today} do
|
45
|
+
completed = @things.today(:completed => true )
|
46
|
+
assert completed.all? { |e| e.title.include?("complete") }
|
47
|
+
end
|
48
|
+
|
49
|
+
[Things, Things::Document].each do |klass|
|
50
|
+
test "should allow a block for #{klass}.new" do
|
51
|
+
block = false
|
52
|
+
klass.new(:database => DATABASE_FIXTURE_PATH) do |d|
|
53
|
+
block = true
|
54
|
+
assert_instance_of(Things::Document, d)
|
55
|
+
end
|
56
|
+
assert(block)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
data/test/test_focus.rb
ADDED
@@ -0,0 +1,96 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class FocusTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@things = @@things ||= Things.new(:database => DATABASE_FIXTURE_PATH)
|
6
|
+
@todays_tasks = [
|
7
|
+
"complete today item",
|
8
|
+
"today item with notes",
|
9
|
+
"complete today item with notes",
|
10
|
+
"complete today item with a tag",
|
11
|
+
"today item with multiple tags",
|
12
|
+
"email bar",
|
13
|
+
"today item",
|
14
|
+
"today item with content (notes)"
|
15
|
+
]
|
16
|
+
end
|
17
|
+
|
18
|
+
test 'should find the Today focus' do
|
19
|
+
assert_equal("z124", @things.focus(:today).id)
|
20
|
+
end
|
21
|
+
|
22
|
+
test "should find the focustype for Today" do
|
23
|
+
assert_equal("65536", @things.focus(:today).type_id)
|
24
|
+
end
|
25
|
+
|
26
|
+
test "should find the focuses" do
|
27
|
+
{ :inbox => "z120",
|
28
|
+
:trash => "z138",
|
29
|
+
:logbook => "z127",
|
30
|
+
:nextactions => "z141"
|
31
|
+
}.each do |name, id|
|
32
|
+
assert_equal(id, @things.focus(name).id)
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
test 'should allow "next" as alias for NextActions focus' do
|
37
|
+
focus = Things::Focus.new(:next, stub(:at => ''))
|
38
|
+
assert_equal "FocusNextActions", focus.type_name
|
39
|
+
end
|
40
|
+
|
41
|
+
test 'should allow "nextactions" as alias for NextActions focus' do
|
42
|
+
focus = Things::Focus.new(:nextactions, stub(:at => ''))
|
43
|
+
assert_equal "FocusNextActions", focus.type_name
|
44
|
+
end
|
45
|
+
|
46
|
+
test 'should allow "someday" as alias for Maybe focus' do
|
47
|
+
focus = Things::Focus.new(:someday, stub(:at => ''))
|
48
|
+
assert_equal "FocusMaybe", focus.type_name
|
49
|
+
end
|
50
|
+
|
51
|
+
test "should raise FocusNotFound if the focus isn't found" do
|
52
|
+
assert_raise(Things::InvalidFocus) { @things.focus(:invalid_focus) }
|
53
|
+
end
|
54
|
+
|
55
|
+
test "should find the same number of tasks as in Today" do
|
56
|
+
tasks = @things.focus(:today).tasks
|
57
|
+
assert_instance_of(Array, tasks)
|
58
|
+
assert_equal(8, tasks.length)
|
59
|
+
end
|
60
|
+
|
61
|
+
test "should find the tasks' titles" do
|
62
|
+
assert_equal(@todays_tasks.sort, @things.today.map(&:title).sort)
|
63
|
+
end
|
64
|
+
|
65
|
+
test "should sort the tasks by their position" do
|
66
|
+
# TODO: tasks with projects/parent have other sorting order but need to
|
67
|
+
# figure out how Things handles that. Therefore skip these tasks for now
|
68
|
+
todays_tasks = @todays_tasks.reject { |e| e == 'email bar' }
|
69
|
+
assert_equal(todays_tasks, @things.today.reject { |e| e.parent? }.map(&:title))
|
70
|
+
end
|
71
|
+
|
72
|
+
test "should only find completed tasks when passing :completed => true" do
|
73
|
+
complete = @things.focus(:today).tasks(:completed => true)
|
74
|
+
assert complete.all? { |e| e.title.include?("complete") }
|
75
|
+
end
|
76
|
+
|
77
|
+
test "should not include completed tasks when passing :completed => false" do
|
78
|
+
complete = @things.focus(:today).tasks(:completed => false)
|
79
|
+
assert !complete.all? { |e| e.title.include?("complete") }
|
80
|
+
end
|
81
|
+
|
82
|
+
test "include canceled tasks when passing :canceled => true" do
|
83
|
+
canceled = @things.focus(:next).tasks(:canceled => true)
|
84
|
+
assert canceled.all? { |e| e.title.include?("cancel") }
|
85
|
+
end
|
86
|
+
|
87
|
+
test "dont include canceled tasks when passing :canceled => false" do
|
88
|
+
canceled = @things.focus(:next).tasks(:canceled => false)
|
89
|
+
assert !canceled.all? { |e| e.title.include?("cancel") }
|
90
|
+
end
|
91
|
+
|
92
|
+
test "should not include projects when listing tasks" do
|
93
|
+
with_children = @things.focus(:next).tasks.select(&:children?)
|
94
|
+
assert_equal 0, with_children.length
|
95
|
+
end
|
96
|
+
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
require "things"
|
2
|
+
require "test/unit"
|
3
|
+
require "mocha"
|
4
|
+
|
5
|
+
class Test::Unit::TestCase
|
6
|
+
FIXTURES_PATH = File.expand_path(File.join(File.dirname(__FILE__), "fixtures")) unless defined?(FIXTURES_PATH)
|
7
|
+
DATABASE_FIXTURE_PATH = File.join(FIXTURES_PATH, 'Database.xml') unless defined?(DATABASE_FIXTURE_PATH)
|
8
|
+
|
9
|
+
def database_content
|
10
|
+
IO.read(DATABASE_FIXTURE_PATH)
|
11
|
+
end
|
12
|
+
|
13
|
+
# From Rails ActiveSupport::Testing::Declarative
|
14
|
+
def self.test(name, &block)
|
15
|
+
test_name = "test_#{name.gsub(/\s+/,'_')}".to_sym
|
16
|
+
defined = instance_method(test_name) rescue false
|
17
|
+
raise "#{test_name} is already defined in #{self}" if defined
|
18
|
+
if block_given?
|
19
|
+
define_method(test_name, &block)
|
20
|
+
else
|
21
|
+
define_method(test_name) do
|
22
|
+
flunk "No implementation provided for #{name}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/test/test_task.rb
ADDED
@@ -0,0 +1,163 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TaskTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@things = @@things ||= Things.new(:database => DATABASE_FIXTURE_PATH)
|
6
|
+
end
|
7
|
+
|
8
|
+
def find_task(name)
|
9
|
+
title = {
|
10
|
+
:with_tags => 'today item with multiple tags',
|
11
|
+
:basic => 'today item',
|
12
|
+
:with_parent => 'email bar',
|
13
|
+
:with_notes => 'today item with content (notes)',
|
14
|
+
}[name]
|
15
|
+
@things.today.detect { |t| t.title == title }
|
16
|
+
end
|
17
|
+
|
18
|
+
def task_with_children
|
19
|
+
task_by_id("z154")
|
20
|
+
end
|
21
|
+
|
22
|
+
def task_by_id(id)
|
23
|
+
node = @things.database.at("object[@type='TODO']##{id}")
|
24
|
+
Things::Task.new(node, @things.database)
|
25
|
+
end
|
26
|
+
|
27
|
+
test "should use the task's title for to_s" do
|
28
|
+
task = find_task(:basic)
|
29
|
+
assert_equal("today item", task.to_s)
|
30
|
+
end
|
31
|
+
|
32
|
+
test "should find the task's tag ids" do
|
33
|
+
task = find_task(:with_tags)
|
34
|
+
assert_instance_of Array, task.tag_ids
|
35
|
+
assert_equal %w[z151 z150].sort, task.tag_ids.sort
|
36
|
+
end
|
37
|
+
|
38
|
+
test "should not find any tags if there isnt any" do
|
39
|
+
assert_equal 0, find_task(:basic).tag_ids.length
|
40
|
+
end
|
41
|
+
|
42
|
+
test "should find the task's notes" do
|
43
|
+
task = find_task(:with_notes)
|
44
|
+
assert_equal %{Check wait times here: http://www.mass.gov/qrmv/boston.shtm}, task.notes
|
45
|
+
end
|
46
|
+
|
47
|
+
test "should know if there are notes" do
|
48
|
+
assert find_task(:with_notes).notes?
|
49
|
+
assert !find_task(:basic).notes?
|
50
|
+
end
|
51
|
+
|
52
|
+
test "should find the task's tag titles" do
|
53
|
+
task = find_task(:with_tags)
|
54
|
+
assert_equal(%w[Home City].sort, task.tags.sort)
|
55
|
+
end
|
56
|
+
|
57
|
+
test "should know if there are any tags" do
|
58
|
+
assert(find_task(:with_tags).tags?)
|
59
|
+
assert(!find_task(:basic).tags?)
|
60
|
+
end
|
61
|
+
|
62
|
+
test "if the task has a specific tag" do
|
63
|
+
task = find_task(:with_tags)
|
64
|
+
assert(task.tag?("Home"))
|
65
|
+
assert(!task.tag?("Errand"))
|
66
|
+
end
|
67
|
+
|
68
|
+
test "should find the tasks parent_id" do
|
69
|
+
task = find_task(:with_parent)
|
70
|
+
assert_equal("z154", task.parent_id)
|
71
|
+
end
|
72
|
+
|
73
|
+
test "should not find the task's parent project if it doesn't have any" do
|
74
|
+
task = find_task(:basic)
|
75
|
+
assert_equal(nil, task.parent_id)
|
76
|
+
end
|
77
|
+
|
78
|
+
test "should find the parent's title" do
|
79
|
+
task = find_task(:with_parent)
|
80
|
+
assert_equal "Make dinner", task.parent.title
|
81
|
+
end
|
82
|
+
|
83
|
+
test "should know if there is a parent project" do
|
84
|
+
assert(find_task(:with_parent).parent?)
|
85
|
+
assert(!find_task(:basic).parent?)
|
86
|
+
end
|
87
|
+
|
88
|
+
test "should know if the task is completed" do
|
89
|
+
@things.today.each do |task|
|
90
|
+
if task.title.include?('complete')
|
91
|
+
assert(task.complete?)
|
92
|
+
assert(!task.incompleted?)
|
93
|
+
else
|
94
|
+
assert(task.incompleted?)
|
95
|
+
assert(!task.completed?)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
test "if a task is canceled" do
|
101
|
+
assert task_by_id("z189").canceled?
|
102
|
+
end
|
103
|
+
|
104
|
+
test "should find the task's order index" do
|
105
|
+
assert_equal(7, find_task(:basic).position.to_i)
|
106
|
+
end
|
107
|
+
|
108
|
+
test "list the tasks children" do
|
109
|
+
assert_instance_of(Array, task_with_children.children)
|
110
|
+
end
|
111
|
+
|
112
|
+
test "find the right number of children" do
|
113
|
+
assert_equal(9, task_with_children.children.length)
|
114
|
+
end
|
115
|
+
|
116
|
+
test "know if there are child tasks" do
|
117
|
+
assert task_with_children.children?
|
118
|
+
assert !find_task(:basic).children?
|
119
|
+
end
|
120
|
+
|
121
|
+
test "populate the children array with Task objects" do
|
122
|
+
assert task_with_children.children.all? { |c| c.class == Things::Task }
|
123
|
+
end
|
124
|
+
|
125
|
+
test "find the children_ids" do
|
126
|
+
ids = %w[z163 z161 z160 z157 z159 z156 z165 z158 z162].sort
|
127
|
+
assert_equal(ids, task_with_children.children_ids.sort)
|
128
|
+
end
|
129
|
+
|
130
|
+
test "should find the due date" do
|
131
|
+
task = task_by_id("z186")
|
132
|
+
assert_equal "2009-08-01", task.due_date.strftime("%Y-%m-%d")
|
133
|
+
end
|
134
|
+
|
135
|
+
test "should know that the task is due" do
|
136
|
+
assert task_by_id("z186").due?
|
137
|
+
end
|
138
|
+
|
139
|
+
test "should know that the task is not due" do
|
140
|
+
Time.stubs(:now).returns(Time.parse('2009-07-31'))
|
141
|
+
assert !task_by_id("z186").due?
|
142
|
+
end
|
143
|
+
|
144
|
+
test "should not be due for a task without due date" do
|
145
|
+
assert !find_task(:basic).due?
|
146
|
+
end
|
147
|
+
|
148
|
+
test "should find the schedule date" do
|
149
|
+
scheduled = task_by_id("z166")
|
150
|
+
assert_equal "2019-03-20", scheduled.scheduled_date.strftime("%Y-%m-%d")
|
151
|
+
end
|
152
|
+
|
153
|
+
test "should know if a task i scheduled" do
|
154
|
+
assert task_by_id("z166").scheduled?
|
155
|
+
assert !find_task(:basic).scheduled?
|
156
|
+
end
|
157
|
+
|
158
|
+
test "each state should have a bullet" do
|
159
|
+
assert_equal "✓", task_by_id("z173").bullet # complete
|
160
|
+
assert_equal "×", task_by_id("z189").bullet # canceled
|
161
|
+
assert_equal "-", find_task(:basic).bullet # regular
|
162
|
+
end
|
163
|
+
end
|
data/things-rb.gemspec
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = %q{things-rb}
|
8
|
+
s.version = "0.3.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Martin Str\303\266m"]
|
12
|
+
s.date = %q{2010-01-20}
|
13
|
+
s.default_executable = %q{things}
|
14
|
+
s.description = %q{Library and command-line tool for accessing Things.app databases}
|
15
|
+
s.email = %q{name@my-domain.se}
|
16
|
+
s.executables = ["things"]
|
17
|
+
s.extra_rdoc_files = [
|
18
|
+
"LICENSE",
|
19
|
+
"README.markdown"
|
20
|
+
]
|
21
|
+
s.files = [
|
22
|
+
".gitignore",
|
23
|
+
"CHANGELOG",
|
24
|
+
"LICENSE",
|
25
|
+
"README.markdown",
|
26
|
+
"Rakefile",
|
27
|
+
"VERSION",
|
28
|
+
"bin/things",
|
29
|
+
"lib/things.rb",
|
30
|
+
"lib/things/document.rb",
|
31
|
+
"lib/things/focus.rb",
|
32
|
+
"lib/things/task.rb",
|
33
|
+
"lib/things/version.rb",
|
34
|
+
"test/fixtures/Database.xml",
|
35
|
+
"test/test_document.rb",
|
36
|
+
"test/test_focus.rb",
|
37
|
+
"test/test_helper.rb",
|
38
|
+
"test/test_task.rb",
|
39
|
+
"things-rb.gemspec"
|
40
|
+
]
|
41
|
+
s.homepage = %q{http://github.com/haraldmartin/things-rb}
|
42
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
43
|
+
s.require_paths = ["lib"]
|
44
|
+
s.rubygems_version = %q{1.3.5}
|
45
|
+
s.summary = %q{Library and command-line tool for accessing Things.app databases}
|
46
|
+
s.test_files = [
|
47
|
+
"test/test_document.rb",
|
48
|
+
"test/test_focus.rb",
|
49
|
+
"test/test_helper.rb",
|
50
|
+
"test/test_task.rb"
|
51
|
+
]
|
52
|
+
|
53
|
+
if s.respond_to? :specification_version then
|
54
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
55
|
+
s.specification_version = 3
|
56
|
+
|
57
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
58
|
+
s.add_runtime_dependency(%q<hpricot>, [">= 0"])
|
59
|
+
else
|
60
|
+
s.add_dependency(%q<hpricot>, [">= 0"])
|
61
|
+
end
|
62
|
+
else
|
63
|
+
s.add_dependency(%q<hpricot>, [">= 0"])
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: things-rb
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.3.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- "Martin Str\xC3\xB6m"
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2010-01-20 00:00:00 +01:00
|
13
|
+
default_executable: things
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: hpricot
|
17
|
+
type: :runtime
|
18
|
+
version_requirement:
|
19
|
+
version_requirements: !ruby/object:Gem::Requirement
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
version:
|
25
|
+
description: Library and command-line tool for accessing Things.app databases
|
26
|
+
email: name@my-domain.se
|
27
|
+
executables:
|
28
|
+
- things
|
29
|
+
extensions: []
|
30
|
+
|
31
|
+
extra_rdoc_files:
|
32
|
+
- LICENSE
|
33
|
+
- README.markdown
|
34
|
+
files:
|
35
|
+
- .gitignore
|
36
|
+
- CHANGELOG
|
37
|
+
- LICENSE
|
38
|
+
- README.markdown
|
39
|
+
- Rakefile
|
40
|
+
- VERSION
|
41
|
+
- bin/things
|
42
|
+
- lib/things.rb
|
43
|
+
- lib/things/document.rb
|
44
|
+
- lib/things/focus.rb
|
45
|
+
- lib/things/task.rb
|
46
|
+
- lib/things/version.rb
|
47
|
+
- test/fixtures/Database.xml
|
48
|
+
- test/test_document.rb
|
49
|
+
- test/test_focus.rb
|
50
|
+
- test/test_helper.rb
|
51
|
+
- test/test_task.rb
|
52
|
+
- things-rb.gemspec
|
53
|
+
has_rdoc: true
|
54
|
+
homepage: http://github.com/haraldmartin/things-rb
|
55
|
+
licenses: []
|
56
|
+
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options:
|
59
|
+
- --charset=UTF-8
|
60
|
+
require_paths:
|
61
|
+
- lib
|
62
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "0"
|
67
|
+
version:
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
requirements:
|
70
|
+
- - ">="
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: "0"
|
73
|
+
version:
|
74
|
+
requirements: []
|
75
|
+
|
76
|
+
rubyforge_project:
|
77
|
+
rubygems_version: 1.3.5
|
78
|
+
signing_key:
|
79
|
+
specification_version: 3
|
80
|
+
summary: Library and command-line tool for accessing Things.app databases
|
81
|
+
test_files:
|
82
|
+
- test/test_document.rb
|
83
|
+
- test/test_focus.rb
|
84
|
+
- test/test_helper.rb
|
85
|
+
- test/test_task.rb
|