flac2mp3 0.2.8 → 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.
data/History.txt CHANGED
@@ -1,3 +1,10 @@
1
+ == 0.3.0 2008-07-29
2
+
3
+ * 2 enhancements:
4
+ * Now has a configuration file, ~/.flac2mp3, where options can be stored.
5
+ Options given on the command-line override any configuration options.
6
+ * Greatly refactored internals, though the command-line operation remains the same.
7
+
1
8
  == 0.2.8 2008-07-21
2
9
 
3
10
  * 1 enhancement:
data/Manifest.txt CHANGED
@@ -7,7 +7,6 @@ bin/flac2mp3
7
7
  config/hoe.rb
8
8
  config/requirements.rb
9
9
  lib/flac2mp3.rb
10
- lib/flac2mp3/string_extensions.rb
11
10
  lib/flac2mp3/version.rb
12
11
  log/debug.log
13
12
  script/destroy
@@ -17,7 +16,6 @@ spec/flac2mp3_command_spec.rb
17
16
  spec/flac2mp3_spec.rb
18
17
  spec/spec.opts
19
18
  spec/spec_helper.rb
20
- spec/string_extensions_spec.rb
21
19
  tasks/deployment.rake
22
20
  tasks/environment.rake
23
21
  tasks/rspec.rake
data/bin/flac2mp3 CHANGED
@@ -15,7 +15,7 @@ require 'flac2mp3/version'
15
15
 
16
16
  # NOTE: the option -p/--path= is given as an example, and should probably be replaced in your application.
17
17
 
18
- OPTIONS = { :delete => false, :silent => false }
18
+ OPTIONS = {}
19
19
  MANDATORY_OPTIONS = %w[]
20
20
 
21
21
  parser = OptionParser.new do |opts|
@@ -32,7 +32,7 @@ BANNER
32
32
  opts.on('-s', '--silent',
33
33
  "Don't show progress") { |silent| OPTIONS[:silent] = silent }
34
34
  opts.on('-e', '--encoding=ENCODING', String,
35
- "Set lame encoding options", "Default: --preset standard") { |encoding| OPTIONS[:encoding] = encoding }
35
+ "Set lame encoding options", "Default: #{Flac2mp3.default_encoding}") { |encoding| OPTIONS[:encoding] = encoding }
36
36
  opts.on('-h', '--help',
37
37
  'Show this help message.') { puts opts; exit }
38
38
  opts.parse!(ARGV)
@@ -50,4 +50,4 @@ unless filename
50
50
  exit
51
51
  end
52
52
 
53
- Flac2mp3.convert(filename.dup, OPTIONS)
53
+ Flac2mp3.convert(filename, OPTIONS)
data/lib/flac2mp3.rb CHANGED
@@ -1,30 +1,116 @@
1
1
  $:.unshift File.dirname(__FILE__)
2
- require 'flac2mp3/string_extensions'
3
2
  require 'flacinfo'
4
3
  require 'mp3info'
4
+ require 'yaml'
5
5
 
6
- module Flac2mp3
7
- class << self
8
- def convert(filename, options = {})
9
- raise TypeError, "'#{filename}' is not a file" unless FileTest.file?(filename)
10
- filename.extend(Flac2mp3::StringExtensions)
11
- out_filename = output_filename(filename)
12
- out_filename.extend(Flac2mp3::StringExtensions)
13
-
14
- commands = { :flac => 'flac', :mp3 => 'lame' }
15
- commands.each { |k, v| v << ' --silent' } if options[:silent]
16
- encoding = options[:encoding]
17
- encoding = default_encoding if encoding.to_s.strip.empty?
18
-
19
- system "#{commands[:flac]} --stdout --decode #{filename.safequote} | #{commands[:mp3]} #{encoding} - #{out_filename.safequote}"
20
-
21
- mp3data(out_filename, flacdata(filename))
6
+ class Flac2mp3
7
+ def initialize(options = {})
8
+ @config = {}
9
+ load_config
10
+ set_options(options)
11
+ end
12
+
13
+ def convert(filename)
14
+ raise TypeError, "'#{filename}' is not a file" unless FileTest.file?(filename)
15
+ process_conversion(filename)
16
+ File.delete(filename) if delete?
17
+ end
18
+
19
+ def process_conversion(filename)
20
+ outfile = output_filename(filename)
21
+ convert_data(filename, outfile)
22
+ convert_metadata(filename, outfile)
23
+ end
24
+
25
+ def convert_data(filename, outfile)
26
+ system "#{flac_command(filename)} | #{mp3_command(outfile)}"
27
+ end
28
+
29
+ def flac_command(filename)
30
+ command = 'flac'
31
+ command << ' --silent' if silent?
32
+
33
+ "#{command} --stdout --decode #{safequote(filename)}"
34
+ end
35
+
36
+ def mp3_command(filename)
37
+ command = 'lame'
38
+ command << ' --silent' if silent?
39
+
40
+ "#{command} #{encoding} - #{safequote(filename)}"
41
+ end
42
+
43
+ def convert_metadata(filename, outfile)
44
+ set_mp3data(outfile, get_flacdata(filename))
45
+ end
46
+
47
+ def get_flacdata(filename)
48
+ FlacInfo.new(filename).tags.inject({}) do |hash, (key, value)|
49
+ key = key.to_s.downcase.to_sym
50
+ value = value.to_i if value.respond_to?(:match) and value.match(/^\d+$/)
51
+ value = value.to_s if self.class.string_fields.include?(key)
22
52
 
23
- File.delete(filename) if options[:delete]
53
+ hash[key] = value
54
+ hash
24
55
  end
25
-
26
- def output_filename(filename)
27
- filename.chomp('.flac') + '.mp3'
56
+ end
57
+
58
+ def set_mp3data(filename, tags)
59
+ raise TypeError, "Tags must be a hash" unless tags.is_a?(Hash)
60
+ Mp3Info.open(filename) do |mp3|
61
+ self.class.convert_tags(tags).each do |mp3tag, data|
62
+ tag = mp3.send(data[:target])
63
+ tag.send("#{mp3tag}=", data[:value])
64
+ end
65
+ end
66
+ end
67
+
68
+ def load_config
69
+ yaml = YAML.load(File.read(File.expand_path('~/.flac2mp3'))) || {}
70
+ @config = yaml.inject({}) do |hash, (key, value)|
71
+ hash[key.to_sym] = value
72
+ hash
73
+ end
74
+ rescue Errno::ENOENT
75
+ @config = {}
76
+ end
77
+
78
+ def set_options(options)
79
+ raise TypeError, 'options must be a hash' unless options.is_a?(Hash)
80
+ @options = config.merge(options)
81
+ end
82
+
83
+ def options
84
+ @options.dup
85
+ end
86
+
87
+ def config
88
+ @config.dup
89
+ end
90
+
91
+ def delete?
92
+ !!options[:delete]
93
+ end
94
+
95
+ def silent?
96
+ !!options[:silent]
97
+ end
98
+
99
+ def encoding
100
+ options[:encoding] || self.class.default_encoding
101
+ end
102
+
103
+ def output_filename(filename)
104
+ filename.chomp('.flac') + '.mp3'
105
+ end
106
+
107
+ def safequote(filename)
108
+ filename.gsub(/(\W)/, '\\\\\1')
109
+ end
110
+
111
+ class << self
112
+ def convert(filename, options = {})
113
+ new(options).convert(filename)
28
114
  end
29
115
 
30
116
  def tag_mapping
@@ -45,45 +131,6 @@ module Flac2mp3
45
131
  }
46
132
  end
47
133
 
48
- def flacdata(filename)
49
- data = FlacInfo.new(filename)
50
- data.tags.inject({}) do |hash, (key, value)|
51
- key = key.to_s.downcase.to_sym
52
- value = value.to_i if value.respond_to?(:match) and value.match(/^\d+$/)
53
- value = value.to_s if string_fields.include?(key)
54
- hash[key] = value
55
- hash
56
- end
57
- end
58
-
59
- def mp3data(filename, tags)
60
- raise TypeError, "Tags must be a hash" unless tags.is_a?(Hash)
61
- Mp3Info.open(filename) do |mp3|
62
- convert_tags(tags).each do |mp3tag, data|
63
- tag = mp3.send(data[:target])
64
- tag.send("#{mp3tag}=", data[:value])
65
- end
66
- end
67
- end
68
-
69
-
70
- private
71
-
72
- def string_fields
73
- [:title, :description]
74
- end
75
-
76
- def tag2_fields
77
- [:bpm, :composer, :compilation, :tracktotal, :tracknumber, :disctotal, :discnumber]
78
- end
79
-
80
- def tag_formats
81
- {
82
- :TRCK => ':tracknumber/:tracktotal',
83
- :TPOS => ':discnumber/:disctotal'
84
- }
85
- end
86
-
87
134
  def convert_tags(tags)
88
135
  mp3_tags = {}
89
136
 
@@ -100,14 +147,27 @@ module Flac2mp3
100
147
  target = tag2_fields.include?(key) ? :tag2 : :tag
101
148
  mp3_tags[mp3tag] = { :target => target, :value => value }
102
149
  end
150
+
103
151
  mp3_tags
104
152
  end
105
153
 
106
-
107
- private
108
-
109
154
  def default_encoding
110
155
  '--preset standard'
111
156
  end
157
+
158
+ def string_fields
159
+ [:title, :description]
160
+ end
161
+
162
+ def tag2_fields
163
+ [:bpm, :composer, :compilation, :tracktotal, :tracknumber, :disctotal, :discnumber]
164
+ end
165
+
166
+ def tag_formats
167
+ {
168
+ :TRCK => ':tracknumber/:tracktotal',
169
+ :TPOS => ':discnumber/:disctotal'
170
+ }
171
+ end
112
172
  end
113
173
  end
@@ -1,8 +1,8 @@
1
- module Flac2mp3 #:nodoc:
1
+ class Flac2mp3 #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
- MINOR = 2
5
- TINY = 8
4
+ MINOR = 3
5
+ TINY = 0
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -36,12 +36,6 @@ describe 'flac2mp3 command' do
36
36
  run_command('blah')
37
37
  end
38
38
 
39
- it 'should duplicate the filename' do
40
- filename = 'blah'
41
- filename.expects(:dup).returns(filename)
42
- run_command(filename)
43
- end
44
-
45
39
  it 'should pass on a true flac-deletion option if specified on the command line (using --delete)' do
46
40
  Flac2mp3.expects(:convert).with(anything, has_entry(:delete => true))
47
41
  run_command('blah', '--delete')
@@ -57,8 +51,8 @@ describe 'flac2mp3 command' do
57
51
  run_command('blah', '-d')
58
52
  end
59
53
 
60
- it 'should pass on a false flac-deletion option if nothing specified on the command line' do
61
- Flac2mp3.expects(:convert).with(anything, has_entry(:delete => false))
54
+ it 'should not pass on any flac-deletion option if nothing specified on the command line' do
55
+ Flac2mp3.expects(:convert).with(anything, Not(has_key(:delete)))
62
56
  run_command('blah')
63
57
  end
64
58
 
@@ -72,8 +66,8 @@ describe 'flac2mp3 command' do
72
66
  run_command('blah', '-s')
73
67
  end
74
68
 
75
- it 'should pass on a false silence option if nothing specified on the command line' do
76
- Flac2mp3.expects(:convert).with(anything, has_entry(:silent => false))
69
+ it 'should not pass on any silence option if nothing specified on the command line' do
70
+ Flac2mp3.expects(:convert).with(anything, Not(has_key(:silent)))
77
71
  run_command('blah')
78
72
  end
79
73
 
@@ -1,459 +1,876 @@
1
1
  require File.dirname(__FILE__) + '/spec_helper.rb'
2
2
 
3
3
  describe Flac2mp3 do
4
- it 'should convert' do
5
- Flac2mp3.should respond_to(:convert)
6
- end
7
-
8
- it 'should provide output filename' do
9
- Flac2mp3.should respond_to(:output_filename)
10
- end
11
-
12
- it 'should provide tag mapping' do
13
- Flac2mp3.should respond_to(:tag_mapping)
14
- end
15
-
16
- it 'should get FLAC tag data' do
17
- Flac2mp3.should respond_to(:flacdata)
18
- end
19
-
20
- it 'should set MP3 tag data' do
21
- Flac2mp3.should respond_to(:mp3data)
22
- end
23
- end
24
-
25
- describe Flac2mp3, 'when converting' do
26
4
  before :each do
27
- Flac2mp3.stubs(:system)
28
- Flac2mp3.stubs(:flacdata)
29
- Flac2mp3.stubs(:mp3data)
30
- File.stubs(:delete)
31
- end
32
-
33
- it 'should require a filename' do
34
- lambda { Flac2mp3.convert }.should raise_error(ArgumentError)
5
+ @flac2mp3 = Flac2mp3.new
35
6
  end
36
7
 
37
- it 'should accept a filename' do
38
- lambda { Flac2mp3.convert('blah.flac') }.should_not raise_error(ArgumentError)
39
- end
40
-
41
- it 'should check if the filename belongs to a regular file' do
42
- filename = 'blah.flac'
43
- FileTest.expects(:file?).with(filename).returns(true)
44
- Flac2mp3.convert(filename)
45
- end
46
- end
47
-
48
- describe Flac2mp3, 'when converting and given a filename belonging to a regular file' do
49
- before :each do
50
- @filename = 'blah.flac'
51
- FileTest.stubs(:file?).with(@filename).returns(true)
52
- @output_filename = 'blah.mp3'
53
- Flac2mp3.stubs(:output_filename).with(@filename).returns(@output_filename)
54
- Flac2mp3.stubs(:system)
55
-
56
- @filename.stubs(:safequote).returns('-blah-flac-')
57
- @output_filename.stubs(:safequote).returns('-blah-mp3-')
58
-
59
- @flacdata = {}
60
- Flac2mp3.stubs(:flacdata).with(@filename).returns(@flacdata)
61
- Flac2mp3.stubs(:mp3data)
62
- end
63
-
64
- it 'should not error' do
65
- lambda { Flac2mp3.convert(@filename) }.should_not raise_error(TypeError)
66
- end
67
-
68
- it 'should extend the filename with the string extensions' do
69
- @filename.expects(:extend).with(Flac2mp3::StringExtensions).returns(@filename)
70
- Flac2mp3.convert(@filename)
71
- end
72
-
73
- it 'should get the output filename' do
74
- Flac2mp3.expects(:output_filename).with(@filename).returns('outfile')
75
- Flac2mp3.convert(@filename)
76
- end
77
-
78
- it 'should extend the output filename with the string extensions' do
79
- @output_filename.expects(:extend).with(Flac2mp3::StringExtensions).returns(@output_filename)
80
- Flac2mp3.convert(@filename)
81
- end
82
-
83
- it 'should use system commands to convert the FLAC to an MP3' do
84
- Flac2mp3.expects(:system).with("flac --stdout --decode #{@filename.safequote} | lame --preset standard - #{@output_filename.safequote}")
85
- Flac2mp3.convert(@filename)
86
- end
87
-
88
- it 'should set the MP3 tags from the FLAC data' do
89
- Flac2mp3.expects(:mp3data).with(@output_filename, @flacdata)
90
- Flac2mp3.convert(@filename)
91
- end
92
-
93
- it 'should accept an option to delete the flac' do
94
- lambda { Flac2mp3.convert(@filename, :delete => true) }.should_not raise_error(ArgumentError)
95
- end
96
-
97
- it 'should delete the original file if given a true value for the option' do
98
- File.expects(:delete).with(@filename)
99
- Flac2mp3.convert(@filename, :delete => true)
100
- end
101
-
102
- it 'should not delete the original file if given a false value for the option' do
103
- File.expects(:delete).never
104
- Flac2mp3.convert(@filename, :delete => false)
105
- end
106
-
107
- it 'should not delete the original file by default' do
108
- File.expects(:delete).never
109
- Flac2mp3.convert(@filename)
110
- end
111
-
112
- it 'should accept an option to run silently' do
113
- lambda { Flac2mp3.convert(@filename, :silent => true) }.should_not raise_error(ArgumentError)
8
+ describe 'when initialized' do
9
+ before :each do
10
+ @options = { :silent => true, :delete => false }
11
+ end
12
+
13
+ it 'should accept options' do
14
+ lambda { Flac2mp3.new(@options) }.should_not raise_error(ArgumentError)
15
+ end
16
+
17
+ it 'should not require options' do
18
+ lambda { Flac2mp3.new }.should_not raise_error(ArgumentError)
19
+ end
20
+
21
+ it 'should load the configuration' do
22
+ Flac2mp3.any_instance.expects(:load_config)
23
+ Flac2mp3.new
24
+ end
25
+
26
+ it 'should set the options' do
27
+ Flac2mp3.any_instance.expects(:set_options).with(@options)
28
+ Flac2mp3.new(@options)
29
+ end
30
+
31
+ it 'should default to empty options' do
32
+ Flac2mp3.any_instance.expects(:set_options).with({})
33
+ Flac2mp3.new
34
+ end
114
35
  end
115
36
 
116
- it 'should tell the system commands to be silent if given a true value for the option' do
117
- Flac2mp3.expects(:system).with("flac --silent --stdout --decode #{@filename.safequote} | lame --silent --preset standard - #{@output_filename.safequote}")
118
- Flac2mp3.convert(@filename, :silent => true)
37
+ it 'should load the configuration' do
38
+ @flac2mp3.should respond_to(:load_config)
119
39
  end
120
40
 
121
- it 'should not tell the system commands to be silent if given a true value for the option' do
122
- Flac2mp3.expects(:system).with("flac --stdout --decode #{@filename.safequote} | lame --preset standard - #{@output_filename.safequote}")
123
- Flac2mp3.convert(@filename, :silent => false)
41
+ describe 'loading the configuration' do
42
+ it 'should look for a config file' do
43
+ File.expects(:read).with(File.expand_path('~/.flac2mp3')).returns('')
44
+ @flac2mp3.load_config
45
+ end
46
+
47
+ describe 'when a config file is found' do
48
+ before :each do
49
+ @config = { :silent => true, :delete => false }
50
+ @contents = @config.to_yaml
51
+ File.stubs(:read).returns(@contents)
52
+ end
53
+
54
+ it 'should parse the file as YAML' do
55
+ YAML.expects(:load).with(@contents)
56
+ @flac2mp3.load_config
57
+ end
58
+
59
+ it 'should store the config' do
60
+ @flac2mp3.load_config
61
+ @flac2mp3.config.should == @config
62
+ end
63
+
64
+ it 'should convert string keys to symbols' do
65
+ File.stubs(:read).returns({ 'silent' => true, 'delete' => false }.to_yaml)
66
+ @flac2mp3.load_config
67
+ @flac2mp3.config.should == @config
68
+ end
69
+
70
+ it 'should handle an empty file' do
71
+ File.stubs(:read).returns('')
72
+ @flac2mp3.load_config
73
+ @flac2mp3.config.should == {}
74
+ end
75
+
76
+ it 'should not allow changes to the config' do
77
+ @flac2mp3.load_config
78
+ @flac2mp3.config[:some_key] = 'some value'
79
+ @flac2mp3.config.should == @config
80
+ end
81
+ end
82
+
83
+ describe 'when no config file is found' do
84
+ before :each do
85
+ File.stubs(:read).raises(Errno::ENOENT)
86
+ end
87
+
88
+ it 'should store an empty config' do
89
+ Flac2mp3.new.config.should == {}
90
+ end
91
+ end
124
92
  end
125
93
 
126
- it 'should not tell the system commands to be silent by default' do
127
- Flac2mp3.expects(:system).with("flac --stdout --decode #{@filename.safequote} | lame --preset standard - #{@output_filename.safequote}")
128
- Flac2mp3.convert(@filename)
94
+ it 'should set options' do
95
+ @flac2mp3.should respond_to(:set_options)
129
96
  end
130
97
 
131
- it 'should accept an option for encoding options' do
132
- lambda { Flac2mp3.convert(@filename, :encoding => '--preset fast standard') }.should_not raise_error(ArgumentError)
98
+ describe 'setting options' do
99
+ before :each do
100
+ @options = { :silent => true, :delete => false }
101
+ end
102
+
103
+ it 'should accept options' do
104
+ lambda { @flac2mp3.set_options(:silent => true) }.should_not raise_error(ArgumentError)
105
+ end
106
+
107
+ it 'should require options' do
108
+ lambda { @flac2mp3.set_options }.should raise_error(ArgumentError)
109
+ end
110
+
111
+ it 'should accept a hash of options' do
112
+ lambda { @flac2mp3.set_options(:silent => true) }.should_not raise_error(TypeError)
113
+ end
114
+
115
+ it 'should require a hash of options' do
116
+ lambda { @flac2mp3.set_options('silent') }.should raise_error(TypeError)
117
+ end
118
+
119
+ it 'should store the options' do
120
+ @flac2mp3.set_options(@options)
121
+ @flac2mp3.options.should == @options
122
+ end
123
+
124
+ it 'should not allow changes to the options' do
125
+ @flac2mp3.set_options(@options.dup)
126
+ @flac2mp3.options[:some_key] = 'some value'
127
+ @flac2mp3.options.should == @options
128
+ end
129
+ end
130
+
131
+ describe 'querying options' do
132
+ it 'should indicate the original file should be deleted when a true option is given' do
133
+ @flac2mp3.set_options(:delete => true)
134
+ @flac2mp3.delete?.should be(true)
135
+ end
136
+
137
+ it 'should indicate the original file should not be deleted when a false option is given' do
138
+ @flac2mp3.set_options(:delete => false)
139
+ @flac2mp3.delete?.should be(false)
140
+ end
141
+
142
+ it 'should indicate the original file should not be deleted when no option is given' do
143
+ @flac2mp3.set_options({})
144
+ @flac2mp3.delete?.should be(false)
145
+ end
146
+
147
+ it 'should indicate the conversion should be silent when a true option is given' do
148
+ @flac2mp3.set_options(:silent => true)
149
+ @flac2mp3.silent?.should be(true)
150
+ end
151
+
152
+ it 'should indicate the conversion should not be silent when a false option is given' do
153
+ @flac2mp3.set_options(:silent => false)
154
+ @flac2mp3.silent?.should be(false)
155
+ end
156
+
157
+ it 'should indicate the conversion should not be silent when no option is given' do
158
+ @flac2mp3.set_options({})
159
+ @flac2mp3.silent?.should be(false)
160
+ end
161
+
162
+ it 'should store the given encoding' do
163
+ encoding = '-VAWESOME'
164
+ @flac2mp3.set_options(:encoding => encoding)
165
+ @flac2mp3.encoding.should == encoding
166
+ end
167
+
168
+ it 'should default the encoding to --preset standard' do
169
+ @flac2mp3.set_options({})
170
+ @flac2mp3.encoding.should == '--preset standard'
171
+ end
172
+
173
+ it 'should use values from the configuration' do
174
+ config = {:silent => true}
175
+ File.stubs(:read).returns(config.to_yaml)
176
+ Flac2mp3.new.silent?.should be(true)
177
+ end
178
+
179
+ it 'should override configuration values with options' do
180
+ config = {:silent => true}
181
+ File.stubs(:read).returns(config.to_yaml)
182
+ Flac2mp3.new(:silent => false).silent?.should be(false)
183
+ end
184
+
185
+ it 'should combine configuration and option values' do
186
+ config = {:silent => true}
187
+ File.stubs(:read).returns(config.to_yaml)
188
+ flac2mp3 = Flac2mp3.new(:delete => true)
189
+
190
+ flac2mp3.silent?.should be(true)
191
+ flac2mp3.delete?.should be(true)
192
+ end
133
193
  end
134
194
 
135
- it 'should use the encoding options if given' do
136
- Flac2mp3.expects(:system).with("flac --stdout --decode #{@filename.safequote} | lame --vbr-new -V2 -h - #{@output_filename.safequote}")
137
- Flac2mp3.convert(@filename, :encoding => '--vbr-new -V2 -h')
195
+ it 'should convert' do
196
+ @flac2mp3.should respond_to(:convert)
138
197
  end
139
198
 
140
- it 'should default the encoding to --preset standard if no encoding options given' do
141
- Flac2mp3.expects(:system).with("flac --stdout --decode #{@filename.safequote} | lame --preset standard - #{@output_filename.safequote}")
142
- Flac2mp3.convert(@filename)
199
+ describe 'when converting' do
200
+ before :each do
201
+ @filename = 'test.flac'
202
+ @flac2mp3.stubs(:process_conversion)
203
+ end
204
+
205
+ it 'should accept a filename' do
206
+ lambda { @flac2mp3.convert(@filename) }.should_not raise_error(ArgumentError)
207
+ end
208
+
209
+ it 'should require a filename' do
210
+ lambda { @flac2mp3.convert }.should raise_error(ArgumentError)
211
+ end
212
+
213
+ it 'should check if the filename belongs to a regular file' do
214
+ FileTest.expects(:file?).with(@filename).returns(true)
215
+ @flac2mp3.convert(@filename)
216
+ end
217
+
218
+ describe 'when given a filename belonging to a regular file' do
219
+ before :each do
220
+ FileTest.stubs(:file?).returns(true)
221
+ end
222
+
223
+ it 'should not error' do
224
+ lambda { @flac2mp3.convert(@filename) }.should_not raise_error(TypeError)
225
+ end
226
+
227
+ it 'should process the conversion' do
228
+ @flac2mp3.expects(:process_conversion).with(@filename)
229
+ @flac2mp3.convert(@filename)
230
+ end
231
+
232
+ it 'should check if the original file should be deleted' do
233
+ @flac2mp3.expects(:delete?)
234
+ @flac2mp3.convert(@filename)
235
+ end
236
+
237
+ describe 'when the original file should be deleted' do
238
+ before :each do
239
+ @flac2mp3.stubs(:delete?).returns(true)
240
+ end
241
+
242
+ it 'should delete the original file' do
243
+ File.expects(:delete).with(@filename)
244
+ @flac2mp3.convert(@filename)
245
+ end
246
+ end
247
+
248
+ describe 'when the original file should not be deleted' do
249
+ before :each do
250
+ @flac2mp3.stubs(:delete?).returns(false)
251
+ end
252
+
253
+ it 'should not delete the original file' do
254
+ File.expects(:delete).never
255
+ @flac2mp3.convert(@filename)
256
+ end
257
+ end
258
+ end
259
+
260
+ describe 'when given a filename not belonging to a regular file' do
261
+ before :each do
262
+ FileTest.stubs(:file?).returns(false)
263
+ end
264
+
265
+ it 'should error' do
266
+ lambda { @flac2mp3.convert(@filename) }.should raise_error(TypeError)
267
+ end
268
+ end
269
+ end
270
+
271
+ it 'should process conversion' do
272
+ @flac2mp3.should respond_to(:process_conversion)
273
+ end
274
+
275
+ describe 'when processing conversion' do
276
+ before :each do
277
+ @filename = 'test.flac'
278
+ @out_filename = 'test.mp3'
279
+ @flac2mp3.stubs(:output_filename).returns(@out_filename)
280
+ @flac2mp3.stubs(:convert_data)
281
+ @flac2mp3.stubs(:convert_metadata)
282
+ end
283
+
284
+ it 'should accept a filename' do
285
+ lambda { @flac2mp3.process_conversion(@filename) }.should_not raise_error(ArgumentError)
286
+ end
287
+
288
+ it 'should require a filename' do
289
+ lambda { @flac2mp3.process_conversion }.should raise_error(ArgumentError)
290
+ end
291
+
292
+ it 'get the output filename from the given filename' do
293
+ @flac2mp3.expects(:output_filename).with(@filename)
294
+ @flac2mp3.process_conversion(@filename)
295
+ end
296
+
297
+ it 'should convert data' do
298
+ @flac2mp3.expects(:convert_data).with(@filename, @out_filename)
299
+ @flac2mp3.process_conversion(@filename)
300
+ end
301
+
302
+ it 'should convert metadata' do
303
+ @flac2mp3.expects(:convert_metadata).with(@filename, @out_filename)
304
+ @flac2mp3.process_conversion(@filename)
305
+ end
143
306
  end
144
307
 
145
- it 'should default the encoding to --preset standard if nil encoding options given' do
146
- Flac2mp3.expects(:system).with("flac --stdout --decode #{@filename.safequote} | lame --preset standard - #{@output_filename.safequote}")
147
- Flac2mp3.convert(@filename, :encoding => nil)
308
+ it 'should provide an output filename' do
309
+ @flac2mp3.should respond_to(:output_filename)
148
310
  end
149
311
 
150
- it 'should default the encoding to --preset standard if blank encoding options given' do
151
- Flac2mp3.expects(:system).with("flac --stdout --decode #{@filename.safequote} | lame --preset standard - #{@output_filename.safequote}")
152
- Flac2mp3.convert(@filename, :encoding => ' ')
153
- end
154
- end
312
+ describe 'providing an output filename' do
313
+ it 'should accept a filename' do
314
+ lambda { @flac2mp3.output_filename('blah.flac') }.should_not raise_error(ArgumentError)
315
+ end
155
316
 
156
- describe Flac2mp3, 'when converting and given a filename not belonging to a regular file' do
157
- before :each do
158
- @filename = 'blah.flac'
159
- FileTest.stubs(:file?).with(@filename).returns(false)
160
- end
161
-
162
- it 'should error' do
163
- lambda { Flac2mp3.convert(@filename) }.should raise_error(TypeError)
164
- end
165
- end
317
+ it 'should require a filename' do
318
+ lambda { @flac2mp3.output_filename }.should raise_error(ArgumentError)
319
+ end
166
320
 
167
- describe Flac2mp3, 'when getting an output filename' do
168
- it 'should require a filename' do
169
- lambda { Flac2mp3.output_filename }.should raise_error(ArgumentError)
170
- end
171
-
172
- it 'should accept a filename' do
173
- lambda { Flac2mp3.output_filename('blah.flac') }.should_not raise_error(ArgumentError)
174
- end
175
-
176
- it 'should convert a .flac extension to an .mp3 extension' do
177
- Flac2mp3.output_filename('blah.flac').should == 'blah.mp3'
178
- end
179
-
180
- it 'should append an .mp3 extension if no .flac extension exists' do
181
- Flac2mp3.output_filename('blah').should == 'blah.mp3'
182
- end
183
- end
321
+ it 'should convert a .flac extension to an .mp3 extension' do
322
+ @flac2mp3.output_filename('blah.flac').should == 'blah.mp3'
323
+ end
184
324
 
185
- describe Flac2mp3, 'providing a mapping of tags' do
186
- it 'should return a hash' do
187
- Flac2mp3.tag_mapping.should be_kind_of(Hash)
188
- end
189
-
190
- it "should map 'album' to 'album'" do
191
- Flac2mp3.tag_mapping[:album].should == :album
192
- end
193
-
194
- it "should map 'artist' to 'artist'" do
195
- Flac2mp3.tag_mapping[:artist].should == :artist
196
- end
197
-
198
- it "should map 'bpm' to 'TBPM'" do
199
- Flac2mp3.tag_mapping[:bpm].should == :TBPM
200
- end
201
-
202
- it "should map 'description' to 'comments'" do
203
- Flac2mp3.tag_mapping[:description].should == :comments
204
- end
205
-
206
- it "should map 'composer' to 'TCOM'" do
207
- Flac2mp3.tag_mapping[:composer].should == :TCOM
208
- end
209
-
210
- it "should map 'date' to 'year'" do
211
- Flac2mp3.tag_mapping[:date].should == :year
325
+ it 'should append an .mp3 extension if no .flac extension exists' do
326
+ @flac2mp3.output_filename('blah').should == 'blah.mp3'
327
+ end
212
328
  end
213
329
 
214
- it "should map 'genre' to 'genre_s'" do
215
- Flac2mp3.tag_mapping[:genre].should == :genre_s
330
+ it 'should convert data' do
331
+ @flac2mp3.should respond_to(:convert_data)
216
332
  end
217
333
 
218
- it "should map 'title' to 'title'" do
219
- Flac2mp3.tag_mapping[:title].should == :title
220
- end
221
-
222
- it "should map 'tracknumber' to 'TRCK'" do
223
- Flac2mp3.tag_mapping[:tracknumber].should == :TRCK
334
+ describe 'when converting data' do
335
+ before :each do
336
+ @filename = 'test.flac'
337
+ @out_filename = 'test.mp3'
338
+ @flac_command = 'flac command'
339
+ @mp3_command = 'mp3 command'
340
+ @flac2mp3.stubs(:flac_command).returns(@flac_command)
341
+ @flac2mp3.stubs(:mp3_command).returns(@mp3_command)
342
+ @flac2mp3.stubs(:system)
343
+ end
344
+
345
+ it 'should accept a filename and an output filename' do
346
+ lambda { @flac2mp3.convert_data(@filename, @out_filename) }.should_not raise_error(ArgumentError)
347
+ end
348
+
349
+ it 'should require an output filename' do
350
+ lambda { @flac2mp3.convert_data(@filename) }.should raise_error(ArgumentError)
351
+ end
352
+
353
+ it 'should require a filename' do
354
+ lambda { @flac2mp3.convert_data }.should raise_error(ArgumentError)
355
+ end
356
+
357
+ it 'should call the flac command with the given filename' do
358
+ @flac2mp3.expects(:flac_command).with(@filename)
359
+ @flac2mp3.convert_data(@filename, @out_filename)
360
+ end
361
+
362
+ it 'should call the mp3 command with the given output filename' do
363
+ @flac2mp3.expects(:mp3_command).with(@out_filename)
364
+ @flac2mp3.convert_data(@filename, @out_filename)
365
+ end
366
+
367
+ it 'should shell out to the system with the flac and mp3 commands' do
368
+ @flac2mp3.expects(:system).with("#{@flac_command} | #{@mp3_command}")
369
+ @flac2mp3.convert_data(@filename, @out_filename)
370
+ end
224
371
  end
225
372
 
226
- it "should map 'tracktotal' to 'TRCK'" do
227
- Flac2mp3.tag_mapping[:tracktotal].should == :TRCK
373
+ it 'should provide a flac command' do
374
+ @flac2mp3.should respond_to(:flac_command)
228
375
  end
229
376
 
230
- it "should map 'discnumber' to 'TPOS'" do
231
- Flac2mp3.tag_mapping[:discnumber].should == :TPOS
377
+ describe 'when providing a flac command' do
378
+ before :each do
379
+ @filename = 'test.flac'
380
+ @safe_filename = 'safetest.safeflac'
381
+ @flac2mp3.stubs(:safequote).returns(@safe_filename)
382
+ @flac2mp3.stubs(:silent?)
383
+ end
384
+
385
+ it 'should accept a filename' do
386
+ lambda { @flac2mp3.flac_command(@filename) }.should_not raise_error(ArgumentError)
387
+ end
388
+
389
+ it 'should require a filename' do
390
+ lambda { @flac2mp3.flac_command }.should raise_error(ArgumentError)
391
+ end
392
+
393
+ it 'should safequote the filename' do
394
+ @flac2mp3.expects(:safequote).with(@filename)
395
+ @flac2mp3.flac_command(@filename)
396
+ end
397
+
398
+ it 'should check if the command should be silent' do
399
+ @flac2mp3.expects(:silent?)
400
+ @flac2mp3.flac_command(@filename)
401
+ end
402
+
403
+ describe 'when the command should be silent' do
404
+ before :each do
405
+ @flac2mp3.stubs(:silent?).returns(true)
406
+ end
407
+
408
+ it 'should provide a flac shell command that will be silent' do
409
+ @flac2mp3.flac_command(@filename).should == "flac --silent --stdout --decode #{@safe_filename}"
410
+ end
411
+ end
412
+
413
+ describe 'when the command should not be silent' do
414
+ before :each do
415
+ @flac2mp3.stubs(:silent?).returns(false)
416
+ end
417
+
418
+ it 'should provide a flac shell command that will not be silent' do
419
+ @flac2mp3.flac_command(@filename).should == "flac --stdout --decode #{@safe_filename}"
420
+ end
421
+ end
422
+ end
423
+
424
+ it 'should provide an mp3 command' do
425
+ @flac2mp3.should respond_to(:mp3_command)
426
+ end
427
+
428
+ describe 'when providing an mp3 command' do
429
+ before :each do
430
+ @filename = 'test.mp3'
431
+ @safe_filename = 'safetest.safemp3'
432
+ @flac2mp3.stubs(:safequote).returns(@safe_filename)
433
+ @flac2mp3.stubs(:silent?)
434
+ @encoding = '--VAWESOME'
435
+ @flac2mp3.stubs(:encoding).returns(@encoding)
436
+ end
437
+
438
+ it 'should accept a filename' do
439
+ lambda { @flac2mp3.mp3_command(@filename) }.should_not raise_error(ArgumentError)
440
+ end
441
+
442
+ it 'should require a filename' do
443
+ lambda { @flac2mp3.mp3_command }.should raise_error(ArgumentError)
444
+ end
445
+
446
+ it 'should safequote the filename' do
447
+ @flac2mp3.expects(:safequote).with(@filename)
448
+ @flac2mp3.mp3_command(@filename)
449
+ end
450
+
451
+ it 'should check if the command should be silent' do
452
+ @flac2mp3.expects(:silent?)
453
+ @flac2mp3.mp3_command(@filename)
454
+ end
455
+
456
+ it 'should check the encoding to use' do
457
+ @flac2mp3.expects(:encoding)
458
+ @flac2mp3.mp3_command(@filename)
459
+ end
460
+
461
+ describe 'when the command should be silent' do
462
+ before :each do
463
+ @flac2mp3.stubs(:silent?).returns(true)
464
+ end
465
+
466
+ it 'should provide an mp3 shell command that will be silent' do
467
+ @flac2mp3.mp3_command(@filename).should == "lame --silent #{@encoding} - #{@safe_filename}"
468
+ end
469
+ end
470
+
471
+ describe 'when the command should not be silent' do
472
+ before :each do
473
+ @flac2mp3.stubs(:silent?).returns(false)
474
+ end
475
+
476
+ it 'should provide an mp3 shell command that will not be silent' do
477
+ @flac2mp3.mp3_command(@filename).should == "lame #{@encoding} - #{@safe_filename}"
478
+ end
479
+ end
232
480
  end
233
481
 
234
- it "should map 'disctotal' to 'TPOS'" do
235
- Flac2mp3.tag_mapping[:disctotal].should == :TPOS
482
+ it 'should quote filenames safely' do
483
+ @flac2mp3.should respond_to(:safequote)
236
484
  end
237
485
 
238
- it "should map 'compilation' to 'TCMP'" do
239
- Flac2mp3.tag_mapping[:compilation].should == :TCMP
240
- end
241
- end
486
+ describe 'when quoting a filename safely' do
487
+ it 'should accept a filename' do
488
+ lambda { @flac2mp3.safequote('test.flac') }.should_not raise_error(ArgumentError)
489
+ end
490
+
491
+ it 'should require a filename' do
492
+ lambda { @flac2mp3.safequote }.should raise_error(ArgumentError)
493
+ end
494
+
495
+ it 'should leave alphanumeric characters alone' do
496
+ @flac2mp3.safequote('abc_123').should == 'abc_123'
497
+ end
242
498
 
243
- describe Flac2mp3, 'when getting FLAC tag data' do
244
- before :each do
245
- @filename = 'blah.flac'
246
- @tags = {}
247
- @flacinfo = stub('flacinfo', :tags => @tags)
248
- FlacInfo.stubs(:new).with(@filename).returns(@flacinfo)
499
+ it 'should escape non-alphanumeric characters' do
500
+ @flac2mp3.safequote(%q[a-b"c 12'3]).should == %q[a\-b\"c\ 12\'3]
501
+ end
249
502
  end
250
503
 
251
- it 'should require a filename' do
252
- lambda { Flac2mp3.flacdata }.should raise_error(ArgumentError)
504
+ it 'should convert metadata' do
505
+ @flac2mp3.should respond_to(:convert_metadata)
253
506
  end
254
507
 
255
- it 'should accept a filename' do
256
- lambda { Flac2mp3.flacdata('blah.flac') }.should_not raise_error(ArgumentError)
257
- end
258
-
259
- it 'should create a FlacInfo object' do
260
- FlacInfo.expects(:new).with(@filename).returns(@flacinfo)
261
- Flac2mp3.flacdata(@filename)
262
- end
263
-
264
- it 'should use the FlacInfo object tags' do
265
- @flacinfo.expects(:tags).returns(@tags)
266
- Flac2mp3.flacdata(@filename)
267
- end
268
-
269
- it 'should return a hash of the tag data' do
270
- @tags[:artist] = 'blah'
271
- @tags[:blah] = 'boo'
272
- @tags[:comment] = 'hey'
273
-
274
- data = Flac2mp3.flacdata(@filename)
275
- data[:artist].should == 'blah'
276
- data[:blah].should == 'boo'
277
- data[:comment].should == 'hey'
278
- end
279
-
280
- it 'should convert tags to symbols' do
281
- @tags['artist'] = 'blah'
282
- @tags['blah'] = 'boo'
283
- @tags['comment'] = 'hey'
284
-
285
- data = Flac2mp3.flacdata(@filename)
286
- data[:artist].should == 'blah'
287
- data[:blah].should == 'boo'
288
- data[:comment].should == 'hey'
289
-
290
- data.should_not have_key('artist')
291
- data.should_not have_key('blah')
292
- data.should_not have_key('comment')
293
- end
294
-
295
- it 'should convert tags to lowercase' do
296
- @tags['Artist'] = 'blah'
297
- @tags[:BLAH] = 'boo'
298
- @tags['cOmMeNt'] = 'hey'
299
-
300
- data = Flac2mp3.flacdata(@filename)
301
- data[:artist].should == 'blah'
302
- data[:blah].should == 'boo'
303
- data[:comment].should == 'hey'
304
-
305
- data.should_not have_key('Artist')
306
- data.should_not have_key(:BLAH)
307
- data.should_not have_key('cOmMeNt')
308
- end
309
-
310
- it 'should convert values consisting only of digits to actual numbers' do
311
- @tags[:track] = '12'
508
+ describe 'when converting metadata' do
509
+ before :each do
510
+ @filename = 'test.flac'
511
+ @out_filename = 'test.mp3'
512
+ @flacdata = stub('flacdata')
513
+ @flac2mp3.stubs(:get_flacdata).returns(@flacdata)
514
+ @flac2mp3.stubs(:set_mp3data)
515
+ end
312
516
 
313
- data = Flac2mp3.flacdata(@filename)
314
- data[:track].should == 12
315
- end
316
-
317
- it 'should leave numeric titles as strings' do
318
- @tags[:title] = '45' # This was my first run-in with this problem, the opening track on Elvis Costello's /When I Was Cruel/
517
+ it 'should accept a filename and an output filename' do
518
+ lambda { @flac2mp3.convert_metadata(@filename, @out_filename) }.should_not raise_error(ArgumentError)
519
+ end
319
520
 
320
- data = Flac2mp3.flacdata(@filename)
321
- data[:title].should == '45'
322
- end
323
-
324
- it 'should leave numeric titles as strings even if the title key is not a simple downcased symbol' do
325
- @tags['TITLE'] = '45'
521
+ it 'should require an output filename' do
522
+ lambda { @flac2mp3.convert_metadata(@filename) }.should raise_error(ArgumentError)
523
+ end
326
524
 
327
- data = Flac2mp3.flacdata(@filename)
328
- data[:title].should == '45'
329
- end
330
-
331
- it 'should leave numeric descriptions as strings' do
332
- @tags[:description] = '1938' # This was my first run-in with this problem, from the Boilermakers' version of "Minor Swing" where for the description all I had was the year of the original
525
+ it 'should require a filename' do
526
+ lambda { @flac2mp3.convert_metadata }.should raise_error(ArgumentError)
527
+ end
333
528
 
334
- data = Flac2mp3.flacdata(@filename)
335
- data[:description].should == '1938'
336
- end
337
-
338
- it 'should leave numeric descriptions as strings even if the description key is not a simple downcased symbol' do
339
- @tags['DESCRIPTION'] = '1938'
529
+ it 'should get the flac metadata' do
530
+ @flac2mp3.expects(:get_flacdata).with(@filename)
531
+ @flac2mp3.convert_metadata(@filename, @out_filename)
532
+ end
340
533
 
341
- data = Flac2mp3.flacdata(@filename)
342
- data[:description].should == '1938'
343
- end
344
- end
345
-
346
- describe Flac2mp3, 'when setting MP3 tag data' do
347
- before :each do
348
- @filename = 'blah.mp3'
349
- @tags = {}
350
- @mp3tags = stub('mp3info tags')
351
- @mp3tags2 = stub('mp3info tags 2')
352
- @mp3info = stub('mp3info obj', :tag => @mp3tags, :tag2 => @mp3tags2)
353
- Mp3Info.stubs(:open).with(@filename).yields(@mp3info)
354
- end
355
-
356
- it 'should require a filename' do
357
- lambda { Flac2mp3.mp3data }.should raise_error(ArgumentError)
358
- end
359
-
360
- it 'should require tag data' do
361
- lambda { Flac2mp3.mp3data('blah.mp3') }.should raise_error(ArgumentError)
534
+ it 'should set the mp3 metadata with the flac metadata' do
535
+ @flac2mp3.expects(:set_mp3data).with(@out_filename, @flacdata)
536
+ @flac2mp3.convert_metadata(@filename, @out_filename)
537
+ end
362
538
  end
363
539
 
364
- it 'should accept a filename and tag data' do
365
- lambda { Flac2mp3.mp3data('blah.mp3', 'tags') }.should_not raise_error(ArgumentError)
540
+ it 'should get flac metadata' do
541
+ @flac2mp3.should respond_to(:get_flacdata)
366
542
  end
367
543
 
368
- it 'should require a hash of tags' do
369
- lambda { Flac2mp3.mp3data('blah.mp3', 'blah') }.should raise_error(TypeError)
370
- end
371
-
372
- it 'should accept a hash of tags' do
373
- lambda { Flac2mp3.mp3data('blah.mp3', {}) }.should_not raise_error(TypeError)
374
- end
375
-
376
- it 'should use an Mp3Info object' do
377
- Mp3Info.expects(:open).with(@filename).yields(@mp3info)
378
- Flac2mp3.mp3data(@filename, @tags)
379
- end
380
-
381
- it 'should set tags in the Mp3Info object' do
382
- @tags[:album] = 'blah'
383
- @tags[:artist] = 'boo'
384
- @tags[:genre] = 'bang'
544
+ describe 'when getting flac metadata' do
545
+ before :each do
546
+ @filename = 'test.flac'
547
+ @tags = {}
548
+ @flacinfo = stub('flacinfo', :tags => @tags)
549
+ FlacInfo.stubs(:new).returns(@flacinfo)
550
+ end
385
551
 
386
- @mp3tags.expects(:album=).with(@tags[:album])
387
- @mp3tags.expects(:artist=).with(@tags[:artist])
388
- @mp3tags.expects(:genre_s=).with(@tags[:genre])
552
+ it 'should accept a filename' do
553
+ lambda { @flac2mp3.get_flacdata(@filename) }.should_not raise_error(ArgumentError)
554
+ end
389
555
 
390
- Flac2mp3.mp3data(@filename, @tags)
391
- end
392
-
393
- it 'should not set tags not given' do
394
- @tags[:album] = 'blah'
395
- @tags[:artist] = 'boo'
396
- @tags[:genre] = 'bang'
556
+ it 'should require a filename' do
557
+ lambda { @flac2mp3.get_flacdata }.should raise_error(ArgumentError)
558
+ end
397
559
 
398
- @mp3tags.stubs(:album=)
399
- @mp3tags.stubs(:artist=)
400
- @mp3tags.stubs(:genre_s=)
560
+ it 'should create a FlacInfo object' do
561
+ FlacInfo.expects(:new).with(@filename).returns(@flacinfo)
562
+ @flac2mp3.get_flacdata(@filename)
563
+ end
564
+
565
+ it 'should use the FlacInfo object tags' do
566
+ @flacinfo.expects(:tags).returns(@tags)
567
+ @flac2mp3.get_flacdata(@filename)
568
+ end
401
569
 
402
- @mp3tags.expects(:comments=).never
403
- @mp3tags.expects(:year=).never
570
+ it 'should return a hash of the tag data' do
571
+ @tags[:artist] = 'blah'
572
+ @tags[:blah] = 'boo'
573
+ @tags[:comment] = 'hey'
574
+
575
+ data = @flac2mp3.get_flacdata(@filename)
576
+ data[:artist].should == 'blah'
577
+ data[:blah].should == 'boo'
578
+ data[:comment].should == 'hey'
579
+ end
404
580
 
405
- Flac2mp3.mp3data(@filename, @tags)
406
- end
407
-
408
- it 'should not set tags not known' do
409
- @tags[:blah] = 'blah'
410
- @tags[:bang] = 'bang'
581
+ it 'should convert tags to symbols' do
582
+ @tags['artist'] = 'blah'
583
+ @tags['blah'] = 'boo'
584
+ @tags['comment'] = 'hey'
585
+
586
+ data = @flac2mp3.get_flacdata(@filename)
587
+ data[:artist].should == 'blah'
588
+ data[:blah].should == 'boo'
589
+ data[:comment].should == 'hey'
590
+
591
+ data.should_not have_key('artist')
592
+ data.should_not have_key('blah')
593
+ data.should_not have_key('comment')
594
+ end
411
595
 
412
- @mp3tags.expects(:blah=).never
413
- @mp3tags.expects(:bang=).never
596
+ it 'should convert tags to lowercase' do
597
+ @tags['Artist'] = 'blah'
598
+ @tags[:BLAH] = 'boo'
599
+ @tags['cOmMeNt'] = 'hey'
600
+
601
+ data = @flac2mp3.get_flacdata(@filename)
602
+ data[:artist].should == 'blah'
603
+ data[:blah].should == 'boo'
604
+ data[:comment].should == 'hey'
605
+
606
+ data.should_not have_key('Artist')
607
+ data.should_not have_key(:BLAH)
608
+ data.should_not have_key('cOmMeNt')
609
+ end
414
610
 
415
- Flac2mp3.mp3data(@filename, @tags)
416
- end
417
-
418
- it 'should use tag2 for bpm' do
419
- @tags[:bpm] = '5'
611
+ it 'should convert values consisting only of digits to actual numbers' do
612
+ @tags[:track] = '12'
613
+
614
+ data = @flac2mp3.get_flacdata(@filename)
615
+ data[:track].should == 12
616
+ end
420
617
 
421
- @mp3tags2.expects(:TBPM=).with(@tags[:bpm])
618
+ it 'should leave numeric values as numbers' do
619
+ @tags[:track] = 12
620
+
621
+ data = @flac2mp3.get_flacdata(@filename)
622
+ data[:track].should == 12
623
+ end
422
624
 
423
- Flac2mp3.mp3data(@filename, @tags)
625
+ it 'should leave numeric titles as strings' do
626
+ @tags[:title] = '45' # This was my first run-in with this problem, the opening track on Elvis Costello's /When I Was Cruel/
627
+
628
+ data = @flac2mp3.get_flacdata(@filename)
629
+ data[:title].should == '45'
630
+ end
631
+
632
+ it 'should leave numeric titles as strings even if the title key is not a simple downcased symbol' do
633
+ @tags['TITLE'] = '45'
634
+
635
+ data = @flac2mp3.get_flacdata(@filename)
636
+ data[:title].should == '45'
637
+ end
638
+
639
+ it 'should leave numeric descriptions as strings' do
640
+ @tags[:description] = '1938' # This was my first run-in with this problem, from the Boilermakers' version of "Minor Swing" where for the description all I had was the year of the original
641
+
642
+ data = @flac2mp3.get_flacdata(@filename)
643
+ data[:description].should == '1938'
644
+ end
645
+
646
+ it 'should leave numeric descriptions as strings even if the description key is not a simple downcased symbol' do
647
+ @tags['DESCRIPTION'] = '1938'
648
+
649
+ data = @flac2mp3.get_flacdata(@filename)
650
+ data[:description].should == '1938'
651
+ end
424
652
  end
425
653
 
426
- it 'should use tag2 for composer' do
427
- @tags[:composer] = 'Il Maestro'
428
-
429
- @mp3tags2.expects(:TCOM=).with(@tags[:composer])
430
-
431
- Flac2mp3.mp3data(@filename, @tags)
654
+ it 'should set mp3 metadata' do
655
+ @flac2mp3.should respond_to(:set_mp3data)
432
656
  end
433
657
 
434
- it 'should use tag2 for compilation' do
435
- @tags[:compilation] = '1'
658
+ describe 'when setting mp3 metadata' do
659
+ before :each do
660
+ @filename = 'test.mp3'
661
+ @tags = {}
662
+ @mp3tags = stub('mp3info tags')
663
+ @mp3tags2 = stub('mp3info tags 2')
664
+ @mp3info = stub('mp3info obj', :tag => @mp3tags, :tag2 => @mp3tags2)
665
+ Mp3Info.stubs(:open).yields(@mp3info)
666
+ end
436
667
 
437
- @mp3tags2.expects(:TCMP=).with(@tags[:compilation])
668
+ it 'should accept a filename and tag data' do
669
+ lambda { @flac2mp3.set_mp3data(@filename, 'tag data') }.should_not raise_error(ArgumentError)
670
+ end
438
671
 
439
- Flac2mp3.mp3data(@filename, @tags)
440
- end
441
-
442
- it 'should set tag2 track to be a combination of tracknumber and tracktotal' do
443
- @tags[:tracknumber] = 4
444
- @tags[:tracktotal] = 15
672
+ it 'should require tag data' do
673
+ lambda { @flac2mp3.set_mp3data(@filename) }.should raise_error(ArgumentError)
674
+ end
675
+
676
+ it 'should require a filename' do
677
+ lambda { @flac2mp3.set_mp3data }.should raise_error(ArgumentError)
678
+ end
679
+
680
+ it 'should accept a hash of tag data' do
681
+ lambda { @flac2mp3.set_mp3data(@filename, 'tag data') }.should raise_error(TypeError)
682
+ end
683
+
684
+ it 'should require a hash of tag data' do
685
+ lambda { @flac2mp3.set_mp3data(@filename, {}) }.should_not raise_error(TypeError)
686
+ end
445
687
 
446
- @mp3tags2.expects(:TRCK=).with('4/15')
688
+ it 'should use an Mp3Info object' do
689
+ Mp3Info.expects(:open).with(@filename)
690
+ @flac2mp3.set_mp3data(@filename, @tags)
691
+ end
447
692
 
448
- Flac2mp3.mp3data(@filename, @tags)
693
+ it 'should set tags in the Mp3Info object' do
694
+ @tags[:album] = 'blah'
695
+ @tags[:artist] = 'boo'
696
+ @tags[:genre] = 'bang'
697
+
698
+ @mp3tags.expects(:album=).with(@tags[:album])
699
+ @mp3tags.expects(:artist=).with(@tags[:artist])
700
+ @mp3tags.expects(:genre_s=).with(@tags[:genre])
701
+
702
+ @flac2mp3.set_mp3data(@filename, @tags)
703
+ end
704
+
705
+ it 'should not set tags not given' do
706
+ @tags[:album] = 'blah'
707
+ @tags[:artist] = 'boo'
708
+ @tags[:genre] = 'bang'
709
+
710
+ @mp3tags.stubs(:album=)
711
+ @mp3tags.stubs(:artist=)
712
+ @mp3tags.stubs(:genre_s=)
713
+
714
+ @mp3tags.expects(:comments=).never
715
+ @mp3tags.expects(:year=).never
716
+
717
+ @flac2mp3.set_mp3data(@filename, @tags)
718
+ end
719
+
720
+ it 'should not set tags not known' do
721
+ @tags[:blah] = 'blah'
722
+ @tags[:bang] = 'bang'
723
+
724
+ @mp3tags.expects(:blah=).never
725
+ @mp3tags.expects(:bang=).never
726
+
727
+ @flac2mp3.set_mp3data(@filename, @tags)
728
+ end
729
+
730
+ it 'should use tag2 for bpm' do
731
+ @tags[:bpm] = '5'
732
+
733
+ @mp3tags2.expects(:TBPM=).with(@tags[:bpm])
734
+
735
+ @flac2mp3.set_mp3data(@filename, @tags)
736
+ end
737
+
738
+ it 'should use tag2 for composer' do
739
+ @tags[:composer] = 'Il Maestro'
740
+
741
+ @mp3tags2.expects(:TCOM=).with(@tags[:composer])
742
+
743
+ @flac2mp3.set_mp3data(@filename, @tags)
744
+ end
745
+
746
+ it 'should use tag2 for compilation' do
747
+ @tags[:compilation] = '1'
748
+
749
+ @mp3tags2.expects(:TCMP=).with(@tags[:compilation])
750
+
751
+ @flac2mp3.set_mp3data(@filename, @tags)
752
+ end
753
+
754
+ it 'should set tag2 track to be a combination of tracknumber and tracktotal' do
755
+ @tags[:tracknumber] = 4
756
+ @tags[:tracktotal] = 15
757
+
758
+ @mp3tags2.expects(:TRCK=).with('4/15')
759
+
760
+ @flac2mp3.set_mp3data(@filename, @tags)
761
+ end
762
+
763
+ it "should set tag2 'pos' to be a combination of discnumber and disctotal" do
764
+ @tags[:discnumber] = 1
765
+ @tags[:disctotal] = 2
766
+
767
+ @mp3tags2.expects(:TPOS=).with('1/2')
768
+
769
+ @flac2mp3.set_mp3data(@filename, @tags)
770
+ end
449
771
  end
450
772
 
451
- it "should set tag2 'pos' to be a combination of discnumber and disctotal" do
452
- @tags[:discnumber] = 1
453
- @tags[:disctotal] = 2
773
+ describe 'as a class' do
774
+ it 'should convert' do
775
+ Flac2mp3.should respond_to(:convert)
776
+ end
454
777
 
455
- @mp3tags2.expects(:TPOS=).with('1/2')
778
+ describe 'when converting' do
779
+ before :each do
780
+ @filename = 'test.flac'
781
+ @options = { :silent => true, :delete => false, :fish => :flat }
782
+ @flac2mp3 = stub('flac2mp3 object', :convert => nil)
783
+ Flac2mp3.stubs(:new).returns(@flac2mp3)
784
+ end
785
+
786
+ it 'should accept a filename and a hash of options' do
787
+ lambda { Flac2mp3.convert(@filename, @options) }.should_not raise_error(ArgumentError)
788
+ end
789
+
790
+ it 'should not require options' do
791
+ lambda { Flac2mp3.convert(@filename) }.should_not raise_error(ArgumentError)
792
+ end
793
+
794
+ it 'should require a filename' do
795
+ lambda { Flac2mp3.convert }.should raise_error(ArgumentError)
796
+ end
797
+
798
+ it 'should instantiate a new Flac2mp3 object' do
799
+ Flac2mp3.expects(:new).returns(@flac2mp3)
800
+ Flac2mp3.convert(@filename)
801
+ end
802
+
803
+ it 'should pass the options when instantiating the Flac2mp3 object' do
804
+ Flac2mp3.expects(:new).with(@options).returns(@flac2mp3)
805
+ Flac2mp3.convert(@filename, @options)
806
+ end
807
+
808
+ it 'should use the Flac2mp3 object to convert the given file' do
809
+ @flac2mp3.expects(:convert).with(@filename)
810
+ Flac2mp3.convert(@filename)
811
+ end
812
+ end
456
813
 
457
- Flac2mp3.mp3data(@filename, @tags)
814
+ it 'should provide a tag mapping' do
815
+ Flac2mp3.should respond_to(:tag_mapping)
816
+ end
817
+
818
+ describe 'providing a tag mapping' do
819
+ it 'should return a hash' do
820
+ Flac2mp3.tag_mapping.should be_kind_of(Hash)
821
+ end
822
+
823
+ it "should map 'album' to 'album'" do
824
+ Flac2mp3.tag_mapping[:album].should == :album
825
+ end
826
+
827
+ it "should map 'artist' to 'artist'" do
828
+ Flac2mp3.tag_mapping[:artist].should == :artist
829
+ end
830
+
831
+ it "should map 'bpm' to 'TBPM'" do
832
+ Flac2mp3.tag_mapping[:bpm].should == :TBPM
833
+ end
834
+
835
+ it "should map 'description' to 'comments'" do
836
+ Flac2mp3.tag_mapping[:description].should == :comments
837
+ end
838
+
839
+ it "should map 'composer' to 'TCOM'" do
840
+ Flac2mp3.tag_mapping[:composer].should == :TCOM
841
+ end
842
+
843
+ it "should map 'date' to 'year'" do
844
+ Flac2mp3.tag_mapping[:date].should == :year
845
+ end
846
+
847
+ it "should map 'genre' to 'genre_s'" do
848
+ Flac2mp3.tag_mapping[:genre].should == :genre_s
849
+ end
850
+
851
+ it "should map 'title' to 'title'" do
852
+ Flac2mp3.tag_mapping[:title].should == :title
853
+ end
854
+
855
+ it "should map 'tracknumber' to 'TRCK'" do
856
+ Flac2mp3.tag_mapping[:tracknumber].should == :TRCK
857
+ end
858
+
859
+ it "should map 'tracktotal' to 'TRCK'" do
860
+ Flac2mp3.tag_mapping[:tracktotal].should == :TRCK
861
+ end
862
+
863
+ it "should map 'discnumber' to 'TPOS'" do
864
+ Flac2mp3.tag_mapping[:discnumber].should == :TPOS
865
+ end
866
+
867
+ it "should map 'disctotal' to 'TPOS'" do
868
+ Flac2mp3.tag_mapping[:disctotal].should == :TPOS
869
+ end
870
+
871
+ it "should map 'compilation' to 'TCMP'" do
872
+ Flac2mp3.tag_mapping[:compilation].should == :TCMP
873
+ end
874
+ end
458
875
  end
459
876
  end