audrey2 0.2.1 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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