id3tag 0.10.1 → 0.14.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.
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