audrey2 0.2.1 → 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.
@@ -0,0 +1,202 @@
1
+ require 'helper'
2
+ require 'mail'
3
+
4
+ class TestEmail < Test::Unit::TestCase
5
+ context "With an initialized Aggregator all configurated with SMTP email delivery" do
6
+ setup do
7
+ @config
8
+ File.stubs(:exist?).with('configfile').returns(true)
9
+ File.stubs(:readable?).with('configfile').returns(true)
10
+ YAML.stubs(:load_file).with('configfile').returns({
11
+ 'recipes_folder' => 'recipes_folder',
12
+ 'themes_folder' => 'themes_folder',
13
+ 'user_agent' => 'user_agent',
14
+ 'sort' => 'sort',
15
+ 'email' => {'to' => 'admin@test.com',
16
+ 'from' => 'audrey2@test.com',
17
+ 'via' => 'smtp',
18
+ 'smtp' => {'address' => 'mail.test.com',
19
+ 'port' => '25',
20
+ 'domain' => 'test.com'}
21
+ }
22
+ })
23
+ File.stubs(:exist?).with('recipes_folder').returns(true)
24
+ File.stubs(:readable?).with('recipes_folder').returns(true)
25
+ File.stubs(:exist?).with('themes_folder').returns(true)
26
+ File.stubs(:readable?).with('themes_folder').returns(true)
27
+ @aggregator = Audrey2::Aggregator.new('configfile')
28
+ recipefile = File.join('recipes_folder', 'recipe')
29
+ outputfile = File.join('output_folder', 'output_file')
30
+ File.stubs(:exist?).with(recipefile).returns(true)
31
+ File.stubs(:readable?).with(recipefile).returns(true)
32
+ @feed = { 'name' => 'feed', 'url' => 'http://test.com/feed.xml' }
33
+ YAML.stubs(:load_file).with(recipefile).returns({
34
+ 'feeds' => [@feed],
35
+ 'theme' => 'theme',
36
+ 'output_file' => outputfile
37
+ })
38
+ File.stubs(:exist?).with('output_folder').returns(true)
39
+ File.stubs(:writable?).with('output_folder').returns(true)
40
+ File.stubs(:exist?).with(outputfile).returns(false)
41
+ theme_path = File.join('themes_folder', 'theme')
42
+ File.stubs(:exist?).with(theme_path).returns(true)
43
+ File.stubs(:readable?).with(theme_path).returns(true)
44
+ entry_template_path = File.join(theme_path, 'entry.haml')
45
+ File.stubs(:exist?).with(entry_template_path).returns(true)
46
+ File.stubs(:readable?).with(entry_template_path).returns(true)
47
+ File.stubs(:read).with(entry_template_path).returns('%p= entry.title')
48
+ helpers_file_path = File.join(theme_path, 'helpers.rb')
49
+ File.stubs(:exist?).with(helpers_file_path).returns(false)
50
+ @feed_content =<<-EOF
51
+ <?xml version="1.0"?>
52
+ <rss version="2.0">
53
+ <channel>
54
+ <title>Test</title>
55
+ <link>http://test.com/</link>
56
+ <description>Test channel</description>
57
+ <item>
58
+ <title>Title</title>
59
+ <link>http://test.com/title</link>
60
+ <description>Test description</description>
61
+ <pubDate>Sun, 15 Aug 2010 16:46:00 EDT</pubDate>
62
+ </item>
63
+ </channel>
64
+ </rss>
65
+ EOF
66
+ end
67
+
68
+ should 'report feed-opening error via email' do
69
+ @aggregator.expects(:open).with('http://test.com/feed.xml', {'User-Agent' => 'user_agent'}).raises(Exception.new('404 Not Found'))
70
+ Mail::Message.any_instance.expects(:[]=).at_least_once.with(:from, 'audrey2@test.com')
71
+ Mail::Message.any_instance.expects(:[]=).at_least_once.with(:to, 'admin@test.com')
72
+ Mail::Message.any_instance.expects(:[]=).at_least_once.with(:subject, '[AUDREY 2.0] Exception Notification')
73
+ Mail::Message.any_instance.expects(:[]=).at_least_once.with(:body, all_of(
74
+ regexp_matches(/An exception occurred while running recipe recipe/),
75
+ regexp_matches(/Exception occurred when opening feed feed at http:\/\/test.com\/feed.xml:/),
76
+ regexp_matches(/404 Not Found/)
77
+ ))
78
+ Mail::Message.any_instance.expects(:delivery_method) .with(:smtp, all_of(
79
+ has_entry(:address => 'mail.test.com'),
80
+ has_entry(:port => '25'),
81
+ has_entry(:domain => 'test.com')
82
+ ))
83
+ Mail::Message.any_instance.stubs(:deliver)
84
+ @aggregator.feed_me('recipe')
85
+ end
86
+
87
+ should 'report feed-parsing error via email' do
88
+ @aggregator.stubs(:open).with('http://test.com/feed.xml', {'User-Agent' => 'user_agent'}).returns(@feed_content)
89
+ FeedNormalizer::FeedNormalizer.stubs(:parse).with(@feed_content).raises(Exception.new("Parsing exception"))
90
+ Mail::Message.any_instance.expects(:[]=).at_least_once.with(:from, 'audrey2@test.com')
91
+ Mail::Message.any_instance.expects(:[]=).at_least_once.with(:to, 'admin@test.com')
92
+ Mail::Message.any_instance.expects(:[]=).at_least_once.with(:subject, '[AUDREY 2.0] Exception Notification')
93
+ Mail::Message.any_instance.expects(:[]=).at_least_once.with(:body, all_of(
94
+ regexp_matches(/An exception occurred while running recipe recipe/),
95
+ regexp_matches(/Exception occurred when parsing feed feed which was downloaded from http:\/\/test.com\/feed.xml:/),
96
+ regexp_matches(/Parsing exception/)
97
+ ))
98
+ Mail::Message.any_instance.expects(:delivery_method) .with(:smtp, all_of(
99
+ has_entry(:address => 'mail.test.com'),
100
+ has_entry(:port => '25'),
101
+ has_entry(:domain => 'test.com')
102
+ ))
103
+ Mail::Message.any_instance.stubs(:deliver)
104
+ @aggregator.feed_me('recipe')
105
+ end
106
+
107
+ end
108
+
109
+ context "With an initialized Aggregator all configurated with sendmail email delivery" do
110
+ setup do
111
+ @config
112
+ File.stubs(:exist?).with('configfile').returns(true)
113
+ File.stubs(:readable?).with('configfile').returns(true)
114
+ YAML.stubs(:load_file).with('configfile').returns({
115
+ 'recipes_folder' => 'recipes_folder',
116
+ 'themes_folder' => 'themes_folder',
117
+ 'user_agent' => 'user_agent',
118
+ 'sort' => 'sort',
119
+ 'email' => {'to' => 'admin@test.com',
120
+ 'from' => 'audrey2@test.com',
121
+ 'via' => 'sendmail'
122
+ }
123
+ })
124
+ File.stubs(:exist?).with('recipes_folder').returns(true)
125
+ File.stubs(:readable?).with('recipes_folder').returns(true)
126
+ File.stubs(:exist?).with('themes_folder').returns(true)
127
+ File.stubs(:readable?).with('themes_folder').returns(true)
128
+ @aggregator = Audrey2::Aggregator.new('configfile')
129
+ recipefile = File.join('recipes_folder', 'recipe')
130
+ outputfile = File.join('output_folder', 'output_file')
131
+ File.stubs(:exist?).with(recipefile).returns(true)
132
+ File.stubs(:readable?).with(recipefile).returns(true)
133
+ @feed = { 'name' => 'feed', 'url' => 'http://test.com/feed.xml' }
134
+ YAML.stubs(:load_file).with(recipefile).returns({
135
+ 'feeds' => [@feed],
136
+ 'theme' => 'theme',
137
+ 'output_file' => outputfile
138
+ })
139
+ File.stubs(:exist?).with('output_folder').returns(true)
140
+ File.stubs(:writable?).with('output_folder').returns(true)
141
+ File.stubs(:exist?).with(outputfile).returns(false)
142
+ theme_path = File.join('themes_folder', 'theme')
143
+ File.stubs(:exist?).with(theme_path).returns(true)
144
+ File.stubs(:readable?).with(theme_path).returns(true)
145
+ entry_template_path = File.join(theme_path, 'entry.haml')
146
+ File.stubs(:exist?).with(entry_template_path).returns(true)
147
+ File.stubs(:readable?).with(entry_template_path).returns(true)
148
+ File.stubs(:read).with(entry_template_path).returns('%p= entry.title')
149
+ helpers_file_path = File.join(theme_path, 'helpers.rb')
150
+ File.stubs(:exist?).with(helpers_file_path).returns(false)
151
+ @feed_content =<<-EOF
152
+ <?xml version="1.0"?>
153
+ <rss version="2.0">
154
+ <channel>
155
+ <title>Test</title>
156
+ <link>http://test.com/</link>
157
+ <description>Test channel</description>
158
+ <item>
159
+ <title>Title</title>
160
+ <link>http://test.com/title</link>
161
+ <description>Test description</description>
162
+ <pubDate>Sun, 15 Aug 2010 16:46:00 EDT</pubDate>
163
+ </item>
164
+ </channel>
165
+ </rss>
166
+ EOF
167
+ end
168
+
169
+ should 'report feed-opening error via email' do
170
+ @aggregator.expects(:open).with('http://test.com/feed.xml', {'User-Agent' => 'user_agent'}).raises(Exception.new('404 Not Found'))
171
+ Mail::Message.any_instance.expects(:[]=).at_least_once.with(:from, 'audrey2@test.com')
172
+ Mail::Message.any_instance.expects(:[]=).at_least_once.with(:to, 'admin@test.com')
173
+ Mail::Message.any_instance.expects(:[]=).at_least_once.with(:subject, '[AUDREY 2.0] Exception Notification')
174
+ Mail::Message.any_instance.expects(:[]=).at_least_once.with(:body, all_of(
175
+ regexp_matches(/An exception occurred while running recipe recipe/),
176
+ regexp_matches(/Exception occurred when opening feed feed at http:\/\/test.com\/feed.xml:/),
177
+ regexp_matches(/404 Not Found/)
178
+ ))
179
+ Mail::Message.any_instance.expects(:delivery_method) .with(:sendmail)
180
+ Mail::Message.any_instance.stubs(:deliver)
181
+ @aggregator.feed_me('recipe')
182
+ end
183
+
184
+ should 'report feed-parsing error via email' do
185
+ @aggregator.stubs(:open).with('http://test.com/feed.xml', {'User-Agent' => 'user_agent'}).returns(@feed_content)
186
+ FeedNormalizer::FeedNormalizer.stubs(:parse).with(@feed_content).raises(Exception.new("Parsing exception"))
187
+ Mail::Message.any_instance.expects(:[]=).at_least_once.with(:from, 'audrey2@test.com')
188
+ Mail::Message.any_instance.expects(:[]=).at_least_once.with(:to, 'admin@test.com')
189
+ Mail::Message.any_instance.expects(:[]=).at_least_once.with(:subject, '[AUDREY 2.0] Exception Notification')
190
+ Mail::Message.any_instance.expects(:[]=).at_least_once.with(:body, all_of(
191
+ regexp_matches(/An exception occurred while running recipe recipe/),
192
+ regexp_matches(/Exception occurred when parsing feed feed which was downloaded from http:\/\/test.com\/feed.xml:/),
193
+ regexp_matches(/Parsing exception/)
194
+ ))
195
+ Mail::Message.any_instance.expects(:delivery_method) .with(:sendmail)
196
+ Mail::Message.any_instance.stubs(:deliver)
197
+ @aggregator.feed_me('recipe')
198
+ end
199
+
200
+ end
201
+
202
+ end
data/test/test_misc.rb ADDED
@@ -0,0 +1,50 @@
1
+ require 'helper'
2
+
3
+ class TestMisc < Test::Unit::TestCase
4
+ context "With HashExtensions loaded, Hash " do
5
+ setup do
6
+ @hash = {
7
+ 'key1' => 'value1',
8
+ 'key2' => :value2,
9
+ :key3 => 'value3',
10
+ :key4 => :value4,
11
+ 'key5' => { 'key5.1' => 'value5.1', 'key5.2' => {'key5.2.1' => 'value5.2.1'}},
12
+ 'key6' => [ {'key6.1' => 'value6.1'}, {'key6.2' => 'value6.2'}]
13
+ }
14
+ end
15
+
16
+ should "mixin HashExtensions" do
17
+ assert Hash.ancestors.include? HashExtensions
18
+ end
19
+
20
+
21
+ should "respond to recursively_symbolize_keys" do
22
+ assert @hash.respond_to? :recursively_symbolize_keys
23
+ end
24
+
25
+ context "output by Hash#recursively_symbolize_keys" do
26
+ setup do
27
+ @symbolized_hash = @hash.recursively_symbolize_keys
28
+ end
29
+
30
+ should 'convert string keys to symbols' do
31
+ [:key1, :key2, :key5, :key6].each { |key| assert @symbolized_hash.has_key? key }
32
+ end
33
+
34
+ should 'leave symbol keys untouched' do
35
+ [:key3, :key4].each { |key| assert @symbolized_hash.has_key? key }
36
+ end
37
+
38
+ should 'recurse into child hashes' do
39
+ [:'key5.1', :'key5.2'].each { |key| assert @symbolized_hash[:key5].has_key? key }
40
+ assert @symbolized_hash[:key5].has_key? :'key5.2'
41
+ assert @symbolized_hash[:key5][:'key5.2'].has_key? :'key5.2.1'
42
+ end
43
+
44
+ should 'recurse into child arrays which contain hashes' do
45
+ [:'key6.1', :'key6.2'].each_with_index { |key, i| assert @symbolized_hash[:key6][i].has_key? key }
46
+ end
47
+ end
48
+
49
+ end
50
+ end
@@ -0,0 +1,69 @@
1
+ require 'helper'
2
+
3
+ class TestOptions < Test::Unit::TestCase
4
+ context 'Calling Options::parse' do
5
+
6
+ context 'without a configfile location specified' do
7
+ setup do
8
+ @options = Audrey2::Options.parse([])
9
+ end
10
+
11
+ should 'use the default configfile location' do
12
+ assert_equal '/etc/audrey2.conf', @options[:config]
13
+ end
14
+ end
15
+
16
+ context 'with a configfile location specified' do
17
+ setup do
18
+ @options = Audrey2::Options.parse(['--config', 'my_config_file'])
19
+ end
20
+
21
+ should 'use the specified configfile location' do
22
+ assert_equal 'my_config_file', @options[:config]
23
+ end
24
+ end
25
+
26
+ context 'with various options and recipes' do
27
+ setup do
28
+ @args = ['--config', 'my_config_file', 'recipe1', 'recipe2']
29
+ Audrey2::Options.parse(@args)
30
+ end
31
+
32
+ should 'consume the options and leave the recipe list' do
33
+ assert_equal 2, @args.length
34
+ assert_equal 'recipe1', @args[0]
35
+ assert_equal 'recipe2', @args[1]
36
+ end
37
+ end
38
+
39
+ context 'with an invalid option' do
40
+ setup { @args = ['--invalid'] }
41
+
42
+ should 'report error, print usage, and exit' do
43
+ err = capture_stderr { assert_raise(SystemExit) { Audrey2::Options.parse(@args) } }
44
+ assert err.string =~ /invalid option: --invalid/
45
+ assert err.string =~ /Usage:/
46
+ end
47
+ end
48
+
49
+ context 'with a missing option argument' do
50
+ setup { @args = ['--config'] }
51
+
52
+ should 'report error, print usage, and exit' do
53
+ err = capture_stderr { assert_raise(SystemExit) { Audrey2::Options.parse(@args) } }
54
+ assert err.string =~ /missing argument: --config/
55
+ assert err.string =~ /Usage:/
56
+ end
57
+ end
58
+
59
+ context 'with --help' do
60
+ setup { @args = ['--help']}
61
+
62
+ should 'print usage and exit' do
63
+ out = capture_stdout { assert_raise(SystemExit) { Audrey2::Options.parse(@args) } }
64
+ assert out.string =~ /Usage:/
65
+ end
66
+ end
67
+ end
68
+
69
+ end
@@ -0,0 +1,87 @@
1
+ require 'helper'
2
+
3
+ class TestParse < Test::Unit::TestCase
4
+ context "With an initialized Aggregator and all configuration met (no email)" do
5
+ setup do
6
+ @config
7
+ File.stubs(:exist?).with('configfile').returns(true)
8
+ File.stubs(:readable?).with('configfile').returns(true)
9
+ YAML.stubs(:load_file).with('configfile').returns({
10
+ 'recipes_folder' => 'recipes_folder',
11
+ 'themes_folder' => 'themes_folder',
12
+ 'user_agent' => 'user_agent',
13
+ 'sort' => 'sort'
14
+ })
15
+ File.stubs(:exist?).with('recipes_folder').returns(true)
16
+ File.stubs(:readable?).with('recipes_folder').returns(true)
17
+ File.stubs(:exist?).with('themes_folder').returns(true)
18
+ File.stubs(:readable?).with('themes_folder').returns(true)
19
+ @aggregator = Audrey2::Aggregator.new('configfile')
20
+ recipefile = File.join('recipes_folder', 'recipe')
21
+ outputfile = File.join('output_folder', 'output_file')
22
+ File.stubs(:exist?).with(recipefile).returns(true)
23
+ File.stubs(:readable?).with(recipefile).returns(true)
24
+ @feed = { 'name' => 'feed', 'url' => 'http://test.com/feed.xml' }
25
+ YAML.stubs(:load_file).with(recipefile).returns({
26
+ 'feeds' => [@feed],
27
+ 'theme' => 'theme',
28
+ 'output_file' => outputfile
29
+ })
30
+ File.stubs(:exist?).with('output_folder').returns(true)
31
+ File.stubs(:writable?).with('output_folder').returns(true)
32
+ File.stubs(:exist?).with(outputfile).returns(false)
33
+ theme_path = File.join('themes_folder', 'theme')
34
+ File.stubs(:exist?).with(theme_path).returns(true)
35
+ File.stubs(:readable?).with(theme_path).returns(true)
36
+ entry_template_path = File.join(theme_path, 'entry.haml')
37
+ File.stubs(:exist?).with(entry_template_path).returns(true)
38
+ File.stubs(:readable?).with(entry_template_path).returns(true)
39
+ File.stubs(:read).with(entry_template_path).returns('%p= entry.title')
40
+ helpers_file_path = File.join(theme_path, 'helpers.rb')
41
+ File.stubs(:exist?).with(helpers_file_path).returns(false)
42
+ @feed_content =<<-EOF
43
+ <?xml version="1.0"?>
44
+ <rss version="2.0">
45
+ <channel>
46
+ <title>Test</title>
47
+ <link>http://test.com/</link>
48
+ <description>Test channel</description>
49
+ <item>
50
+ <title>Title</title>
51
+ <link>http://test.com/title</link>
52
+ <description>Test description</description>
53
+ <pubDate>Sun, 15 Aug 2010 16:46:00 EDT</pubDate>
54
+ </item>
55
+ </channel>
56
+ </rss>
57
+ EOF
58
+ end
59
+
60
+ should 'download, parse, and write templatized output' do
61
+ @aggregator.expects(:open).with('http://test.com/feed.xml', {'User-Agent' => 'user_agent'}).returns(@feed_content)
62
+ s = StringIO.new
63
+ s.expects(:<<).with("<p>Title</p>\n")
64
+ File.expects(:open).with(File.join('output_folder', 'output_file'), 'w').yields s
65
+ @aggregator.feed_me('recipe')
66
+ assert_equal '%p= entry.title', @aggregator.instance_variable_get('@entry_template')
67
+ end
68
+
69
+ should 'report feed-opening error via exit' do
70
+ @aggregator.expects(:open).with('http://test.com/feed.xml', {'User-Agent' => 'user_agent'}).raises(Exception.new('404 Not Found'))
71
+ err = capture_stderr { assert_raise(SystemExit) { @aggregator.feed_me('recipe') } }
72
+ assert err.string =~ /An exception occurred while running recipe recipe:/
73
+ assert err.string =~ /Exception occurred when opening feed feed at http:\/\/test.com\/feed.xml:/
74
+ assert err.string =~ /404 Not Found/
75
+ end
76
+
77
+ should 'report feed-parsing error via exit' do
78
+ @aggregator.stubs(:open).with('http://test.com/feed.xml', {'User-Agent' => 'user_agent'}).returns(@feed_content)
79
+ FeedNormalizer::FeedNormalizer.expects(:parse).with(@feed_content).raises(Exception.new("Parsing exception"))
80
+ err = capture_stderr { assert_raise(SystemExit) { @aggregator.feed_me('recipe') } }
81
+ assert err.string =~ /An exception occurred while running recipe recipe:/
82
+ assert err.string =~ /Exception occurred when parsing feed feed which was downloaded from http:\/\/test.com\/feed.xml:/
83
+ assert err.string =~ /Parsing exception/
84
+ end
85
+
86
+ end
87
+ end
@@ -0,0 +1,99 @@
1
+ require 'helper'
2
+
3
+ class TestRecipes < Test::Unit::TestCase
4
+ context "With an initialized Aggregator" do
5
+ setup do
6
+ @config
7
+ File.stubs(:exist?).with('configfile').returns(true)
8
+ File.stubs(:readable?).with('configfile').returns(true)
9
+ YAML.stubs(:load_file).with('configfile').returns({
10
+ 'recipes_folder' => 'recipes_folder',
11
+ 'themes_folder' => 'themes_folder',
12
+ 'user_agent' => 'user_agent',
13
+ 'sort' => 'sort'
14
+ })
15
+ File.stubs(:exist?).with('recipes_folder').returns(true)
16
+ File.stubs(:readable?).with('recipes_folder').returns(true)
17
+ File.stubs(:exist?).with('themes_folder').returns(true)
18
+ File.stubs(:readable?).with('themes_folder').returns(true)
19
+ @aggregator = Audrey2::Aggregator.new('configfile')
20
+ end
21
+
22
+ context "and a nonexistent recipe file" do
23
+ should 'report error and exit' do
24
+ recipefile = File.join('recipes_folder', 'recipe')
25
+ File.expects(:exist?).with(recipefile).returns(false)
26
+ err = capture_stderr { assert_raise(SystemExit) { @aggregator.feed_me('recipe') } }
27
+ assert_match /ERROR: Recipe file #{recipefile} does not exist/, err.string
28
+ end
29
+ end
30
+
31
+ context "and an unreadable recipe file" do
32
+ should 'report error and exit' do
33
+ recipefile = File.join('recipes_folder', 'recipe')
34
+ File.stubs(:exist?).with(recipefile).returns(true)
35
+ File.expects(:readable?).with(recipefile).returns(false)
36
+ err = capture_stderr { assert_raise(SystemExit) { @aggregator.feed_me('recipe') } }
37
+ assert_match /ERROR: Recipe file #{recipefile} is not readable/, err.string
38
+ end
39
+ end
40
+
41
+ context "with an unparsable recipe file" do
42
+ should 'report error and exit' do
43
+ recipefile = File.join('recipes_folder', 'recipe')
44
+ File.stubs(:exist?).with(recipefile).returns(true)
45
+ File.stubs(:readable?).with(recipefile).returns(true)
46
+ YAML.expects(:load_file).with(recipefile).raises(Exception)
47
+ err = capture_stderr { assert_raise(SystemExit) { @aggregator.feed_me('recipe') } }
48
+ assert_match /ERROR: Problem parsing recipe file #{recipefile}/, err.string
49
+ end
50
+ end
51
+
52
+ context "and a recipe file" do
53
+ setup do
54
+ recipefile = File.join('recipes_folder', 'recipe')
55
+ @outputfile = File.join('output_folder', 'output_file')
56
+ File.stubs(:exist?).with(recipefile).returns(true)
57
+ File.stubs(:readable?).with(recipefile).returns(true)
58
+ YAML.stubs(:load_file).with(recipefile).returns({
59
+ 'feeds' => [{ 'name' => 'feed', 'url' => 'http://test.com/feed.xml' }],
60
+ 'theme' => 'theme',
61
+ 'output_file' => @outputfile
62
+ })
63
+ end
64
+
65
+ context 'with an invalid output folder' do
66
+ should 'report error and exit' do
67
+ File.expects(:exist?).with('output_folder').returns(false)
68
+ err = capture_stderr { assert_raise(SystemExit) { @aggregator.feed_me('recipe') } }
69
+ assert_match /ERROR: Output folder output_folder does not exist/, err.string
70
+ end
71
+ end
72
+
73
+ context "and an unwritable output folder" do
74
+ should 'report error and exit' do
75
+ File.stubs(:exist?).with('output_folder').returns(true)
76
+ File.expects(:writable?).with('output_folder').returns(false)
77
+ err = capture_stderr { assert_raise(SystemExit) { @aggregator.feed_me('recipe') } }
78
+ assert_match /ERROR: Output folder output_folder is not writable/, err.string
79
+ end
80
+ end
81
+
82
+ context "and an existing but unwritable output file" do
83
+ setup do
84
+ File.stubs(:exist?).with('output_folder').returns(true)
85
+ File.stubs(:writable?).with('output_folder').returns(true)
86
+ end
87
+
88
+ should 'report error and exit' do
89
+ File.expects(:exist?).with(@outputfile).returns(true)
90
+ File.expects(:writable?).with(@outputfile).returns(false)
91
+ err = capture_stderr { assert_raise(SystemExit) { @aggregator.feed_me('recipe') } }
92
+ assert_match /ERROR: Output file #{@outputfile} is not writable/, err.string
93
+ end
94
+ end
95
+
96
+ # TODO: Verify max_entries behavior
97
+ end
98
+ end
99
+ end
data/test/test_sort.rb ADDED
@@ -0,0 +1,65 @@
1
+ require 'helper'
2
+
3
+ class TestOptions < Test::Unit::TestCase
4
+ context "With an initialized Aggregator" do
5
+ setup do
6
+ @config
7
+ File.stubs(:exist?).with('configfile').returns(true)
8
+ File.stubs(:readable?).with('configfile').returns(true)
9
+ YAML.stubs(:load_file).with('configfile').returns({
10
+ 'recipes_folder' => 'recipes_folder',
11
+ 'themes_folder' => 'themes_folder',
12
+ 'user_agent' => 'user_agent'
13
+ })
14
+ File.stubs(:exist?).with('recipes_folder').returns(true)
15
+ File.stubs(:readable?).with('recipes_folder').returns(true)
16
+ File.stubs(:exist?).with('themes_folder').returns(true)
17
+ File.stubs(:readable?).with('themes_folder').returns(true)
18
+ @aggregator = Audrey2::Aggregator.new('configfile')
19
+ end
20
+
21
+ context "And an unordered set of entries" do
22
+ setup do
23
+ class TestEntry
24
+ attr_accessor :date_published
25
+ def initialize(date_published); @date_published = date_published; end
26
+ end
27
+ @entry1 = TestEntry.new(Date.parse('2010-08-08'))
28
+ @entry2 = TestEntry.new(Date.parse('2010-08-09'))
29
+ @entry3 = TestEntry.new(Date.parse('2010-08-10'))
30
+ @entries = [@entry3, @entry1, @entry2]
31
+ end
32
+
33
+ should "sort in reverse order under reverse_chronological sort" do
34
+ assert_equal @entry3, @entries[0]
35
+ assert_equal @entry1, @entries[1]
36
+ assert_equal @entry2, @entries[2]
37
+ @entries.sort! &@aggregator.send(:entry_sort_comparator, :reverse_chronological)
38
+ assert_equal @entry3, @entries[0]
39
+ assert_equal @entry2, @entries[1]
40
+ assert_equal @entry1, @entries[2]
41
+ end
42
+
43
+ should "sort in chronological order under chronological sort" do
44
+ assert_equal @entry3, @entries[0]
45
+ assert_equal @entry1, @entries[1]
46
+ assert_equal @entry2, @entries[2]
47
+ @entries.sort! &@aggregator.send(:entry_sort_comparator, :chronological)
48
+ assert_equal @entry1, @entries[0]
49
+ assert_equal @entry2, @entries[1]
50
+ assert_equal @entry3, @entries[2]
51
+ end
52
+
53
+ should "sort in reverse order by default" do
54
+ assert_equal @entry3, @entries[0]
55
+ assert_equal @entry1, @entries[1]
56
+ assert_equal @entry2, @entries[2]
57
+ @entries.sort! &@aggregator.send(:entry_sort_comparator, :reverse_chronological)
58
+ assert_equal @entry3, @entries[0]
59
+ assert_equal @entry2, @entries[1]
60
+ assert_equal @entry1, @entries[2]
61
+ end
62
+
63
+ end
64
+ end
65
+ end