dropcaster 0.0.4 → 0.0.5.rc1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.document +5 -5
- data/.gitignore +14 -0
- data/.travis.yml +6 -0
- data/Gemfile +2 -13
- data/Gemfile.lock +94 -29
- data/Guardfile +12 -0
- data/LICENSE.txt +20 -20
- data/{README.md → README.markdown} +185 -171
- data/Rakefile +11 -47
- data/TODO +13 -12
- data/bin/dropcaster +129 -117
- data/bin/lstags +51 -45
- data/doc/sample-channel.yml +88 -81
- data/doc/sample-sidecar.yml +19 -19
- data/dropcaster.gemspec +36 -97
- data/lib/dropcaster/channel.rb +195 -159
- data/lib/dropcaster/channel_file_locator.rb +57 -57
- data/lib/dropcaster/errors.rb +25 -25
- data/lib/dropcaster/item.rb +28 -47
- data/lib/dropcaster/log_formatter.rb +9 -9
- data/lib/dropcaster/version.rb +3 -0
- data/lib/dropcaster.rb +28 -30
- data/templates/channel.html.erb +45 -43
- data/templates/channel.rss.erb +65 -64
- data/test/extensions/windows.rb +12 -12
- data/test/fixtures/channel.yml +16 -15
- data/test/fixtures/test_template.json.erb +40 -40
- data/test/helper.rb +10 -14
- data/test/unit/test_app.rb +129 -99
- data/test/unit/test_channel.rb +80 -73
- data/test/unit/test_channel_locator.rb +76 -93
- data/test/unit/test_channel_xml.rb +90 -89
- data/test/unit/test_item.rb +51 -63
- metadata +225 -158
- data/VERSION +0 -1
- data/lib/dropcaster/hashkeys.rb +0 -12
data/test/unit/test_app.rb
CHANGED
@@ -1,99 +1,129 @@
|
|
1
|
-
require 'helper'
|
2
|
-
require '
|
3
|
-
require '
|
4
|
-
require '
|
5
|
-
|
6
|
-
|
7
|
-
#
|
8
|
-
# End-to-end test
|
9
|
-
#
|
10
|
-
# Same as TestChannelXML, but with the XML generated by calling the bin script
|
11
|
-
#
|
12
|
-
class TestApp < TestChannelXML
|
13
|
-
include DropcasterTest
|
14
|
-
APP_SCRIPT = 'ruby bin/dropcaster'
|
15
|
-
|
16
|
-
def channel_rss
|
17
|
-
%x[#{APP_SCRIPT} #{FIXTURE_ITUNES_MP3}]
|
18
|
-
end
|
19
|
-
|
20
|
-
def test_overwrite_title
|
21
|
-
test_title = 'Alice and Bob in Wonderland'
|
22
|
-
channel = channel_node(%x[#{APP_SCRIPT} #{FIXTURE_ITUNES_MP3} --title '#{test_title}'])
|
23
|
-
assert_equal(test_title, channel.find('title').first.content)
|
24
|
-
end
|
25
|
-
|
26
|
-
def
|
27
|
-
|
28
|
-
channel = channel_node(%x[#{APP_SCRIPT} #{FIXTURE_ITUNES_MP3} --
|
29
|
-
assert_equal(
|
30
|
-
end
|
31
|
-
|
32
|
-
def
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
assert_equal(
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
1
|
+
require 'helper'
|
2
|
+
require 'open3'
|
3
|
+
require 'uri'
|
4
|
+
require 'json'
|
5
|
+
require_relative 'test_channel_xml'
|
6
|
+
|
7
|
+
#
|
8
|
+
# End-to-end test
|
9
|
+
#
|
10
|
+
# Same as TestChannelXML, but with the XML generated by calling the bin script
|
11
|
+
#
|
12
|
+
class TestApp < TestChannelXML
|
13
|
+
include DropcasterTest
|
14
|
+
APP_SCRIPT = 'ruby bin/dropcaster'
|
15
|
+
|
16
|
+
def channel_rss
|
17
|
+
%x[#{APP_SCRIPT} #{FIXTURE_ITUNES_MP3}]
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_overwrite_title
|
21
|
+
test_title = 'Alice and Bob in Wonderland'
|
22
|
+
channel = channel_node(%x[#{APP_SCRIPT} #{FIXTURE_ITUNES_MP3} --title '#{test_title}'])
|
23
|
+
assert_equal(test_title, channel.find('title').first.content)
|
24
|
+
end
|
25
|
+
|
26
|
+
def test_overwrite_subtitle
|
27
|
+
test_subtitle = 'Tales from another world that is upside down'
|
28
|
+
channel = channel_node(%x[#{APP_SCRIPT} #{FIXTURE_ITUNES_MP3} --subtitle '#{test_subtitle}'])
|
29
|
+
assert_equal(test_subtitle, channel.find('itunes:subtitle').first.content)
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_overwrite_link
|
33
|
+
test_link = 'http://www.example.com/foo/bar'
|
34
|
+
channel = channel_node(%x[#{APP_SCRIPT} #{FIXTURE_ITUNES_MP3} --url '#{test_link}'])
|
35
|
+
assert_equal(test_link, channel.find('link').first.content)
|
36
|
+
end
|
37
|
+
|
38
|
+
def test_overwrite_link_without_ending_slash
|
39
|
+
test_link_base = 'http://www.dropbox.com/foo/bar/'
|
40
|
+
test_link_file = 'index.html'
|
41
|
+
test_link = "#{test_link_base}#{test_link_file}"
|
42
|
+
channel = channel_node(%x[#{APP_SCRIPT} #{FIXTURE_ITUNES_MP3} --url '#{test_link}'])
|
43
|
+
assert_equal(test_link, channel.find('link').first.content)
|
44
|
+
|
45
|
+
options = YAML.load_file(File.join(FIXTURES_DIR, Dropcaster::CHANNEL_YML))
|
46
|
+
assert_equal(URI.join(test_link_base, options[:image_url]).to_s, channel.find('itunes:image').first['href'])
|
47
|
+
|
48
|
+
# check that the item URLs are correct, too
|
49
|
+
item = channel.find("item").first
|
50
|
+
assert(item)
|
51
|
+
|
52
|
+
# enclosure
|
53
|
+
enclosure = item.find('enclosure').first
|
54
|
+
assert(enclosure)
|
55
|
+
assert_equal(URI.join(test_link_base, 'test/fixtures/iTunes.mp3').to_s, enclosure['url'])
|
56
|
+
|
57
|
+
# item image
|
58
|
+
assert_equal(URI.join(test_link_base, options[:image_url]).to_s, item.find('itunes:image').first['href'])
|
59
|
+
end
|
60
|
+
|
61
|
+
def test_dir_only
|
62
|
+
channel = channel_node(%x[#{APP_SCRIPT} #{FIXTURES_DIR}])
|
63
|
+
assert_equal(1, channel.find('item').size)
|
64
|
+
end
|
65
|
+
|
66
|
+
def test_overwrite_enclosures_url
|
67
|
+
test_enclosures_url = 'http://www.example.com/foo/bar/episodes/'
|
68
|
+
channel = channel_node(%x[#{APP_SCRIPT} #{FIXTURE_ITUNES_MP3} --enclosures '#{test_enclosures_url}'])
|
69
|
+
item = channel.find("item").first
|
70
|
+
assert(item)
|
71
|
+
enclosure = item.find('enclosure').first
|
72
|
+
assert(enclosure)
|
73
|
+
assert_equal(URI.join(test_enclosures_url,'test/fixtures/iTunes.mp3').to_s, enclosure['url'])
|
74
|
+
end
|
75
|
+
|
76
|
+
def test_overwrite_image_url
|
77
|
+
test_image_url = 'http://www.example.com/foo/bar/override.gif'
|
78
|
+
channel = channel_node(%x[#{APP_SCRIPT} #{FIXTURE_ITUNES_MP3} --image '#{test_image_url}'])
|
79
|
+
assert_equal(test_image_url, channel.find('itunes:image').first['href'])
|
80
|
+
|
81
|
+
# Make sure the items pick up this URL, too
|
82
|
+
item = channel.find("item").first
|
83
|
+
assert(item)
|
84
|
+
assert_equal(test_image_url, item.find('itunes:image').first['href'])
|
85
|
+
end
|
86
|
+
|
87
|
+
def test_overwrite_description
|
88
|
+
test_description = 'Testing commandline apps is not that hard.'
|
89
|
+
channel = channel_node(%x[#{APP_SCRIPT} #{FIXTURE_ITUNES_MP3} --description '#{test_description}'])
|
90
|
+
assert_equal(test_description, channel.find('description').first.content)
|
91
|
+
assert_equal(test_description, channel.find('itunes:summary', NS_ITUNES).first.content)
|
92
|
+
end
|
93
|
+
|
94
|
+
def test_no_channel_file
|
95
|
+
Open3.popen3(APP_SCRIPT){|stdin, stdout, stderr|
|
96
|
+
assert_match(/ERROR: No channel file found/, stderr.read)
|
97
|
+
} unless Kernel.is_windows?
|
98
|
+
end
|
99
|
+
|
100
|
+
def test_overwrite_all
|
101
|
+
test_title = 'Bob and Alice in Wonderland'
|
102
|
+
test_link = 'http://www.example.com/bar/foot'
|
103
|
+
test_description = 'Testing commandline apps is really not that hard.'
|
104
|
+
|
105
|
+
channel = channel_node(%x[#{APP_SCRIPT} #{FIXTURE_ITUNES_MP3} --title '#{test_title}' --url '#{test_link}' --description '#{test_description}'])
|
106
|
+
|
107
|
+
assert_equal(test_title, channel.find('title').first.content)
|
108
|
+
assert_equal(test_link, channel.find('link').first.content)
|
109
|
+
assert_equal(test_description, channel.find('description').first.content)
|
110
|
+
assert_equal(test_description, channel.find('itunes:summary', NS_ITUNES).first.content)
|
111
|
+
end
|
112
|
+
|
113
|
+
def test_channel_template_not_found
|
114
|
+
Open3.popen3("#{APP_SCRIPT} #{FIXTURE_ITUNES_MP3} --channel-template foo/bar/42"){|stdin, stdout, stderr|
|
115
|
+
assert_match(/Unable to load template file/, stderr.read)
|
116
|
+
} unless Kernel.is_windows?
|
117
|
+
end
|
118
|
+
|
119
|
+
#
|
120
|
+
# We supply an alternative channel template that produces JSON, parse it back and make some basic assertions on the results
|
121
|
+
#
|
122
|
+
def test_overwrite_channel_template
|
123
|
+
channel_template = File.join(FIXTURES_DIR, 'test_template.json.erb')
|
124
|
+
channel = JSON.parse(%x[#{APP_SCRIPT} #{FIXTURE_ITUNES_MP3} --channel-template #{channel_template}])
|
125
|
+
assert_equal("All About Everything", channel['channel']['title'])
|
126
|
+
end
|
127
|
+
|
128
|
+
# TODO --channel
|
129
|
+
end
|
data/test/unit/test_channel.rb
CHANGED
@@ -1,73 +1,80 @@
|
|
1
|
-
require 'helper'
|
2
|
-
|
3
|
-
class TestChannel < Test
|
4
|
-
include DropcasterTest
|
5
|
-
|
6
|
-
def setup
|
7
|
-
@options = YAML.load_file(File.join(FIXTURES_DIR, Dropcaster::CHANNEL_YML))
|
8
|
-
@channel = Dropcaster::Channel.new(FIXTURES_DIR, @options)
|
9
|
-
end
|
10
|
-
|
11
|
-
def test_item_count
|
12
|
-
assert_equal(1, @channel.items.size)
|
13
|
-
end
|
14
|
-
|
15
|
-
def test_channel
|
16
|
-
assert_equal(@options[:title], @channel.title)
|
17
|
-
assert_equal(@options[:url], @channel.url)
|
18
|
-
assert_equal(@options[:description], @channel.description)
|
19
|
-
assert_equal(@options[:subtitle], @channel.subtitle)
|
20
|
-
assert_equal(@options[:language], @channel.language)
|
21
|
-
assert_equal(@options[:copyright], @channel.copyright)
|
22
|
-
assert_equal(@options[:author], @channel.author)
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
assert_equal(@options[:owner][:
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
end
|
1
|
+
require 'helper'
|
2
|
+
|
3
|
+
class TestChannel < MiniTest::Test
|
4
|
+
include DropcasterTest
|
5
|
+
|
6
|
+
def setup
|
7
|
+
@options = YAML.load_file(File.join(FIXTURES_DIR, Dropcaster::CHANNEL_YML))
|
8
|
+
@channel = Dropcaster::Channel.new(FIXTURES_DIR, @options)
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_item_count
|
12
|
+
assert_equal(1, @channel.items.size)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_channel
|
16
|
+
assert_equal(@options[:title], @channel.title)
|
17
|
+
assert_equal(@options[:url], @channel.url)
|
18
|
+
assert_equal(@options[:description], @channel.description)
|
19
|
+
assert_equal(@options[:subtitle], @channel.subtitle)
|
20
|
+
assert_equal(@options[:language], @channel.language)
|
21
|
+
assert_equal(@options[:copyright], @channel.copyright)
|
22
|
+
assert_equal(@options[:author], @channel.author)
|
23
|
+
assert_equal(@options[:keywords], @channel.keywords)
|
24
|
+
|
25
|
+
owner = @channel.owner
|
26
|
+
assert_equal(@options[:owner][:name], owner[:name])
|
27
|
+
assert_equal(@options[:owner][:email], owner[:email])
|
28
|
+
|
29
|
+
assert_equal(URI.join(@options[:url], @options[:image_url]).to_s, @channel.image_url)
|
30
|
+
|
31
|
+
categories = @channel.categories
|
32
|
+
assert_equal(@options[:categories], categories)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_channel_url_without_slash
|
36
|
+
@options[:url] << 'index.html'
|
37
|
+
@channel = Dropcaster::Channel.new(FIXTURES_DIR, @options)
|
38
|
+
assert_equal(@options[:url], @channel.url)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_channel_explicit_yes
|
42
|
+
assert_channel_explicit('Yes', true)
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_channel_explicit_no
|
46
|
+
assert_channel_explicit('No', false)
|
47
|
+
end
|
48
|
+
|
49
|
+
def test_channel_explicit_nil
|
50
|
+
assert_channel_explicit(nil, nil)
|
51
|
+
end
|
52
|
+
|
53
|
+
def test_channel_explicit_clean
|
54
|
+
assert_channel_explicit('Clean', 'Clean')
|
55
|
+
end
|
56
|
+
|
57
|
+
def assert_channel_explicit(expected, value)
|
58
|
+
@options[:explicit] = value
|
59
|
+
channel = Dropcaster::Channel.new(FIXTURES_DIR, @options)
|
60
|
+
assert_equal(expected, channel.explicit)
|
61
|
+
end
|
62
|
+
|
63
|
+
def test_raise_on_missing_title
|
64
|
+
assert_raises Dropcaster::MissingAttributeError do
|
65
|
+
Dropcaster::Channel.new(FIXTURES_DIR, {:url => 'bar', :description => 'foobar'})
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
def test_raise_on_missing_url
|
70
|
+
assert_raises Dropcaster::MissingAttributeError do
|
71
|
+
Dropcaster::Channel.new(FIXTURES_DIR, {:title => 'foo', :description => 'foobar'})
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def test_raise_on_missing_description
|
76
|
+
assert_raises Dropcaster::MissingAttributeError do
|
77
|
+
Dropcaster::Channel.new(FIXTURES_DIR, {:title => 'foo', :url => 'bar'})
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
@@ -1,93 +1,76 @@
|
|
1
|
-
require 'helper'
|
2
|
-
require 'tmpdir'
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
end
|
31
|
-
|
32
|
-
def
|
33
|
-
sources =
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
sources
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
sources << File.join(tmp_dir1, 'another_dir')
|
78
|
-
sources << File.join(tmp_dir2, 'another_dir')
|
79
|
-
|
80
|
-
assert_raises Dropcaster::AmbiguousSourcesError do
|
81
|
-
Dropcaster::ChannelFileLocator.locate(sources)
|
82
|
-
end
|
83
|
-
}
|
84
|
-
}
|
85
|
-
end
|
86
|
-
|
87
|
-
private
|
88
|
-
|
89
|
-
def assert_location(sources)
|
90
|
-
channel_file = Dropcaster::ChannelFileLocator.locate(sources)
|
91
|
-
assert_equal(File.join(TestChannelLocator.temp_dir, Dropcaster::CHANNEL_YML), channel_file)
|
92
|
-
end
|
93
|
-
end
|
1
|
+
require 'helper'
|
2
|
+
require 'tmpdir'
|
3
|
+
require 'pry'
|
4
|
+
|
5
|
+
class TestChannelLocator < MiniTest::Test
|
6
|
+
include DropcasterTest
|
7
|
+
|
8
|
+
def setup
|
9
|
+
@temp_dir = Dir.mktmpdir
|
10
|
+
end
|
11
|
+
def teardown
|
12
|
+
FileUtils.remove_entry_secure(@temp_dir)
|
13
|
+
end
|
14
|
+
|
15
|
+
def test_single_file
|
16
|
+
sources = File.join(@temp_dir, 'single_file.mp3')
|
17
|
+
assert_location(sources)
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_current_directory
|
21
|
+
sources = File.join(@temp_dir, '.')
|
22
|
+
assert_location(Pathname.new(sources).cleanpath) # Cleanup path before we compare
|
23
|
+
end
|
24
|
+
|
25
|
+
def test_single_directory
|
26
|
+
source_dir = File.join(@temp_dir, 'single_dir')
|
27
|
+
Dir.mkdir(source_dir)
|
28
|
+
expected = File.join(@temp_dir, 'single_dir', Dropcaster::CHANNEL_YML)
|
29
|
+
assert_equal(expected, Dropcaster::ChannelFileLocator.locate(source_dir))
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_array_of_files_same_dir
|
33
|
+
sources = Array.new
|
34
|
+
sources << File.join(@temp_dir, 'file1.mp3')
|
35
|
+
sources << File.join(@temp_dir, 'file2.mp3')
|
36
|
+
sources << File.join(@temp_dir, 'file3.mp3')
|
37
|
+
|
38
|
+
assert_location(sources)
|
39
|
+
end
|
40
|
+
|
41
|
+
def test_array_of_files_different_dir
|
42
|
+
sources = Array.new
|
43
|
+
sources << File.join(@temp_dir, 'foo', 'file1.mp3')
|
44
|
+
sources << File.join(@temp_dir, 'bar', 'file1.mp3')
|
45
|
+
sources << File.join(@temp_dir, 'baz', 'file1.mp3')
|
46
|
+
|
47
|
+
assert_raises Dropcaster::AmbiguousSourcesError do
|
48
|
+
Dropcaster::ChannelFileLocator.locate(sources)
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def test_array_with_one_directory
|
53
|
+
assert_location(File.join(@temp_dir, ['single_dir']))
|
54
|
+
end
|
55
|
+
|
56
|
+
def test_array_with_more_than_a_single_directory
|
57
|
+
Dir.mktmpdir{|tmp_dir1|
|
58
|
+
Dir.mktmpdir{|tmp_dir2|
|
59
|
+
sources = Array.new
|
60
|
+
sources << File.join(tmp_dir1, 'another_dir')
|
61
|
+
sources << File.join(tmp_dir2, 'another_dir')
|
62
|
+
|
63
|
+
assert_raises Dropcaster::AmbiguousSourcesError do
|
64
|
+
Dropcaster::ChannelFileLocator.locate(sources)
|
65
|
+
end
|
66
|
+
}
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
private
|
71
|
+
|
72
|
+
def assert_location(sources)
|
73
|
+
channel_file = Dropcaster::ChannelFileLocator.locate(sources)
|
74
|
+
assert_equal(File.join(@temp_dir, Dropcaster::CHANNEL_YML), channel_file)
|
75
|
+
end
|
76
|
+
end
|