Skip to content

Commit 39a345a

Browse files
author
Benjamin Russell
authored
Fix Ape Tag Bugs (#112)
**Description**: There's a bug in Ape integration tests - the temp file was being loaded as an mp3. I have no idea *why* the tests weren't failing, but anyways, upon fixing that issue, two Ape tests failed: * WriteStandardPictures * Ape tag class wasn't limiting the size of the binary tags * Fixed by adding a parameter back to the subarray method that limits the size of the binary data * Standard picture tests were assuming mimetype would be written correctly for all formats * Fixed by allowing application/octet-stream as a valid test mimetype for the non-picture picture * WriteExtendedTags * Combined tag class was erroneously accepting NaN from empty tags as valid values for replaygain properties * Fixed by changing the logic for choosing which tag to use for combined tag reading * Fixing bug with ape tag integration test * Fix a bug in combined tag that broke probably more things than expected
1 parent 4bfb546 commit 39a345a

4 files changed

Lines changed: 35 additions & 42 deletions

File tree

src/ape/apeTagItem.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,7 @@ export class ApeTagItem {
9393
item._size = keyEndIndex - offset + 1 + valueLength;
9494

9595
if (item._type === ApeTagItemType.Binary) {
96-
item._data = data.subarray(keyEndIndex + 1).toByteVector();
96+
item._data = data.subarray(keyEndIndex + 1, valueLength).toByteVector();
9797
} else {
9898
item._text = data.subarray(keyEndIndex + 1, valueLength).toStrings(StringType.UTF8);
9999
}

src/combinedTag.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -305,7 +305,7 @@ export default abstract class CombinedTag extends Tag {
305305
public set pictures(val: IPicture[]) { this.setValues((t, v) => { t.pictures = v; }, val); }
306306

307307
/** @inheritDoc */
308-
public get isCompilation(): boolean { return this.getFirstValue((t) => t.isCompilation); }
308+
public get isCompilation(): boolean { return this.getFirstValue((t) => t.isCompilation, false); }
309309
/** @inheritDoc */
310310
public set isCompilation(val: boolean) { this.setValues((t, v) => { t.isCompilation = v; }, val); }
311311

@@ -430,8 +430,10 @@ export default abstract class CombinedTag extends Tag {
430430
private getFirstValue<T>(propertyFn: (t: Tag) => T, defaultValue?: T): T {
431431
const tagWithProperty = this._tags.find((t) => {
432432
if (!t) { return false; }
433+
434+
// Block falsy values (false, 0, null, undefined, NaN), allow ""
433435
const val = propertyFn(t);
434-
return val !== undefined && val !== null && val !== defaultValue;
436+
return val || (typeof(val) === "string" && val === "");
435437
});
436438
return tagWithProperty ? propertyFn(tagWithProperty) : defaultValue;
437439
}

test-integration/ape_fileTests.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {StandardFileTests} from "./utilities/standardFileTests";
88

99
@suite class Ape_FileTests {
1010
private static readonly sampleFilePath = TestConstants.getSampleFilePath("sample.ape");
11-
private static readonly tmpFileName = "tmpwrite.mp3";
11+
private static readonly tmpFileName = "tmpwrite.ape";
1212

1313
private static file: File;
1414

test-integration/utilities/standardFileTests.ts

Lines changed: 29 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,9 @@ import {assert} from "chai";
44
import TestConstants from "./testConstants";
55
import Utilities from "./utilities";
66
import {ILazy} from "../../src/interfaces";
7-
import {
8-
ByteVector,
9-
File,
10-
Picture,
11-
PictureLazy,
12-
PictureType,
13-
ReadStyle,
14-
Tag,
15-
TagTypes
16-
} from "../../src";
7+
import {ByteVector, File, Picture, PictureLazy, PictureType, ReadStyle, Tag, TagTypes} from "../../src";
178
import {NumberUtils} from "../../src/utils";
9+
import {Testers} from "../../test-unit/utilities/testers";
1810

1911
export enum TestTagLevel {
2012
Normal,
@@ -140,39 +132,38 @@ export class StandardFileTests {
140132
}
141133
}
142134

143-
assert.strictEqual(pics[0].description, "TEST description 1");
144-
assert.strictEqual(pics[0].mimeType, "image/gif");
145-
assert.strictEqual(pics[0].data.length, fs.statSync(this.samplePicture).size);
146-
assert.isTrue(ByteVector.equals(pics[0].data, raws[0]));
147-
148-
assert.strictEqual(pics[1].description, "TEST description 2");
149-
assert.strictEqual(pics[1].data.length, fs.statSync(this.sampleOther).size);
150-
assert.isTrue(ByteVector.equals(pics[1].data, raws[1]));
151-
152-
assert.strictEqual(pics[2].description, "TEST description 3");
153-
assert.strictEqual(pics[2].mimeType, "image/gif");
154-
assert.strictEqual(pics[2].data.length, fs.statSync(this.samplePicture).size);
155-
assert.isTrue(ByteVector.equals(pics[2].data, raws[2]));
135+
// Grab the pictures back - order may be changed
136+
const pic0 = pics.find((p) => p.description === "TEST description 1");
137+
assert.isOk(pic0);
138+
assert.strictEqual(pic0.data.length, raws[0].length);
139+
Testers.bvEqual(pic0.data, raws[0]);
140+
if (level >= TestTagLevel.Medium) {
141+
assert.strictEqual(pic0.type, PictureType.BackCover);
142+
assert.strictEqual(pic0.mimeType, "image/gif");
143+
} else {
144+
assert.notStrictEqual(pic0.type, PictureType.NotAPicture);
145+
}
156146

157-
// Types and mimetypes assumed to be properly supported at Medium level test
147+
const pic1 = pics.find((p) => p.description === "TEST description 2");
148+
assert.isOk(pic1);
149+
assert.strictEqual(pic1.data.length, raws[1].length);
150+
Testers.bvEqual(pic1.data, raws[1]);
158151
if (level >= TestTagLevel.Medium) {
159-
assert.strictEqual(pics[1].mimeType, "audio/mp4");
160-
assert.strictEqual(pics[0].type, PictureType.BackCover);
161-
assert.strictEqual(pics[1].type, PictureType.NotAPicture);
162-
assert.strictEqual(pics[2].type, PictureType.Other);
152+
assert.isTrue(pic1.mimeType === "audio/mp4" || pic1.mimeType === "application/octet-stream");
153+
assert.strictEqual(pic1.type, PictureType.NotAPicture);
163154
} else {
164-
assert.notStrictEqual(pics[0].type, PictureType.NotAPicture);
165-
assert.strictEqual(pics[1].type, PictureType.NotAPicture);
166-
assert.notStrictEqual(pics[2].type, PictureType.NotAPicture);
155+
assert.strictEqual(pic1.type, PictureType.NotAPicture);
167156
}
168157

169-
// Filename assumed to be properly supported at high level test
170-
if (level >= TestTagLevel.High) {
171-
assert.strictEqual(pics[1].filename, "apple_tags.m4a");
172-
} else if (level >= TestTagLevel.Medium) {
173-
if (pics[1].filename) {
174-
assert.strictEqual(pics[1].filename, "apple_tags.m4a");
175-
}
158+
const pic2 = pics.find((p) => p.description === "TEST description 3");
159+
assert.isOk(pic2);
160+
assert.strictEqual(pic2.data.length, raws[2].length);
161+
Testers.bvEqual(pic2.data, raws[2]);
162+
if (level >= TestTagLevel.Medium) {
163+
assert.strictEqual(pic2.type, PictureType.Other);
164+
assert.strictEqual(pic2.mimeType, "image/gif");
165+
} else {
166+
assert.notStrictEqual(pic2.type, PictureType.NotAPicture);
176167
}
177168
} finally {
178169
Utilities.deleteBestEffort(tmpFile);

0 commit comments

Comments
 (0)