flac2mp3 0.2.8 → 0.3.0

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