dropcaster 0.0.4 → 0.0.5.rc1
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.
- 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
|