org_mode 0.0.1
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 +7 -0
- data/Gemfile +26 -0
- data/README.mkd +30 -0
- data/Rakefile +1 -0
- data/bin/org-mode +32 -0
- data/features/cmdline_agenda.feature +34 -0
- data/features/cmdline_handles_errors_cracefully.feature +10 -0
- data/features/cmdline_noparams.feature +11 -0
- data/features/cmdline_todos.feature +5 -0
- data/features/steps.rb +35 -0
- data/features/support/env.rb +0 -0
- data/features/support/org_mode_script.rb +53 -0
- data/lib/core_ext/string.rb +5 -0
- data/lib/org_mode/commands/agenda.rb +39 -0
- data/lib/org_mode/commands/update.rb +4 -0
- data/lib/org_mode/commands.rb +7 -0
- data/lib/org_mode/loader.rb +17 -0
- data/lib/org_mode/parser.rb +137 -0
- data/lib/org_mode/reporters/agenda.rb +44 -0
- data/lib/org_mode/version.rb +3 -0
- data/lib/org_mode.rb +87 -0
- data/org_mode.gemspec +28 -0
- data/spec/data/org-file-01-simple-node-structure.org +12 -0
- data/spec/lib/org_mode/commands/agenda_spec.rb +55 -0
- data/spec/lib/org_mode/parser_spec.rb +323 -0
- data/spec/lib/org_mode/reporters/agenda_spec.rb +74 -0
- data/spec/lib/org_mode_spec.rb +52 -0
- data/spec/support/blueprints.rb +27 -0
- data/spec/support/capture_stdout.rb +12 -0
- data/spec/support/include_hash.rb +7 -0
- data/spec/support/write_into_tempfile.rb +6 -0
- metadata +166 -0
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'org_mode/commands/agenda'
|
2
|
+
require 'tempfile'
|
3
|
+
require 'core_ext/string'
|
4
|
+
require 'support/capture_stdout'
|
5
|
+
require 'support/write_into_tempfile'
|
6
|
+
require 'timecop'
|
7
|
+
|
8
|
+
# Helper to execute agenda and compare the output
|
9
|
+
def execute_and_compare_stdout_with args, options, expected_output
|
10
|
+
output = capture_stdout do
|
11
|
+
@org_mode_commands_agenda.execute(args, options)
|
12
|
+
end
|
13
|
+
output.should == expected_output
|
14
|
+
end
|
15
|
+
|
16
|
+
describe OrgMode::Commands::Agenda do
|
17
|
+
before do
|
18
|
+
Timecop.freeze('2012-01-01 15:00')
|
19
|
+
|
20
|
+
@org_mode_commands_agenda = OrgMode::Commands::Agenda.new
|
21
|
+
end
|
22
|
+
|
23
|
+
context '#execute' do
|
24
|
+
context 'when loaded with one file' do
|
25
|
+
it 'extracts and displays scheduled tasks correctly' do
|
26
|
+
org_file = write_into_tempfile <<-eos.strip_indent(10)
|
27
|
+
* TODO Scheduled task <1-1-2012 Wed 15:15>
|
28
|
+
eos
|
29
|
+
execute_and_compare_stdout_with [org_file.path], stub, <<-eos.strip_indent(10)
|
30
|
+
Agenda ()
|
31
|
+
2012-01-01
|
32
|
+
TODO Scheduled task
|
33
|
+
eos
|
34
|
+
end
|
35
|
+
end
|
36
|
+
context 'when loaded with two files' do
|
37
|
+
it 'displays both in expected format and sorted correctly' do
|
38
|
+
org_file = write_into_tempfile <<-eos.strip_indent(10)
|
39
|
+
* TODO Scheduled task on the 5th <5-1-2012 Wed 15:15>
|
40
|
+
eos
|
41
|
+
org_file2 = write_into_tempfile <<-eos.strip_indent(10)
|
42
|
+
* TODO Scheduled task on the 1th <1-1-2012 Wed 15:15>
|
43
|
+
eos
|
44
|
+
execute_and_compare_stdout_with [org_file, org_file2].map(&:path), stub,
|
45
|
+
<<-eos.strip_indent(10)
|
46
|
+
Agenda ()
|
47
|
+
2012-01-01
|
48
|
+
TODO Scheduled task on the 1th
|
49
|
+
2012-01-05
|
50
|
+
TODO Scheduled task on the 5th
|
51
|
+
eos
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
@@ -0,0 +1,323 @@
|
|
1
|
+
require 'org_mode'
|
2
|
+
require 'org_mode/parser'
|
3
|
+
|
4
|
+
# Parser
|
5
|
+
# ------
|
6
|
+
#
|
7
|
+
# Two way parser:
|
8
|
+
# First pass
|
9
|
+
# Find file settings
|
10
|
+
# Find all nodes
|
11
|
+
# Title and content tree structure
|
12
|
+
# Second pass
|
13
|
+
# Parse all nodes
|
14
|
+
# (using information from file, ak TODO keywords)
|
15
|
+
# Parse title
|
16
|
+
# Parse content
|
17
|
+
#
|
18
|
+
# Node
|
19
|
+
# Title
|
20
|
+
# TodoStateKeyword
|
21
|
+
# Date
|
22
|
+
# Content
|
23
|
+
# CodeBlockParser
|
24
|
+
# PlainTextParser
|
25
|
+
#
|
26
|
+
# Nodes
|
27
|
+
# SettingsNode
|
28
|
+
# settings_hash
|
29
|
+
# SettingsAttachment
|
30
|
+
# PlainTextNode
|
31
|
+
# content
|
32
|
+
# CodeBlockNode
|
33
|
+
# language
|
34
|
+
# content
|
35
|
+
|
36
|
+
|
37
|
+
# Private: Loads org example
|
38
|
+
#
|
39
|
+
# name - takes part of filename
|
40
|
+
#
|
41
|
+
# Returns the contents of the file
|
42
|
+
def load_org_example name
|
43
|
+
File.open("spec/data/org-file-#{name}.org").read
|
44
|
+
end
|
45
|
+
|
46
|
+
describe OrgMode::FileParser do
|
47
|
+
context ".parse_into_tokens" do
|
48
|
+
it "should pars only one" do
|
49
|
+
org_data = <<-org.gsub(/^\s{8}/,'')
|
50
|
+
* First
|
51
|
+
org
|
52
|
+
b,n,e = OrgMode::FileParser.parse_into_tokens(org_data)
|
53
|
+
b.should be_empty
|
54
|
+
n.should == [["* First", ""]]
|
55
|
+
e.should be_empty
|
56
|
+
end
|
57
|
+
it "should pars only one without enter" do
|
58
|
+
org_data = "* First"
|
59
|
+
b,n,e = OrgMode::FileParser.parse_into_tokens(org_data)
|
60
|
+
b.should be_empty
|
61
|
+
n.should == [["* First", ""]]
|
62
|
+
e.should be_empty
|
63
|
+
end
|
64
|
+
it "should divide data up correctly" do
|
65
|
+
org_data = <<-org.gsub(/^\s{8}/,'')
|
66
|
+
* First
|
67
|
+
** Second
|
68
|
+
org
|
69
|
+
b,n,e = OrgMode::FileParser.parse_into_tokens(org_data)
|
70
|
+
b.should be_empty
|
71
|
+
n.should == [["* First", ""], ["** Second", ""]]
|
72
|
+
e.should be_empty
|
73
|
+
end
|
74
|
+
it "should handle nodes with content" do
|
75
|
+
org_data = <<-org.gsub(/^\s{8}/,'')
|
76
|
+
* First
|
77
|
+
Content for first node
|
78
|
+
** Second
|
79
|
+
Content for nested node
|
80
|
+
org
|
81
|
+
b,n,e = OrgMode::FileParser.parse_into_tokens(org_data)
|
82
|
+
b.should be_empty
|
83
|
+
n.should == [["* First", " Content for first node"], ["** Second", " Content for nested node"]]
|
84
|
+
e.should be_empty
|
85
|
+
end
|
86
|
+
it "should handle content with no nodes" do
|
87
|
+
org_data = <<-org.gsub(/^\s{8}/,'')
|
88
|
+
Just some textfile without any nodes
|
89
|
+
org
|
90
|
+
b,n,e = OrgMode::FileParser.parse_into_tokens(org_data)
|
91
|
+
b.should == 'Just some textfile without any nodes'
|
92
|
+
n.should == []
|
93
|
+
e.should be_empty
|
94
|
+
end
|
95
|
+
it "should take an empty string" do
|
96
|
+
org_data = <<-org.gsub(/^\s{8}/,'')
|
97
|
+
org
|
98
|
+
b,n,e = OrgMode::FileParser.parse_into_tokens(org_data)
|
99
|
+
b.should be_empty
|
100
|
+
n.should == []
|
101
|
+
e.should be_empty
|
102
|
+
end
|
103
|
+
end
|
104
|
+
|
105
|
+
context ".parse" do
|
106
|
+
let(:org_data) { load_org_example '01-simple-node-structure' }
|
107
|
+
it "should just parse the file" do
|
108
|
+
parsed = OrgMode::FileParser.parse(org_data)
|
109
|
+
end
|
110
|
+
context 'with a parsed org_file' do
|
111
|
+
let(:org_file) { OrgMode::FileParser.parse(org_data) }
|
112
|
+
|
113
|
+
it "should return an OrgMode::File" do
|
114
|
+
org_file.should be_an_instance_of( OrgMode::File )
|
115
|
+
end
|
116
|
+
|
117
|
+
it "parses the tree correctly" do
|
118
|
+
org_file.nodes.length.should == 12
|
119
|
+
end
|
120
|
+
|
121
|
+
it "has an empty beginning" do
|
122
|
+
org_file.header.should be_empty
|
123
|
+
end
|
124
|
+
it "has an empty ending" do
|
125
|
+
org_file.footer.should be_empty
|
126
|
+
end
|
127
|
+
context 'parent_child relations' do
|
128
|
+
it "root node has no parent" do
|
129
|
+
org_file.nodes[0].parent.should be_nil
|
130
|
+
end
|
131
|
+
it "root node has 2 children" do
|
132
|
+
org_file.nodes[0].children.length.should == 2
|
133
|
+
org_file.nodes[0].children[0].title.should == 'FirstChildMain'
|
134
|
+
org_file.nodes[0].children[1].title.should == 'SecondChildMain'
|
135
|
+
end
|
136
|
+
it "ThirdMain should be in business" do
|
137
|
+
org_file.nodes[8].children[0].children[0].children[0].title.should ==
|
138
|
+
'FirstChildFirstChildFirstChildMain'
|
139
|
+
end
|
140
|
+
it "destilled the correct root nodes" do
|
141
|
+
org_file.root_nodes.map(&:title).should == %w[Main SecondMain ThirdMain]
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe OrgMode::NodeParser do
|
149
|
+
context ".parse" do
|
150
|
+
context "title" do
|
151
|
+
context "standard node title" do
|
152
|
+
let(:node) {OrgMode::NodeParser.parse('** Standard node title', nil)}
|
153
|
+
it "parses the title correctly" do
|
154
|
+
node.title.should == 'Standard node title'
|
155
|
+
end
|
156
|
+
it "determines the correct stars" do
|
157
|
+
node.stars.should == 2
|
158
|
+
end
|
159
|
+
it "determines the correct indent" do
|
160
|
+
node.indent.should == 3
|
161
|
+
end
|
162
|
+
end
|
163
|
+
context "level deeper node title" do
|
164
|
+
let(:node) {OrgMode::NodeParser.parse('*** Standard node title one level deeper', nil)}
|
165
|
+
it "parses the title correctly" do
|
166
|
+
node.title.should == 'Standard node title one level deeper'
|
167
|
+
end
|
168
|
+
it "determines the correct stars" do
|
169
|
+
node.stars.should == 3
|
170
|
+
end
|
171
|
+
it "determines the correct indent" do
|
172
|
+
node.indent.should == 4
|
173
|
+
end
|
174
|
+
end
|
175
|
+
context "node title with date" do
|
176
|
+
let(:node) {OrgMode::NodeParser.parse('** Date node title <2012-02-02 Wed>', nil) }
|
177
|
+
it "parses the date from the title correcty" do
|
178
|
+
node.date.strftime('%Y-%m-%d').should == '2012-02-02'
|
179
|
+
end
|
180
|
+
end
|
181
|
+
context "node title with date time" do
|
182
|
+
let(:node) {OrgMode::NodeParser.parse('** Date node title <2012-02-03 Wed 15:15>', nil)}
|
183
|
+
it "parses the date-time from the title correcty" do
|
184
|
+
node.date.strftime('%Y-%m-%d %H:%M').should == '2012-02-03 15:15'
|
185
|
+
end
|
186
|
+
end
|
187
|
+
context "node title with date-range" do
|
188
|
+
let(:node) {OrgMode::NodeParser.parse('** Date node title <2012-02-03 Wed 15:15-16:15>', nil)}
|
189
|
+
it "parses the date from the title correcty" do
|
190
|
+
node.date.strftime('%Y-%m-%d %H:%M').should == '2012-02-03 15:15'
|
191
|
+
end
|
192
|
+
it "parses the start_tiem correctly" do
|
193
|
+
node.date_start_time.strftime('%Y-%m-%d %H:%M').should == '2012-02-03 15:15'
|
194
|
+
end
|
195
|
+
it "parses the end_time correctly" do
|
196
|
+
node.date_end_time.strftime('%Y-%m-%d %H:%M').should == '2012-02-03 16:15'
|
197
|
+
end
|
198
|
+
end
|
199
|
+
context "parses TODO states correctly" do
|
200
|
+
let(:node) {OrgMode::NodeParser.parse('** TODO Date node title', nil)}
|
201
|
+
it "parses the TODO keyword correctly" do
|
202
|
+
node.todo_state.should == 'TODO'
|
203
|
+
end
|
204
|
+
context "parses DONE state correctly" do
|
205
|
+
let(:node) {OrgMode::NodeParser.parse('** DONE Date node title', nil)}
|
206
|
+
it "parses the TODO keyword correctly" do
|
207
|
+
node.todo_state.should == 'DONE'
|
208
|
+
end
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
context "content indentation" do
|
213
|
+
context "correctly indented" do
|
214
|
+
before do
|
215
|
+
org_title, *org_content = <<-eos.gsub(/^\s{10}/,'').lines.to_a
|
216
|
+
*** Title
|
217
|
+
Content belonging
|
218
|
+
at a certain indent
|
219
|
+
should be parsed correctly
|
220
|
+
eos
|
221
|
+
@node = OrgMode::NodeParser.parse(org_title, org_content.join)
|
222
|
+
end
|
223
|
+
it "parses content and removes indent" do
|
224
|
+
@node.content.should == <<-eos.gsub(/^\s{10}/,'')
|
225
|
+
Content belonging
|
226
|
+
at a certain indent
|
227
|
+
should be parsed correctly
|
228
|
+
eos
|
229
|
+
end
|
230
|
+
end
|
231
|
+
context "too far" do
|
232
|
+
before do
|
233
|
+
org_title, *org_content = <<-eos.gsub(/^\s{10}/,'').lines.to_a
|
234
|
+
*** Title
|
235
|
+
Content belonging
|
236
|
+
at a certain indent
|
237
|
+
should be parsed correctly
|
238
|
+
eos
|
239
|
+
@node = OrgMode::NodeParser.parse(org_title, org_content.join)
|
240
|
+
end
|
241
|
+
it "parses content and removes indent" do
|
242
|
+
@node.content.should == <<-eos.gsub(/^\s{10}/,'')
|
243
|
+
Content belonging
|
244
|
+
at a certain indent
|
245
|
+
should be parsed correctly
|
246
|
+
eos
|
247
|
+
end
|
248
|
+
end
|
249
|
+
context "indented in content block" do
|
250
|
+
before do
|
251
|
+
org_title, *org_content = <<-eos.gsub(/^\s{10}/,'').lines.to_a
|
252
|
+
*** Title
|
253
|
+
Content belonging
|
254
|
+
at a certain indent
|
255
|
+
should be parsed correctly
|
256
|
+
eos
|
257
|
+
@node = OrgMode::NodeParser.parse(org_title, org_content.join)
|
258
|
+
end
|
259
|
+
it "parses content and removes indent" do
|
260
|
+
@node.content.should == <<-eos.gsub(/^\s{10}/,'')
|
261
|
+
Content belonging
|
262
|
+
at a certain indent
|
263
|
+
should be parsed correctly
|
264
|
+
eos
|
265
|
+
end
|
266
|
+
end
|
267
|
+
context "one row outdented" do
|
268
|
+
before do
|
269
|
+
org_title, *org_content = <<-eos.gsub(/^\s{10}/,'').lines.to_a
|
270
|
+
*** Title
|
271
|
+
Content belonging
|
272
|
+
at a certain indent
|
273
|
+
should be parsed correctly
|
274
|
+
eos
|
275
|
+
@node = OrgMode::NodeParser.parse(org_title, org_content.join)
|
276
|
+
end
|
277
|
+
it "parses content and removes indent" do
|
278
|
+
@node.content.should == <<-eos.gsub(/^\s{10}/,'')
|
279
|
+
Content belonging
|
280
|
+
at a certain indent
|
281
|
+
should be parsed correctly
|
282
|
+
eos
|
283
|
+
end
|
284
|
+
end
|
285
|
+
end
|
286
|
+
context "content whitespace" do
|
287
|
+
it "removes whitespace at beginning" do
|
288
|
+
org_title, *org_content = <<-eos.gsub(/^\s{8}/,'').lines.to_a
|
289
|
+
*** Title
|
290
|
+
|
291
|
+
|
292
|
+
|
293
|
+
Content belonging
|
294
|
+
at a certain indent
|
295
|
+
should be parsed correctly
|
296
|
+
eos
|
297
|
+
@node = OrgMode::NodeParser.parse(org_title, org_content.join)
|
298
|
+
@node.content.should == <<-eos.gsub(/^\s{8}/,'')
|
299
|
+
Content belonging
|
300
|
+
at a certain indent
|
301
|
+
should be parsed correctly
|
302
|
+
eos
|
303
|
+
end
|
304
|
+
it "removes whitespace at ending" do
|
305
|
+
org_title, *org_content = <<-eos.gsub(/^\s{8}/,'').lines.to_a
|
306
|
+
*** Title
|
307
|
+
Content belonging
|
308
|
+
at a certain indent
|
309
|
+
should be parsed correctly
|
310
|
+
|
311
|
+
|
312
|
+
|
313
|
+
eos
|
314
|
+
@node = OrgMode::NodeParser.parse(org_title, org_content.join)
|
315
|
+
@node.content.should == <<-eos.gsub(/^\s{8}/,'')
|
316
|
+
Content belonging
|
317
|
+
at a certain indent
|
318
|
+
should be parsed correctly
|
319
|
+
eos
|
320
|
+
end
|
321
|
+
end
|
322
|
+
end
|
323
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'org_mode/reporters/agenda'
|
2
|
+
require 'support/blueprints'
|
3
|
+
require 'support/include_hash'
|
4
|
+
require 'timecop'
|
5
|
+
|
6
|
+
describe OrgMode::Reporters::Agenda do
|
7
|
+
before do
|
8
|
+
Timecop.freeze('2012-02-02')
|
9
|
+
end
|
10
|
+
let(:file_collection) do
|
11
|
+
nodes = []
|
12
|
+
files = []
|
13
|
+
nodes << OrgMode::Node.make(:stars => 1, :date=>Date.parse('2012-02-01'))
|
14
|
+
nodes << OrgMode::Node.make(:stars => 2, :date=>Date.parse('2012-02-05'))
|
15
|
+
files << OrgMode::File.make(:nodes => nodes)
|
16
|
+
nodes = []
|
17
|
+
nodes << OrgMode::Node.make(:stars => 1,
|
18
|
+
:todo_state => 'DONE',
|
19
|
+
:date => Date.parse('2012-06-01'))
|
20
|
+
nodes << OrgMode::Node.make(:stars => 2, :date=>Date.parse('2012-02-03'))
|
21
|
+
nodes << OrgMode::Node.make(:stars => 3, :date=>DateTime.parse('2012-02-01 15:00'))
|
22
|
+
files << OrgMode::File.make(:nodes => nodes)
|
23
|
+
OrgMode::FileCollection.make(:files => files)
|
24
|
+
end
|
25
|
+
let(:reporter) { OrgMode::Reporters::Agenda.new(file_collection) }
|
26
|
+
|
27
|
+
context '#open_nodes_grouped_by_day' do
|
28
|
+
|
29
|
+
let (:reported) { reporter.open_nodes_grouped_by_day }
|
30
|
+
|
31
|
+
it "extracts the correct dates and in the correct order" do
|
32
|
+
dates = reported.map {|e| e[:date] }
|
33
|
+
dates.should == ["2012-02-01", "2012-02-03", "2012-02-05"]
|
34
|
+
end
|
35
|
+
it "should group the nodecounts correctly" do
|
36
|
+
nodecount_per_date = reported.map { |e| [e[:date], e[:nodes].length] }
|
37
|
+
nodecount_per_date.should == [["2012-02-01", 2], ["2012-02-03", 1], ["2012-02-05", 1]]
|
38
|
+
end
|
39
|
+
it "should result in the following subhashes" do
|
40
|
+
reported.should ==
|
41
|
+
[{:date=>"2012-02-01",
|
42
|
+
:nodes=>
|
43
|
+
[{:title=>"org-node",
|
44
|
+
:content=>"org-node content",
|
45
|
+
:todo_state=>"TODO",
|
46
|
+
:date=>"2012-02-01 00:00",
|
47
|
+
:stars=>1},
|
48
|
+
{:title=>"org-node",
|
49
|
+
:content=>"org-node content",
|
50
|
+
:todo_state=>"TODO",
|
51
|
+
:date=>"2012-02-01 15:00",
|
52
|
+
:stars=>3}]},
|
53
|
+
{:date=>"2012-02-03",
|
54
|
+
:nodes=>
|
55
|
+
[{:title=>"org-node",
|
56
|
+
:content=>"org-node content",
|
57
|
+
:todo_state=>"TODO",
|
58
|
+
:date=>"2012-02-03 00:00",
|
59
|
+
:stars=>2}]},
|
60
|
+
{:date=>"2012-02-05",
|
61
|
+
:nodes=>
|
62
|
+
[{:title=>"org-node",
|
63
|
+
:content=>"org-node content",
|
64
|
+
:todo_state=>"TODO",
|
65
|
+
:date=>"2012-02-05 00:00",
|
66
|
+
:stars=>2}]}]
|
67
|
+
end
|
68
|
+
it "it ignores the DONE task" do
|
69
|
+
dates = reported.map {|e| e[:date] }
|
70
|
+
dates.should_not include("2012-06-01")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'org_mode'
|
2
|
+
require 'support/blueprints'
|
3
|
+
|
4
|
+
describe OrgMode::File do
|
5
|
+
let(:file) do
|
6
|
+
nodes = []
|
7
|
+
files = []
|
8
|
+
nodes << OrgMode::Node.make(:stars => 1)
|
9
|
+
nodes << OrgMode::Node.make(:stars => 2, :date=>Time.now)
|
10
|
+
nodes << OrgMode::Node.make(:stars => 3)
|
11
|
+
nodes << OrgMode::Node.make(:stars => 1)
|
12
|
+
OrgMode::File.make(:nodes => nodes)
|
13
|
+
end
|
14
|
+
|
15
|
+
it "accumulates correctly" do
|
16
|
+
file.nodes.length.should == 4
|
17
|
+
end
|
18
|
+
|
19
|
+
it "detects all rootnodes correctly" do
|
20
|
+
file.root_nodes.length.should == 2
|
21
|
+
end
|
22
|
+
|
23
|
+
it "detects all scheduled nodes correctly" do
|
24
|
+
file.scheduled_nodes.length.should == 1
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
describe OrgMode::FileCollection do
|
29
|
+
let(:file_collection) do
|
30
|
+
nodes = []
|
31
|
+
files = []
|
32
|
+
nodes << OrgMode::Node.make(:stars => 1)
|
33
|
+
nodes << OrgMode::Node.make(:stars => 2)
|
34
|
+
files << OrgMode::File.make(:nodes => nodes)
|
35
|
+
nodes = []
|
36
|
+
nodes << OrgMode::Node.make(:stars => 1)
|
37
|
+
nodes << OrgMode::Node.make(:stars => 2, :date=>Time.now)
|
38
|
+
nodes << OrgMode::Node.make(:stars => 3)
|
39
|
+
files << OrgMode::File.make(:nodes => nodes)
|
40
|
+
OrgMode::FileCollection.make(:files => files)
|
41
|
+
end
|
42
|
+
it "accumulates correctly" do
|
43
|
+
file_collection.nodes.length.should == 5
|
44
|
+
end
|
45
|
+
|
46
|
+
it "detects all rootnodes correctly" do
|
47
|
+
file_collection.root_nodes.length.should == 2
|
48
|
+
end
|
49
|
+
it "detects all scheduled nodes correctly" do
|
50
|
+
file_collection.scheduled_nodes.length.should == 1
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'org_mode'
|
2
|
+
|
3
|
+
class OrgMode::Node
|
4
|
+
def self.make(attrs={})
|
5
|
+
self.new.tap do |n|
|
6
|
+
n.title = attrs[:title] || "org-node"
|
7
|
+
n.stars = attrs[:stars] || rand(4)
|
8
|
+
n.content = attrs[:content] || "org-node content"
|
9
|
+
n.date = attrs[:date]
|
10
|
+
n.todo_state = attrs[:todo_state] || 'TODO'
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
class OrgMode::File
|
16
|
+
def self.make(attrs={})
|
17
|
+
nodes = attrs[:nodes] || Array.new(2) { OrgMode::Node.make }
|
18
|
+
self.new("aheader", nodes , "afooter")
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class OrgMode::FileCollection
|
23
|
+
def self.make(attrs={})
|
24
|
+
files = attrs[:files] || Array.new(2) { OrgMode::File.make }
|
25
|
+
self.new( files )
|
26
|
+
end
|
27
|
+
end
|