id3tag 0.10.1 → 0.14.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +46 -6
  3. data/lib/id3tag.rb +14 -4
  4. data/lib/id3tag/audio_file.rb +10 -4
  5. data/lib/id3tag/configuration.rb +43 -2
  6. data/lib/id3tag/configuration_struct.rb +13 -0
  7. data/lib/id3tag/encoding_util.rb +1 -1
  8. data/lib/id3tag/frames/v1/comments_frame.rb +1 -1
  9. data/lib/id3tag/frames/v1/text_frame.rb +1 -5
  10. data/lib/id3tag/frames/v2/comments_frame.rb +1 -1
  11. data/lib/id3tag/frames/v2/text_frame.rb +4 -6
  12. data/lib/id3tag/id3_v2_frame_parser.rb +13 -9
  13. data/lib/id3tag/tag.rb +1 -1
  14. data/lib/id3tag/version.rb +1 -1
  15. metadata +21 -110
  16. data/.document +0 -5
  17. data/.gitignore +0 -8
  18. data/.rspec +0 -1
  19. data/.travis.yml +0 -15
  20. data/Gemfile +0 -4
  21. data/Rakefile +0 -24
  22. data/id3tag.gemspec +0 -28
  23. data/spec/features/can_read_non_audio_files_spec.rb +0 -17
  24. data/spec/features/can_read_tag_v1_spec.rb +0 -15
  25. data/spec/fixtures/id3v1_and_v2.mp3 +0 -0
  26. data/spec/fixtures/id3v1_with_track_nr.mp3 +0 -0
  27. data/spec/fixtures/id3v1_without_track_nr.mp3 +0 -0
  28. data/spec/fixtures/id3v2.mp3 +0 -0
  29. data/spec/fixtures/pov_20131018-2100a.mp3.v1_tag_body +0 -0
  30. data/spec/fixtures/pov_20131018-2100a.mp3.v2_3_tag_body +0 -0
  31. data/spec/fixtures/signals_1.mp3.v2_3_tag_body +0 -0
  32. data/spec/id3tag_extract_tags +0 -18
  33. data/spec/lib/id3tag/audio_file_spec.rb +0 -131
  34. data/spec/lib/id3tag/frames/util/genre_name_by_id_finder_spec.rb +0 -18
  35. data/spec/lib/id3tag/frames/v1/comments_frame_spec.rb +0 -39
  36. data/spec/lib/id3tag/frames/v1/genre_frame_spec.rb +0 -20
  37. data/spec/lib/id3tag/frames/v1/text_frame_spec.rb +0 -14
  38. data/spec/lib/id3tag/frames/v1/track_nr_frame_spec.rb +0 -19
  39. data/spec/lib/id3tag/frames/v2/basic_frame_spec.rb +0 -140
  40. data/spec/lib/id3tag/frames/v2/comments_frame_spec.rb +0 -45
  41. data/spec/lib/id3tag/frames/v2/frame_fabricator_spec.rb +0 -70
  42. data/spec/lib/id3tag/frames/v2/frame_flags_spec.rb +0 -588
  43. data/spec/lib/id3tag/frames/v2/genre_frame/genre_parser_24_spec.rb +0 -26
  44. data/spec/lib/id3tag/frames/v2/genre_frame/genre_parser_pre_24_spec.rb +0 -48
  45. data/spec/lib/id3tag/frames/v2/genre_frame/genre_parser_spec.rb +0 -13
  46. data/spec/lib/id3tag/frames/v2/genre_frame_spec.rb +0 -61
  47. data/spec/lib/id3tag/frames/v2/picture_frame_spec.rb +0 -127
  48. data/spec/lib/id3tag/frames/v2/text_frame_spec.rb +0 -89
  49. data/spec/lib/id3tag/frames/v2/unique_file_id_frame_spec.rb +0 -31
  50. data/spec/lib/id3tag/frames/v2/user_text_frame_spec.rb +0 -34
  51. data/spec/lib/id3tag/id3_v1_frame_parser_spec.rb +0 -71
  52. data/spec/lib/id3tag/id3_v2_frame_parser_spec.rb +0 -32
  53. data/spec/lib/id3tag/id3_v2_tag_header_spec.rb +0 -149
  54. data/spec/lib/id3tag/id3tag_spec.rb +0 -17
  55. data/spec/lib/id3tag/io_util_spec.rb +0 -30
  56. data/spec/lib/id3tag/number_util_spec.rb +0 -32
  57. data/spec/lib/id3tag/string_util_spec.rb +0 -81
  58. data/spec/lib/id3tag/synchsafe_integer_spec.rb +0 -14
  59. data/spec/lib/id3tag/tag_spec.rb +0 -352
  60. data/spec/spec_helper.rb +0 -23
  61. data/spec/support/mp3_fixtures.rb +0 -4
  62. data/standard_documents/id3v2-00.txt +0 -1657
  63. data/standard_documents/id3v2.3.0.txt +0 -2022
  64. data/standard_documents/id3v2.4.0-frames.txt +0 -1732
  65. data/standard_documents/id3v2.4.0-structure.txt +0 -732
@@ -1,32 +0,0 @@
1
- require "spec_helper"
2
- describe ID3Tag::ID3V2FrameParser do
3
- subject { described_class.new(frame_bytes, tag_major_version) }
4
-
5
- context "parsing v2.2.x tag" do
6
- let(:tag_major_version) { 2 }
7
- let(:frame_bytes) { "TP2\u0000\u0000\u0004\u0000ABC" + "TP1\u0000\u0000\u0004\u0000DEF" }
8
- it "should fabricate frames" do
9
- expect(ID3Tag::Frames::V2::FrameFabricator).to receive(:fabricate).with('TP2', "\u0000ABC", nil, 2).once
10
- expect(ID3Tag::Frames::V2::FrameFabricator).to receive(:fabricate).with('TP1', "\u0000DEF", nil, 2).once
11
- subject.frames
12
- end
13
- end
14
- context "parsing v2.2.3 tag" do
15
- let(:tag_major_version) { 3 }
16
- let(:frame_bytes) { "TIT2\u0000\u0000\u0000\u0004\u0000\u0000\u0000ABC" + "TIT1\u0000\u0000\u0000\u0004\u0000\u0000\u0000DEF" }
17
- it "should fabricate frames" do
18
- expect(ID3Tag::Frames::V2::FrameFabricator).to receive(:fabricate).with('TIT2', "\u0000ABC", "\u0000\u0000", 3).once
19
- expect(ID3Tag::Frames::V2::FrameFabricator).to receive(:fabricate).with('TIT1', "\u0000DEF", "\u0000\u0000", 3).once
20
- subject.frames
21
- end
22
- end
23
- context "parsing v2.4.x tag" do
24
- let(:tag_major_version) { 4 }
25
- let(:frame_bytes) { "TIT2\u0000\u0000\u0000\u0004\u0000\u0000\u0000ABC" + "TIT1\u0000\u0000\u0000\u0004\u0000\u0000\u0000DEF" }
26
- it "should fabricate frames" do
27
- expect(ID3Tag::Frames::V2::FrameFabricator).to receive(:fabricate).with('TIT2', "\u0000ABC", "\u0000\u0000", 4).once
28
- expect(ID3Tag::Frames::V2::FrameFabricator).to receive(:fabricate).with('TIT1', "\u0000DEF", "\u0000\u0000", 4).once
29
- subject.frames
30
- end
31
- end
32
- end
@@ -1,149 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe ID3Tag::ID3v2TagHeader do
4
- subject { described_class.new(header_data) }
5
-
6
- describe "#major_version_number" do
7
- context "when first bit represent 3" do
8
- let(:header_data) { "ID3\03\00..." }
9
-
10
- describe '#major_version_number' do
11
- subject { super().major_version_number }
12
- it { is_expected.to eq(3) }
13
- end
14
- end
15
- end
16
-
17
- describe "#minor_version_number" do
18
- context "when 2nd bit represent 2" do
19
- let(:header_data) { "ID3\03\02..." }
20
-
21
- describe '#minor_version_number' do
22
- subject { super().minor_version_number }
23
- it { is_expected.to eq(2) }
24
- end
25
- end
26
- end
27
-
28
- describe "#version_number" do
29
- let(:header_data) { "ID3\02\03..." }
30
-
31
- describe '#version_number' do
32
- subject { super().version_number }
33
- it { is_expected.to eq("2.3") }
34
- end
35
- end
36
-
37
- describe "header flags" do
38
- context "when flags bite is 0b10000000" do
39
- let(:header_data) { "ID3\03\00#{0b10000000.chr}" }
40
-
41
- describe '#unsynchronisation?' do
42
- subject { super().unsynchronisation? }
43
- it { is_expected.to eq(true) }
44
- end
45
-
46
- describe '#extended_header?' do
47
- subject { super().extended_header? }
48
- it { is_expected.to eq(false) }
49
- end
50
-
51
- describe '#experimental?' do
52
- subject { super().experimental? }
53
- it { is_expected.to eq(false) }
54
- end
55
-
56
- describe '#footer_present?' do
57
- subject { super().footer_present? }
58
- it { is_expected.to eq(false) }
59
- end
60
- end
61
- context "when flags bite is 0b01000000" do
62
- let(:header_data) { "ID3\03\00#{0b01000000.chr}" }
63
-
64
- describe '#unsynchronisation?' do
65
- subject { super().unsynchronisation? }
66
- it { is_expected.to eq(false) }
67
- end
68
-
69
- describe '#extended_header?' do
70
- subject { super().extended_header? }
71
- it { is_expected.to eq(true) }
72
- end
73
-
74
- describe '#experimental?' do
75
- subject { super().experimental? }
76
- it { is_expected.to eq(false) }
77
- end
78
-
79
- describe '#footer_present?' do
80
- subject { super().footer_present? }
81
- it { is_expected.to eq(false) }
82
- end
83
- end
84
- context "when flags bite is 0b00100000" do
85
- let(:header_data) { "ID3\03\00#{0b00100000.chr}" }
86
-
87
- describe '#unsynchronisation?' do
88
- subject { super().unsynchronisation? }
89
- it { is_expected.to eq(false) }
90
- end
91
-
92
- describe '#extended_header?' do
93
- subject { super().extended_header? }
94
- it { is_expected.to eq(false) }
95
- end
96
-
97
- describe '#experimental?' do
98
- subject { super().experimental? }
99
- it { is_expected.to eq(true) }
100
- end
101
-
102
- describe '#footer_present?' do
103
- subject { super().footer_present? }
104
- it { is_expected.to eq(false) }
105
- end
106
- end
107
- context "when flags bite is 0b00010000" do
108
- let(:header_data) { "ID3\03\00#{0b00010000.chr}" }
109
-
110
- describe '#unsynchronisation?' do
111
- subject { super().unsynchronisation? }
112
- it { is_expected.to eq(false) }
113
- end
114
-
115
- describe '#extended_header?' do
116
- subject { super().extended_header? }
117
- it { is_expected.to eq(false) }
118
- end
119
-
120
- describe '#experimental?' do
121
- subject { super().experimental? }
122
- it { is_expected.to eq(false) }
123
- end
124
-
125
- describe '#footer_present?' do
126
- subject { super().footer_present? }
127
- it { is_expected.to eq(true) }
128
- end
129
- end
130
- end
131
-
132
- describe "#tag_size" do
133
- let(:header_data) { "ID3abc\x00\x00\x01\x7F" }
134
-
135
- describe '#tag_size' do
136
- subject { super().tag_size }
137
- it { is_expected.to eq(255) }
138
- end
139
- end
140
-
141
- describe "#inspect" do
142
- let(:header_data) { "ID3\u0003\u0000\u0000\u0000\u0000\u0000\u0000" }
143
-
144
- describe '#inspect' do
145
- subject { super().inspect }
146
- it { is_expected.to eq "<ID3Tag::ID3v2TagHeader version:2.3.0 size:0 unsync:false ext.header:false experimental:false footer:false>" }
147
- end
148
- end
149
- end
@@ -1,17 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe ID3Tag do
4
- let(:file) { mp3_fixture('id3v2.mp3') }
5
- describe "#read" do
6
- it "reads file tag" do
7
- expect(ID3Tag.read(file)).to be_instance_of(ID3Tag::Tag)
8
- end
9
-
10
- it "accepts block" do
11
- expect do |b|
12
- ID3Tag.read(file, &b)
13
- end.to yield_control
14
- end
15
- end
16
- end
17
-
@@ -1,30 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe ID3Tag::IOUtil do
4
-
5
- describe "#read_until_terminator" do
6
- subject { ID3Tag::IOUtil.read_until_terminator(io, group_size) }
7
- context "when reading IO and looking for UTF-8 terminator - 1 null byte" do
8
- let(:group_size) { 1 }
9
- context "when only 1 null byte present" do
10
- let(:io) { StringIO.new("abcd\x00ef") }
11
- it { is_expected.to eq("abcd") }
12
- end
13
- context "when no null bytes are present" do
14
- let(:io) { StringIO.new("abcdef") }
15
- it { is_expected.to eq("abcdef") }
16
- end
17
- end
18
- context "when reading IO and looking for UTF-16 terminator - 2 null bytes" do
19
- let(:group_size) { 2 }
20
- context "when only 1 null byte present" do
21
- let(:io) { StringIO.new("a\x00b\x00\x00\x00c\x00") }
22
- it "should return content until terminator and leave cursor just right after" do
23
- expect(subject).to eq("a\x00b\x00")
24
- expect(io.read).to eq("c\x00")
25
- end
26
- end
27
- end
28
- end
29
-
30
- end
@@ -1,32 +0,0 @@
1
- require "spec_helper"
2
- describe ID3Tag::NumberUtil do
3
- describe "#convert_string_to_32bit_integer" do
4
- context "when string with 4 bytes given" do
5
- it "should return integer" do
6
- expect(described_class.convert_string_to_32bit_integer("abcd")).to eq(1633837924)
7
- end
8
- end
9
-
10
- context "when string with less than 4 bytes given" do
11
- it "should raise Argument error" do
12
- expect do
13
- described_class.convert_string_to_32bit_integer("ab")
14
- end.to raise_error(ArgumentError)
15
- end
16
- end
17
-
18
- context "when non-string argument is given" do
19
- it "should raise Argument error" do
20
- expect do
21
- described_class.convert_string_to_32bit_integer(Object.new)
22
- end.to raise_error(ArgumentError)
23
- end
24
- end
25
- end
26
-
27
- describe "#convert_32bit_integer_to_string" do
28
- it "should return 4 byte string" do
29
- expect(described_class.convert_32bit_integer_to_string(1633837924)).to eq("abcd")
30
- end
31
- end
32
- end
@@ -1,81 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe ID3Tag::StringUtil do
4
- describe "#blank?" do
5
- subject { described_class.blank?(test_string) }
6
- context "when test string is like ''" do
7
- let(:test_string) { "" }
8
- it { is_expected.to eq(true) }
9
- end
10
-
11
- context "when test string is like ' '" do
12
- let(:test_string) { " " }
13
- it { is_expected.to eq(true) }
14
- end
15
-
16
- context "when test string is like 'foo'" do
17
- let(:test_string) { "foo" }
18
- it { is_expected.to eq(false) }
19
- end
20
- end
21
-
22
- describe "do_unsynchronization" do
23
- let(:input) { }
24
- subject { described_class.do_unsynchronization(input) }
25
-
26
- context "when a false synchronization is present" do
27
- let(:input) { "\xFF\xEE" }
28
- it { is_expected.to eq("\xFF\x00\xEE") }
29
- end
30
- context "when a false synchronization is not present" do
31
- let(:input) { "\xEE\xEE" }
32
- it { is_expected.to eq("\xEE\xEE") }
33
- end
34
- end
35
-
36
- describe "undo_unsynchronization" do
37
- let(:input) { }
38
- subject { described_class.undo_unsynchronization(input) }
39
-
40
- context "when unsynchronization in present" do
41
- let(:input) { "\xFF\x00\xEE\xEE" }
42
- it { is_expected.to eq("\xFF\xEE\xEE") }
43
- end
44
- context "when unsynchronization in not present" do
45
- let(:input) { "\xEE\xEE" }
46
- it { is_expected.to eq("\xEE\xEE") }
47
- end
48
- end
49
-
50
- describe "cut_at_null_byte" do
51
- let(:input) { }
52
- subject { described_class.cut_at_null_byte(input) }
53
-
54
- context 'when content is empty' do
55
- let(:input) { '' }
56
- it { is_expected.to eq('') }
57
- end
58
-
59
- context 'when content is present' do
60
- let(:input) { "a\u0000b" }
61
- it { is_expected.to eq('a') }
62
- end
63
- end
64
-
65
- describe "split_by_null_byte" do
66
- let(:input) { }
67
- subject { described_class.split_by_null_byte(input) }
68
- context "when content have only 1 null byte" do
69
- let(:input) { "a\u0000b" }
70
- it { is_expected.to eq(["a", "b"]) }
71
- end
72
- context "when content have multiple null bytes" do
73
- let(:input) { "a\u0000\u0000b" }
74
- it { is_expected.to eq(["a", "\u0000b"]) }
75
- end
76
- context "when content have multiple null bytes" do
77
- let(:input) { "abc" }
78
- it { is_expected.to eq(["abc", ""]) }
79
- end
80
- end
81
- end
@@ -1,14 +0,0 @@
1
- require "spec_helper"
2
- describe ID3Tag::SynchsafeInteger do
3
- it "encodes regular integers" do
4
- expect(described_class.encode(255)).to eq(383)
5
- expect(described_class.encode(5)).to eq(5)
6
- expect(described_class.encode(128)).to eq(256)
7
- end
8
-
9
- it "decodes synchsafe integers" do
10
- expect(described_class.decode(383)).to eq(255)
11
- expect(described_class.decode(5)).to eq(5)
12
- expect(described_class.decode(256)).to eq(128)
13
- end
14
- end
@@ -1,352 +0,0 @@
1
- require "spec_helper"
2
-
3
- describe ID3Tag::Tag do
4
- describe "class method #read"
5
-
6
- describe "#get_frame" do
7
- subject { described_class.read(nil) }
8
- context "when more that one frame by that ID exists" do
9
- before :each do
10
- allow(subject).to receive(:get_frames) { [:frame, :frame] }
11
- end
12
- it "should raise MultipleFrameError" do
13
- expect { subject.get_frame(:some_unique_frame) }.to raise_error(ID3Tag::Tag::MultipleFrameError)
14
- end
15
- end
16
-
17
- context "when only one frame by that ID exists" do
18
- before :each do
19
- allow(subject).to receive(:get_frames) { [:frame] }
20
- end
21
- it "should return the frame" do
22
- expect(subject.get_frame(:some_unique_frame)).to eq(:frame)
23
- end
24
- end
25
- end
26
-
27
- describe "#get_frames" do
28
- subject { described_class.read(nil) }
29
- let(:a1) { ID3Tag::Frames::V1::TextFrame.new(:A, 'a1') }
30
- let(:a2) { ID3Tag::Frames::V1::TextFrame.new(:A, 'a2') }
31
- let(:b) { ID3Tag::Frames::V1::TextFrame.new(:B, 'b') }
32
- before :each do
33
- allow(subject).to receive(:frames) { [a1, a2, b] }
34
- end
35
- it "returns frames with specific IDs" do
36
- expect(subject.get_frames(:A)).to eq([a1, a2])
37
- end
38
- end
39
-
40
- describe "#frames" do
41
- subject { described_class.read(nil) }
42
- before do
43
- allow(subject).to receive(:v1_frames) { [:v1_frame1, :v1_frame2] }
44
- allow(subject).to receive(:v2_frames) { [:v2_frame1, :v2_frame2] }
45
- end
46
- it "returns v2 frames and v1 frames" do
47
- expect(subject.frames).to eq([:v2_frame1, :v2_frame2, :v1_frame1, :v1_frame2])
48
- end
49
- end
50
-
51
- describe "#frame_ids" do
52
- subject { described_class.read(nil) }
53
- let(:frame_1) { ID3Tag::Frames::V1::TextFrame.new(:AA, 'a1') }
54
- let(:frame_2) { ID3Tag::Frames::V1::TextFrame.new(:BB, 'a2') }
55
- before do
56
- allow(subject).to receive(:frames) { [frame_1, frame_2] }
57
- end
58
- it "returns frames ids" do
59
- expect(subject.frame_ids).to eq([:AA, :BB])
60
- end
61
- end
62
-
63
- describe "#v1_frames" do
64
- context "when tag reading initialized with v1 tag only" do
65
- subject { described_class.read(nil, :v1) }
66
- context "when file has v1 tag" do
67
- before do
68
- allow_any_instance_of(ID3Tag::AudioFile).to receive(:v1_tag_present?) { true }
69
- allow_any_instance_of(ID3Tag::AudioFile).to receive(:v1_tag_body) { '' }
70
- allow_any_instance_of(ID3Tag::ID3V1FrameParser).to receive(:frames) { [:v1_frame] }
71
- end
72
- it "reads v1 tags" do
73
- expect(subject.v1_frames).to eq([:v1_frame])
74
- end
75
- end
76
-
77
- context "when file does not have v1 tag" do
78
- before do
79
- allow_any_instance_of(ID3Tag::AudioFile).to receive(:v1_tag_present?) { false }
80
- allow_any_instance_of(ID3Tag::AudioFile).to receive(:v1_tag_body) { '' }
81
- end
82
- it "returns empty array" do
83
- expect(subject.v1_frames).to eq([])
84
- end
85
- end
86
- end
87
-
88
- context "when tag reading initialized with v2 tag only" do
89
- subject { described_class.read(nil, :v2) }
90
- context "when file has v1 tag" do
91
- before do
92
- allow_any_instance_of(ID3Tag::AudioFile).to receive(:v1_tag_present?) { true }
93
- allow_any_instance_of(ID3Tag::AudioFile).to receive(:v1_tag_body) { '' }
94
- end
95
- it "reads v1 tags" do
96
- expect(subject.v1_frames).to eq([])
97
- end
98
- end
99
- end
100
-
101
- context "when tag reading initialized with all versions flag" do
102
- subject { described_class.read(nil, :all) }
103
- context "when file has v1 tag" do
104
- before do
105
- allow_any_instance_of(ID3Tag::AudioFile).to receive(:v1_tag_present?) { true }
106
- allow_any_instance_of(ID3Tag::AudioFile).to receive(:v1_tag_body) { '' }
107
- allow_any_instance_of(ID3Tag::ID3V1FrameParser).to receive(:frames) { [:v1_frame] }
108
- end
109
- it "reads v1 tags" do
110
- expect(subject.v1_frames).to eq([:v1_frame])
111
- end
112
- end
113
- end
114
- end
115
-
116
- describe "#v2_frames" do
117
- before do
118
- allow_any_instance_of(ID3Tag::AudioFile).to receive(:v2_tag_major_version_number) { 3 }
119
- end
120
- context "when tag reading initialized with v2 tag only" do
121
- subject { described_class.read(nil, :v2) }
122
- context "when file has v2 tag" do
123
- before do
124
- allow_any_instance_of(ID3Tag::AudioFile).to receive(:v2_tag_present?) { true }
125
- allow_any_instance_of(ID3Tag::AudioFile).to receive(:v2_tag_body) { '' }
126
- allow_any_instance_of(ID3Tag::AudioFile).to receive(:v2_tag_size) { 120 }
127
- allow_any_instance_of(ID3Tag::ID3V2FrameParser).to receive(:frames) { [:v2_frame] }
128
- end
129
- it "reads v2 tags" do
130
- expect(subject.v2_frames).to eq([:v2_frame])
131
- end
132
- end
133
-
134
- context "when file does not have v2 tag" do
135
- before do
136
- allow_any_instance_of(ID3Tag::AudioFile).to receive(:v2_tag_present?) { false }
137
- allow_any_instance_of(ID3Tag::AudioFile).to receive(:v2_tag_body) { '' }
138
- end
139
- it "returns empty array" do
140
- expect(subject.v2_frames).to eq([])
141
- end
142
- end
143
- end
144
-
145
- context "when tag reading initialized with v1 tag only" do
146
- subject { described_class.read(nil, :v1) }
147
- context "when file has v2 tag" do
148
- before do
149
- allow_any_instance_of(ID3Tag::AudioFile).to receive(:v2_tag_present?) { true }
150
- allow_any_instance_of(ID3Tag::AudioFile).to receive(:v2_tag_body) { '' }
151
- end
152
- it "returns empty array" do
153
- expect(subject.v2_frames).to eq([])
154
- end
155
- end
156
- end
157
-
158
- context "when tag reading initialized with all versions flag" do
159
- subject { described_class.read(nil, :all) }
160
- context "when file has v2 tag" do
161
- before do
162
- allow_any_instance_of(ID3Tag::AudioFile).to receive(:v2_tag_present?) { true }
163
- allow_any_instance_of(ID3Tag::AudioFile).to receive(:v2_tag_body) { '' }
164
- allow_any_instance_of(ID3Tag::AudioFile).to receive(:v2_tag_size) { 120 }
165
- allow_any_instance_of(ID3Tag::ID3V2FrameParser).to receive(:frames) { [:v2_frame] }
166
- end
167
- it "reads v2 tags" do
168
- expect(subject.v2_frames).to eq([:v2_frame])
169
- end
170
- end
171
- end
172
- end
173
-
174
- describe "Tests with real-world tags" do
175
- let(:audio_file) { double("Fake Audio file") }
176
-
177
- subject do
178
- described_class.new(nil, scope_version).tap do |obj|
179
- allow(obj).to receive(:audio_file) { audio_file }
180
- end
181
- end
182
-
183
- before do
184
- allow(audio_file).to receive_messages({
185
- :v1_tag_present? => v1_tag_present_flag,
186
- :v2_tag_present? => v2_tag_present_flag,
187
- :v1_tag_body => v1_tag_body,
188
- :v1_tag_size => v1_tag_body.to_s.size,
189
- :v2_tag_body => v2_tag_body,
190
- :v2_tag_size => v2_tag_body.to_s.size,
191
- :v2_tag_major_version_number => v2_tag_major_version_number
192
- })
193
- end
194
-
195
- context "signals_1.mp3.v2_3_tag_body" do
196
- let(:v1_tag_present_flag) { true }
197
- let(:v2_tag_present_flag) { true }
198
- let(:v1_tag_body) { }
199
- let(:v2_tag_body) { mp3_fixture("signals_1.mp3.v2_3_tag_body").read }
200
- let(:v2_tag_major_version_number) { 3 }
201
-
202
- context "Reading only v2" do
203
- let(:scope_version) { :v2 }
204
-
205
- describe '#artist' do
206
- subject { super().artist }
207
- it { is_expected.to eq("Sabled Sun") }
208
- end
209
-
210
- describe '#title' do
211
- subject { super().title }
212
- it { is_expected.to eq("Sabled Sun - Signals I") }
213
- end
214
-
215
- describe '#album' do
216
- subject { super().album }
217
- it { is_expected.to eq("Signals I") }
218
- end
219
-
220
- describe '#year' do
221
- subject { super().year }
222
- it { is_expected.to eq("2013") }
223
- end
224
-
225
- describe '#track_nr' do
226
- subject { super().track_nr }
227
- it { is_expected.to eq "1" }
228
- end
229
-
230
- describe '#genre' do
231
- subject { super().genre }
232
- it { is_expected.to eq "Jazz" }
233
- end
234
-
235
- describe '#comments' do
236
- subject { super().comments }
237
- it { is_expected.to eq("Visit http://cryochamber.bandcamp.com") }
238
- end
239
- it "should return eng comment" do
240
- expect(subject.comments(:eng)).to eq("Visit http://cryochamber.bandcamp.com")
241
- end
242
- it "should read private frames" do
243
- expect(subject.get_frames(:PRIV).find { |f| f.owner_identifier.force_encoding(Encoding::UTF_8) == "WM/MediaClassPrimaryID" }).to be_kind_of(ID3Tag::Frames::V2::PrivateFrame)
244
- end
245
- end
246
- end
247
-
248
- context "pov_20131018-2100a.mp3" do
249
- let(:v1_tag_present_flag) { true }
250
- let(:v2_tag_present_flag) { true }
251
- let(:v1_tag_body) { mp3_fixture("pov_20131018-2100a.mp3.v1_tag_body").read }
252
- let(:v2_tag_body) { mp3_fixture("pov_20131018-2100a.mp3.v2_3_tag_body").read }
253
- let(:v2_tag_major_version_number) { 3 }
254
-
255
- context "Reading only v1" do
256
- let(:scope_version) { :v1 }
257
-
258
- describe '#artist' do
259
- subject { super().artist }
260
- it { is_expected.to eq("") }
261
- end
262
-
263
- describe '#title' do
264
- subject { super().title }
265
- it { is_expected.to eq("pov_20131018-2100a.mp3") }
266
- end
267
-
268
- describe '#album' do
269
- subject { super().album }
270
- it { is_expected.to eq("") }
271
- end
272
-
273
- describe '#year' do
274
- subject { super().year }
275
- it { is_expected.to eq("") }
276
- end
277
-
278
- describe '#track_nr' do
279
- subject { super().track_nr }
280
- it { is_expected.to be_nil }
281
- end
282
-
283
- describe '#genre' do
284
- subject { super().genre }
285
- it { is_expected.to eq("Blues") }
286
- end
287
-
288
- describe '#comments' do
289
- subject { super().comments }
290
- it { is_expected.to be_nil }
291
- end
292
-
293
- describe '#frame_ids' do
294
- subject { super().frame_ids }
295
- it { is_expected.to eq [:title, :artist, :album, :year, :comments, :genre] }
296
- end
297
- end
298
- context "Reading only v2" do
299
- let(:scope_version) { :v2 }
300
-
301
- describe '#artist' do
302
- subject { super().artist }
303
- it { is_expected.to eq("BBC Radio 4") }
304
- end
305
-
306
- describe '#title' do
307
- subject { super().title }
308
- it { is_expected.to eq("PoV: Lisa Jardine: Machine Intelligence: 18 Oct 13") }
309
- end
310
-
311
- describe '#album' do
312
- subject { super().album }
313
- it { is_expected.to eq("A Point of View") }
314
- end
315
-
316
- describe '#year' do
317
- subject { super().year }
318
- it { is_expected.to eq("2013") }
319
- end
320
-
321
- describe '#track_nr' do
322
- subject { super().track_nr }
323
- it { is_expected.to be_nil }
324
- end
325
- it "should return nil for genre as this tag have incorect genre frame" do
326
- expect(subject.genre).to eq("")
327
- end
328
-
329
- describe '#comments' do
330
- subject { super().comments }
331
- it { is_expected.to eq("Lisa Jardine compares the contributions of Ada Lovelace and Alan Turing a century later to computer science and contrasts their views on the potential of and limits to machine intelligence. \r\nProducer: Sheila Cook") }
332
- end
333
- it "should return eng comment" do
334
- expect(subject.comments(:eng)).to eq("Lisa Jardine compares the contributions of Ada Lovelace and Alan Turing a century later to computer science and contrasts their views on the potential of and limits to machine intelligence. \r\nProducer: Sheila Cook")
335
- end
336
- it "should return blank string for latvian comments" do
337
- expect(subject.comments(:lav)).to be_nil
338
- end
339
-
340
- describe '#frame_ids' do
341
- subject { super().frame_ids }
342
- it { is_expected.to eq [:TALB, :TPE1, :COMM, :USLT, :TCON, :TIT2, :TYER, :TCOP, :APIC] }
343
- end
344
- it "should have comments frame with short desc and language code" do
345
- expect(subject.get_frames(:COMM).size).to eq(1)
346
- expect(subject.get_frame(:COMM).language).to eq("eng")
347
- expect(subject.get_frame(:COMM).description).to eq("")
348
- end
349
- end
350
- end
351
- end
352
- end