From e2d2de8450e82f73f93c54e3e9a12b4822dcc7a9 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 22 Jul 2026 14:47:46 -0500 Subject: [PATCH 01/18] Reorganize a bunch of crap in ID3v2 --- docs/classes/Id3v2TagFooter.md | 2 +- docs/classes/Id3v2TagHeader.md | 10 +- docs/enums/Id3v2TagHeaderFlags.md | 2 +- docs/modules.md | 2 +- src/id3v2/enums.ts | 350 ++++++++++++++++++ src/id3v2/frames/attachmentFrame.ts | 14 +- src/id3v2/frames/commentsFrame.ts | 10 +- src/id3v2/frames/eventTimeCodeFrame.ts | 14 +- src/id3v2/frames/frame.ts | 35 +- src/id3v2/frames/frameFactory.ts | 27 +- src/id3v2/frames/frameHeader.ts | 116 ++---- src/id3v2/frames/genreFrame.ts | 8 +- src/id3v2/frames/musicCdIdentifierFrame.ts | 8 +- src/id3v2/frames/playCountFrame.ts | 10 +- src/id3v2/frames/popularimeterFrame.ts | 8 +- src/id3v2/frames/privateFrame.ts | 8 +- src/id3v2/frames/relativeVolumeFrame.ts | 65 +--- src/id3v2/frames/synchronizedLyricsFrame.ts | 10 +- src/id3v2/frames/termsOfUseFrame.ts | 8 +- src/id3v2/frames/textInformationFrame.ts | 20 +- src/id3v2/frames/uniqueFileIdentifierFrame.ts | 10 +- src/id3v2/frames/unknownFrame.ts | 8 +- src/id3v2/frames/unsynchronizedLyricsFrame.ts | 8 +- src/id3v2/frames/urlLinkFrame.ts | 8 +- src/id3v2/frames/userTextInformationFrame.ts | 8 +- src/id3v2/frames/userUrlLinkFrame.ts | 8 +- src/id3v2/id3v2Tag.ts | 46 +-- src/id3v2/{id3v2TagFooter.ts => tagFooter.ts} | 29 +- src/id3v2/{id3v2TagHeader.ts => tagHeader.ts} | 60 +-- ...ExtendedHeader.ts => tagHeaderExtended.ts} | 14 +- src/id3v2/utilTypes.ts | 194 ---------- src/index.ts | 22 +- src/sandwich/endTag.ts | 6 +- src/sandwich/startTag.ts | 2 +- test-unit/combinedTagTests.ts | 4 +- test-unit/flac/flacFileTests.ts | 6 +- test-unit/id3v2/attachmentsFrameTests.ts | 41 +- test-unit/id3v2/commentsFrameTests.ts | 25 +- test-unit/id3v2/eventTimeCodeFrameTests.ts | 24 +- test-unit/id3v2/frameConstructorTests.ts | 10 +- test-unit/id3v2/frameFactoryTests.ts | 60 +-- test-unit/id3v2/frameHeaderTests.ts | 113 +++--- test-unit/id3v2/frameTests.ts | 25 +- test-unit/id3v2/genreFrameTests.ts | 9 +- test-unit/id3v2/id3v2TagTests.ts | 39 +- .../id3v2/musicCdIdentifierFrameTests.ts | 11 +- test-unit/id3v2/playCountFrameTests.ts | 21 +- test-unit/id3v2/popularimeterFrameTests.ts | 27 +- test-unit/id3v2/privateFrameTests.ts | 19 +- test-unit/id3v2/relativeVolumeFrameTests.ts | 25 +- .../id3v2/synchronizedLyricsFrameTests.ts | 32 +- test-unit/id3v2/tagExtendedHeaderTests.ts | 30 +- test-unit/id3v2/tagFooterTests.ts | 60 +-- test-unit/id3v2/tagHeaderTests.ts | 99 ++--- test-unit/id3v2/termsOfUseFrameTests.ts | 19 +- test-unit/id3v2/textInformationFrameTests.ts | 25 +- .../id3v2/uniqueFileIdentifierFrameTests.ts | 15 +- test-unit/id3v2/unknownFrameTests.ts | 11 +- .../id3v2/unsynchronizedLyricsFrameTests.ts | 25 +- test-unit/id3v2/urlLinkFrameTests.ts | 13 +- .../id3v2/userTextInformationFrameTests.ts | 25 +- test-unit/id3v2/userUrlLinkFrameTests.ts | 25 +- .../matroska/matroskaTagCollectionTests.ts | 10 +- test-unit/matroska/utils.ts | 2 +- test-unit/riff/riffFileTests.ts | 6 +- test-unit/sandwich/endTagTests.ts | 17 +- test-unit/sandwich/sandwichTagTests.ts | 6 +- test-unit/xiph/resources.ts | 3 +- 68 files changed, 1038 insertions(+), 994 deletions(-) create mode 100644 src/id3v2/enums.ts rename src/id3v2/{id3v2TagFooter.ts => tagFooter.ts} (87%) rename src/id3v2/{id3v2TagHeader.ts => tagHeader.ts} (80%) rename src/id3v2/{id3v2ExtendedHeader.ts => tagHeaderExtended.ts} (91%) diff --git a/docs/classes/Id3v2TagFooter.md b/docs/classes/Id3v2TagFooter.md index 18a975fc..aac06e2a 100644 --- a/docs/classes/Id3v2TagFooter.md +++ b/docs/classes/Id3v2TagFooter.md @@ -210,7 +210,7 @@ same tag. | Name | Type | Description | | :------ | :------ | :------ | -| `header` | [`Id3v2TagHeader`](Id3v2TagHeader.md) | Header from which to base the new footer | +| `header` | [`TagHeader`](Id3v2TagHeader.md) | Header from which to base the new footer | #### Returns diff --git a/docs/classes/Id3v2TagHeader.md b/docs/classes/Id3v2TagHeader.md index efe3ee41..431e7611 100644 --- a/docs/classes/Id3v2TagHeader.md +++ b/docs/classes/Id3v2TagHeader.md @@ -1,6 +1,6 @@ -[node-taglib-sharp](../README.md) / [Exports](../modules.md) / Id3v2TagHeader +[node-taglib-sharp](../README.md) / [Exports](../modules.md) / TagHeader -# Class: Id3v2TagHeader +# Class: TagHeader This class provides a representation of an ID3v2 tag header which can be read from and written to disk. @@ -32,7 +32,7 @@ to disk. ### constructor -• **new Id3v2TagHeader**() +• **new TagHeader**() ## Properties @@ -182,7 +182,7 @@ ___ ### fromData -▸ `Static` **fromData**(`data`): [`Id3v2TagHeader`](Id3v2TagHeader.md) +▸ `Static` **fromData**(`data`): [`TagHeader`](Id3v2TagHeader.md) Constructs and initializes a new instance by reading it from the raw header data. @@ -194,4 +194,4 @@ Constructs and initializes a new instance by reading it from the raw header data #### Returns -[`Id3v2TagHeader`](Id3v2TagHeader.md) +[`TagHeader`](Id3v2TagHeader.md) diff --git a/docs/enums/Id3v2TagHeaderFlags.md b/docs/enums/Id3v2TagHeaderFlags.md index 758b6a15..ac7e17a3 100644 --- a/docs/enums/Id3v2TagHeaderFlags.md +++ b/docs/enums/Id3v2TagHeaderFlags.md @@ -2,7 +2,7 @@ # Enumeration: Id3v2TagHeaderFlags -Indicates the flags applied to a [Id3v2TagHeader](../classes/Id3v2TagHeader.md) object. +Indicates the flags applied to a [TagHeader](../classes/Id3v2TagHeader.md) object. ## Table of contents diff --git a/docs/modules.md b/docs/modules.md index bd7de908..8bdd06d6 100644 --- a/docs/modules.md +++ b/docs/modules.md @@ -90,7 +90,7 @@ - [Id3v2SynchronizedLyricsFrame](classes/Id3v2SynchronizedLyricsFrame.md) - [Id3v2Tag](classes/Id3v2Tag.md) - [Id3v2TagFooter](classes/Id3v2TagFooter.md) -- [Id3v2TagHeader](classes/Id3v2TagHeader.md) +- [TagHeader](classes/Id3v2TagHeader.md) - [Id3v2TermsOfUseFrame](classes/Id3v2TermsOfUseFrame.md) - [Id3v2TextInformationFrame](classes/Id3v2TextInformationFrame.md) - [Id3v2UniqueFileIdentifierFrame](classes/Id3v2UniqueFileIdentifierFrame.md) diff --git a/src/id3v2/enums.ts b/src/id3v2/enums.ts new file mode 100644 index 00000000..8e0a6457 --- /dev/null +++ b/src/id3v2/enums.ts @@ -0,0 +1,350 @@ +/** + * Type of channel data to get from or set to a {@link RelativeVolumeFrame} object + */ +export enum ChannelType { + /** + * Channel data for some other speaker + */ + Other = 0x00, + + /** + * Channel data for the master volume + */ + MasterVolume = 0x01, + + /** + * Channel data for the front right speaker + */ + FrontRight = 0x02, + + /** + * Channel data for front left speaker + */ + FrontLeft = 0x03, + + /** + * Channel data for center right speaker + */ + BackRight = 0x04, + + /** + * Channel data for back left speaker + */ + BackLeft = 0x05, + + /** + * Channel data for front center speaker + */ + FrontCentre = 0x06, + + /** + * Channel data for back center speaker + */ + BackCenter = 0x07, + + /** + * Channel data for subwoofer + */ + Subwoofer = 0x08 +} + +/** + * Indicates what type of event the event represents. + */ +export enum EventType { + /** + * Padding - no meaning + */ + Padding = 0x00, + + /** + * End of initial silence + */ + EndOfInitialSilence = 0x01, + + /** + * Start of the intro + */ + IntroStart = 0x02, + + /** + * Start of the main part of the song + */ + MainPartStart = 0x03, + + /** + * Start of the outro + */ + OutroStart = 0x04, + + /** + * End of the outro + */ + OutroEnd = 0x05, + + /** + * Start of the verse + */ + VerseStart = 0x06, + + /** + * Start of the refrain + */ + RefrainStart = 0x07, + + /** + * Start of the interlude + */ + InterludeStart = 0x08, + + /** + * Start of the theme + */ + ThemeStart = 0x09, + + /** + * Start of a variation + */ + VariationStart = 0x0A, + + /** + * Indicates a key change event + */ + KeyChange = 0x0B, + + /** + * Indicates a tempo/time signature change event + */ + TimeChange = 0x0C, + + /** + * Indicates momentary unwanted noise (snap, crackle, and pop) + */ + MomentaryUnwantedNoise = 0x0D, + + /** + * Start of sustained noise + */ + SustainedNoise = 0x0E, + + /** + * End of sustained noise + */ + SustainedNoiseEnd = 0x0F, + + /** + * End of the intro + */ + IntroEnd = 0x10, + + /** + * End of the main part of the song + */ + MainPartEnd = 0x11, + + /** + * End of the verse + */ + VerseEnd = 0x12, + + /** + * End of the refrain + */ + RefrainEnd = 0x13, + + /** + * End of the main theme + */ + ThemeEnd = 0x14, + + /** + * Start of profanity + */ + Profanity = 0x15, + + /** + * End of profanity + */ + ProfanityEnd = 0x16, + + /** + * End of audio + */ + AudioEnd = 0xFD, + + /** + * End of the audio file + */ + AudioFileEnd = 0xFE +} + +/** + * Indicates the flags applied to a {@link Id3v2FrameHeader} object. + */ +export enum FrameFlags { + /** + * Header contains no flags. + */ + None = 0, + + /** + * Frame is to be deleted if the tag is altered. + */ + TagAlterPreservation = 0x4000, + + /** + * Frame is to be deleted if the file is altered. + */ + FileAlterPreservation = 0x2000, + + /** + * Frame is read-only and should not be altered. + */ + ReadOnly = 0x1000, + + /** + * Frame has a grouping identity. + */ + GroupingIdentity = 0x0040, + + /** + * Frame data is compressed. + */ + Compression = 0x0008, + + /** + * Frame data is encrypted. + */ + Encryption = 0x0004, + + /** + * Frame data has been unsynchronized using the ID3v2 unsynchronization scheme. + */ + Unsynchronized = 0x0002, + + /** + * Frame has a data length indicator. + */ + DataLengthIndicator = 0x0001 +} + +/** + * Indicates the flags applied to a {@link Id3v2TagHeader} object. + */ +export enum TagFlags { + /** + * The header contains no flags. + */ + None = 0x0, + + /** + * The tag described by the header contains a footer. + */ + FooterPresent = 0x10, + + /** + * The tag described by the header is experimental. + */ + ExperimentalIndicator = 0x20, + + /** + * The tag described by the header contains an extended header. + */ + ExtendedHeader = 0x40, + + /** + * The tag described by the header has been unsynchronized using the ID3v2 unsynchronization + * scheme. + */ + Unsynchronization = 0x80, +} + +/** + * Indicates a major version of ID3v2. + */ +export enum Id3v2Version { + /** + * Indicates the ID3v2.2 version. + */ + V22 = 1, + + /** + * Indicates the ID3v2.3 version. + */ + V23 = 2, + + /** + * Indicates the ID3v2.4 version. + */ + V24 = 4 +} + +/** + * Specifies the type of text contained in a synchronized lyrics frame + */ +export enum SynchronizedTextType { + /** + * Text is some other type of text + */ + Other = 0x00, + + /** + * Text contains lyrical data + */ + Lyrics = 0x01, + + /** + * Text contains a transcription + */ + TextTranscription = 0x02, + + /** + * Text lists the movements in the piece + */ + Movement = 0x03, + + /** + * Text describes events that occur + */ + Events = 0x04, + + /** + * Text contains chord changes that occur in the music + */ + Chord = 0x05, + + /** + * Text contains trivia or "pop up" information about the media + */ + Trivia = 0x06, + + /** + * Text contains URLs for relevant webpages + */ + WebpageUrls = 0x07, + + /** + * Text contains URLs for relevant images + */ + ImageUrls = 0x08 +} + +/** + * Specifies the timestamp format used by a few frame types. + */ +export enum TimestampFormat { + /** + * Timestamp is of unknown format + */ + Unknown = 0x00, + + /** + * Timestamp represents the number of MPEG frames since the beginning of the audio stream + */ + AbsoluteMpegFrames = 0x01, + + /** + * Timestamp represents the number of milliseconds since the beginning of the audio stream + */ + AbsoluteMilliseconds = 0x02 +} diff --git a/src/id3v2/frames/attachmentFrame.ts b/src/id3v2/frames/attachmentFrame.ts index 3bb0e514..09d7c7a5 100644 --- a/src/id3v2/frames/attachmentFrame.ts +++ b/src/id3v2/frames/attachmentFrame.ts @@ -1,9 +1,9 @@ import Frame from "./frame"; +import FrameHeader from "./frameHeader"; import Id3v2Settings from "../id3v2Settings"; import {ByteVector, StringType} from "../../byteVector"; import {CorruptFileError} from "../../errors"; import {IFileAbstraction} from "../../fileAbstraction"; -import {Id3v2FrameHeader} from "./frameHeader"; import {FrameIdentifiers} from "../frameIdentifiers"; import {IPicture, Picture, PictureLazy, PictureType} from "../../picture"; import {ArrayUtils, Guards} from "../../utils"; @@ -24,7 +24,7 @@ export default class AttachmentFrame extends Frame implements IPicture { // #region Constructors - private constructor(frameHeader: Id3v2FrameHeader) { + private constructor(frameHeader: FrameHeader) { super(frameHeader); } @@ -34,7 +34,7 @@ export default class AttachmentFrame extends Frame implements IPicture { * @param fieldBytes Bytes that contain the fields of the frame * @param version ID3v2 version the frame was originally encoded with */ - public static fromFieldBytes(header: Id3v2FrameHeader, fieldBytes: ByteVector, version: number): AttachmentFrame { + public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: number): AttachmentFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); Guards.byte(version, "version"); @@ -79,7 +79,7 @@ export default class AttachmentFrame extends Frame implements IPicture { // @TODO: Make lazy loading optional public static fromFile( file: IFileAbstraction, - header: Id3v2FrameHeader, + header: FrameHeader, frameStart: number, size: number, version: number @@ -109,7 +109,7 @@ export default class AttachmentFrame extends Frame implements IPicture { // NOTE: We assume the frame is an APIC frame of size 1 until we parse it and find out // otherwise. - const frame = new AttachmentFrame(new Id3v2FrameHeader(FrameIdentifiers.APIC, undefined, 1)); + const frame = new AttachmentFrame(new FrameHeader(FrameIdentifiers.APIC, undefined, 1)); frame._rawPicture = picture; return frame; } @@ -221,7 +221,7 @@ export default class AttachmentFrame extends Frame implements IPicture { ? FrameIdentifiers.GEOB : FrameIdentifiers.APIC; if (this.header.frameId !== frameId) { - this.header = new Id3v2FrameHeader(frameId); + this.header = new FrameHeader(frameId); } this._type = value; @@ -233,7 +233,7 @@ export default class AttachmentFrame extends Frame implements IPicture { /** @inheritDoc */ public clone(): Frame { - const frame = new AttachmentFrame(new Id3v2FrameHeader(this.frameId)); + const frame = new AttachmentFrame(new FrameHeader(this.frameId)); frame._data = this._data?.toByteVector(); frame._description = this._description; frame._encoding = this._encoding; diff --git a/src/id3v2/frames/commentsFrame.ts b/src/id3v2/frames/commentsFrame.ts index 4151bbd9..514b733d 100644 --- a/src/id3v2/frames/commentsFrame.ts +++ b/src/id3v2/frames/commentsFrame.ts @@ -1,8 +1,8 @@ import Frame from "./frame"; +import FrameHeader from "./frameHeader"; import Id3v2Settings from "../id3v2Settings"; import {ByteVector, StringType} from "../../byteVector"; import {CorruptFileError} from "../../errors"; -import {Id3v2FrameHeader} from "./frameHeader"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; @@ -18,7 +18,7 @@ export default class CommentsFrame extends Frame { // #region - private constructor(frameHeader: Id3v2FrameHeader) { + private constructor(frameHeader: FrameHeader) { super(frameHeader); } @@ -28,7 +28,7 @@ export default class CommentsFrame extends Frame { * @param fieldBytes Bytes that contain the fields of the frame * @param version ID3v2 version the frame was originally encoded with */ - public static fromFieldBytes(header: Id3v2FrameHeader, fieldBytes: ByteVector, version: number): CommentsFrame { + public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: number): CommentsFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); Guards.byte(version, "version"); @@ -82,7 +82,7 @@ export default class CommentsFrame extends Frame { language?: string, encoding?: StringType ): CommentsFrame { - const frame = new CommentsFrame(new Id3v2FrameHeader(FrameIdentifiers.COMM)); + const frame = new CommentsFrame(new FrameHeader(FrameIdentifiers.COMM)); frame._description = description ?? ""; frame._language = language ?? "XXX"; frame._text = text ?? ""; @@ -151,7 +151,7 @@ export default class CommentsFrame extends Frame { /** @inheritDoc */ public clone(): Frame { - const clone = new CommentsFrame(new Id3v2FrameHeader(FrameIdentifiers.COMM)); + const clone = new CommentsFrame(new FrameHeader(FrameIdentifiers.COMM)); clone._description = this._description; clone._language = this._language; clone._text = this._text; diff --git a/src/id3v2/frames/eventTimeCodeFrame.ts b/src/id3v2/frames/eventTimeCodeFrame.ts index facb2484..9fd987f0 100644 --- a/src/id3v2/frames/eventTimeCodeFrame.ts +++ b/src/id3v2/frames/eventTimeCodeFrame.ts @@ -1,9 +1,9 @@ import Frame from "./frame"; +import FrameHeader from "./frameHeader"; import {ByteVector} from "../../byteVector"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "./frameHeader"; +import {EventType, FrameFlags, TimestampFormat} from "../enums"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; -import {EventType, TimestampFormat} from "../utilTypes"; import {CorruptFileError} from "../../errors"; /** @@ -85,7 +85,7 @@ export class EventTimeCodeFrame extends Frame { // #region Constructors - private constructor(header: Id3v2FrameHeader) { + private constructor(header: FrameHeader) { super(header); } @@ -96,7 +96,7 @@ export class EventTimeCodeFrame extends Frame { * @param version ID3v2 version the frame was originally encoded with */ public static fromFieldBytes( - header: Id3v2FrameHeader, + header: FrameHeader, fieldBytes: ByteVector, version: number ): EventTimeCodeFrame { @@ -149,8 +149,8 @@ export class EventTimeCodeFrame extends Frame { * to `[]`. */ public static fromFields(timestampFormat?: TimestampFormat, events?: EventTimeCode[]): EventTimeCodeFrame { - const frame = new EventTimeCodeFrame(new Id3v2FrameHeader(FrameIdentifiers.ETCO)); - frame.flags = Id3v2FrameFlags.FileAlterPreservation; // @TODO: Should we be mucking around with flags like this? + const frame = new EventTimeCodeFrame(new FrameHeader(FrameIdentifiers.ETCO)); + frame.flags = FrameFlags.FileAlterPreservation; // @TODO: Should we be mucking around with flags like this? frame._timestampFormat = timestampFormat ?? TimestampFormat.Unknown; frame._events = events ?? []; @@ -192,7 +192,7 @@ export class EventTimeCodeFrame extends Frame { /** @inheritDoc */ public clone(): Frame { - const frame = new EventTimeCodeFrame(new Id3v2FrameHeader(this.frameId, this.flags)); + const frame = new EventTimeCodeFrame(new FrameHeader(this.frameId, this.flags)); frame._events = this._events.map(i => i.clone()); frame._timestampFormat = this._timestampFormat; diff --git a/src/id3v2/frames/frame.ts b/src/id3v2/frames/frame.ts index b4056ffb..f57aacab 100644 --- a/src/id3v2/frames/frame.ts +++ b/src/id3v2/frames/frame.ts @@ -1,7 +1,8 @@ +import FrameHeader from "./frameHeader"; import Id3v2Settings from "../id3v2Settings"; import SyncData from "../syncData"; import {ByteVector, StringType} from "../../byteVector"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "./frameHeader"; +import {FrameFlags} from "../enums"; import {FrameIdentifier} from "../frameIdentifiers"; import {Guards, NumberUtils} from "../../utils"; @@ -11,7 +12,7 @@ import {Guards, NumberUtils} from "../../utils"; */ export default abstract class Frame { - private _header: Id3v2FrameHeader; + private _header: FrameHeader; // #region Constructors @@ -20,7 +21,7 @@ export default abstract class Frame { * @param header Header for the frame. * @protected */ - protected constructor(header: Id3v2FrameHeader) { + protected constructor(header: FrameHeader) { this._header = header; } @@ -45,14 +46,14 @@ export default abstract class Frame { /** * Gets the frame flags applied to the current instance. */ - public get flags(): Id3v2FrameFlags { return this._header.flags; } + public get flags(): FrameFlags { return this._header.flags; } /** * Sets the frame flags applied to the current instance. - * If the value includes either {@link Id3v2FrameFlags.Encryption} or - * {@link Id3v2FrameFlags.Compression}, {@link render} will throw. + * If the value includes either {@link FrameFlags.Encryption} or + * {@link FrameFlags.Compression}, {@link render} will throw. */ // @TODO: This shouldn't be necessary, but removing it breaks more things than I want to fix right now. - public set flags(value: Id3v2FrameFlags) { this._header.flags = value; } + public set flags(value: FrameFlags) { this._header.flags = value; } /** * Gets the frame ID for the current instance. @@ -85,13 +86,13 @@ export default abstract class Frame { * Gets the header for the frame. For new frames this should not exist. * @protected */ - protected get header(): Id3v2FrameHeader { return this._header; } + protected get header(): FrameHeader { return this._header; } /** * Sets the header for the frame. * @param value Header for the frame * @protected */ - protected set header(value: Id3v2FrameHeader) { this._header = value; } + protected set header(value: FrameHeader) { this._header = value; } // #endregion @@ -121,16 +122,16 @@ export default abstract class Frame { // 2) Render the extended header and process with the body // Remove flags that are not supported by older versions of ID3v2 if (version < 4) { - const v4Flags = Id3v2FrameFlags.DataLengthIndicator | Id3v2FrameFlags.Unsynchronized; + const v4Flags = FrameFlags.DataLengthIndicator | FrameFlags.Unsynchronized; this.flags &= ~(v4Flags); } if (version < 3) { - const v3Flags = Id3v2FrameFlags.Compression - | Id3v2FrameFlags.Encryption - | Id3v2FrameFlags.FileAlterPreservation - | Id3v2FrameFlags.GroupingIdentity - | Id3v2FrameFlags.ReadOnly - | Id3v2FrameFlags.TagAlterPreservation; + const v3Flags = FrameFlags.Compression + | FrameFlags.Encryption + | FrameFlags.FileAlterPreservation + | FrameFlags.GroupingIdentity + | FrameFlags.ReadOnly + | FrameFlags.TagAlterPreservation; this.flags &= ~(v3Flags); } @@ -139,7 +140,7 @@ export default abstract class Frame { // Combine extended header with body bytes to form complete body. Unsynchronize if necessary. let payloadBytes = ByteVector.concatenate(extendedHeaderBytes, fieldBytes); - if (NumberUtils.hasFlag(this.flags, Id3v2FrameFlags.Unsynchronized)) { + if (NumberUtils.hasFlag(this.flags, FrameFlags.Unsynchronized)) { payloadBytes = SyncData.unsyncByteVector(payloadBytes); } diff --git a/src/id3v2/frames/frameFactory.ts b/src/id3v2/frames/frameFactory.ts index 03be210f..763e396c 100644 --- a/src/id3v2/frames/frameFactory.ts +++ b/src/id3v2/frames/frameFactory.ts @@ -1,6 +1,7 @@ import AttachmentFrame from "./attachmentFrame"; import CommentsFrame from "./commentsFrame"; import Frame from "./frame"; +import FrameHeader from "./frameHeader"; import GenreFrame from "./genreFrame"; import MusicCdIdentifierFrame from "./musicCdIdentifierFrame"; import PlayCountFrame from "./playCountFrame"; @@ -19,7 +20,7 @@ import {ByteVector} from "../../byteVector"; import {CorruptFileError, NotImplementedError} from "../../errors"; import {EventTimeCodeFrame} from "./eventTimeCodeFrame"; import {File} from "../../file"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "./frameHeader"; +import {FrameFlags} from "../enums"; import {FrameIdentifier, FrameIdentifiers} from "../frameIdentifiers"; import {RelativeVolumeFrame} from "./relativeVolumeFrame"; import {SynchronizedLyricsFrame} from "./synchronizedLyricsFrame"; @@ -32,9 +33,9 @@ import {Guards, NumberUtils} from "../../utils"; * @param header The header that describes the frame. * @param version ID3v2 version the frame is encoded with. Must be unsigned 8-bit int */ -export type FrameCreator = (data: ByteVector, offset: number, header: Id3v2FrameHeader, version: number) => Frame; +export type FrameCreator = (data: ByteVector, offset: number, header: FrameHeader, version: number) => Frame; -type InternalFrameCreator = (header: Id3v2FrameHeader, fieldBytes: ByteVector, version: number) => Frame; +type InternalFrameCreator = (header: FrameHeader, fieldBytes: ByteVector, version: number) => Frame; /** * Performs the necessary operations to determine and create the correct child classes of @@ -74,7 +75,7 @@ export class Id3v2FrameFactory { * @param creator Frame creator function * * data: ByteVector Raw ID3v2 frame * * offset: number Offset in data at which the frame data begins (should be int) - * * header: Id3v2FrameHeader Header for the frame contained in data + * * header: FrameHeader Header for the frame contained in data * * version: number ID3v2 version the raw frame data is stored in (should be byte) * * returns Frame if method was able to match the frame, falsy otherwise */ @@ -114,7 +115,7 @@ export class Id3v2FrameFactory { file.seek(offset); // 2) Read basic frame header - const headerSize = Id3v2FrameHeader.getBaseSize(version); + const headerSize = FrameHeader.getBaseSize(version); const headerBytes = file.readBlock(headerSize); if (headerBytes.length < headerSize) { throw new Error("Argument error: data does not contain enough bytes for an ID3v2 frame header"); @@ -125,7 +126,7 @@ export class Id3v2FrameFactory { return undefined; } - const header = Id3v2FrameHeader.fromData(headerBytes, version); + const header = FrameHeader.fromData(headerBytes, version); this.assertSupportedFlags(header.flags); // @TODO: Support lazy loading frames again @@ -157,7 +158,7 @@ export class Id3v2FrameFactory { Guards.byte(version, "version"); // 1) Read the basic frame header - const headerSize = Id3v2FrameHeader.getBaseSize(version); + const headerSize = FrameHeader.getBaseSize(version); const headerBytes = data.subarray(offset, headerSize); if (headerBytes.length < headerSize) { throw new Error("Argument error: data does not contain enough bytes for an ID3v2 frame header"); @@ -168,7 +169,7 @@ export class Id3v2FrameFactory { return undefined; } - const header = Id3v2FrameHeader.fromData(headerBytes, version); + const header = FrameHeader.fromData(headerBytes, version); this.assertSupportedFlags(header.flags); // 2) Read the body bytes and finish constructing frame @@ -178,14 +179,14 @@ export class Id3v2FrameFactory { return { frame: frame, totalSize: header.frameSize + headerSize }; } - private static assertSupportedFlags(headerFlags: Id3v2FrameFlags): void { + private static assertSupportedFlags(headerFlags: FrameFlags): void { // TODO: Support compression - if (NumberUtils.hasFlag(headerFlags, Id3v2FrameFlags.Compression)) { + if (NumberUtils.hasFlag(headerFlags, FrameFlags.Compression)) { throw new NotImplementedError("Compression is not supported"); } // TODO: Support encryption - if (NumberUtils.hasFlag(headerFlags, Id3v2FrameFlags.Encryption)) { + if (NumberUtils.hasFlag(headerFlags, FrameFlags.Encryption)) { throw new NotImplementedError("Encryption is not supported"); } @@ -193,7 +194,7 @@ export class Id3v2FrameFactory { } private static createFrameFromFieldBytes( - header: Id3v2FrameHeader, + header: FrameHeader, payloadBytes: ByteVector, version: number, unsynchedAtTagLevel: boolean @@ -209,7 +210,7 @@ export class Id3v2FrameFactory { // Mark the frame as unsynchronized if the entire tag is already unsynchronized // @TODO: Is this how the spec is written? Or was this to correct for invalid flags? if (unsynchedAtTagLevel) { - header.flags &= ~Id3v2FrameFlags.Unsynchronized; + header.flags &= ~FrameFlags.Unsynchronized; } // 1) Unsynchronize if necessary diff --git a/src/id3v2/frames/frameHeader.ts b/src/id3v2/frames/frameHeader.ts index 70a55627..62480d8d 100644 --- a/src/id3v2/frames/frameHeader.ts +++ b/src/id3v2/frames/frameHeader.ts @@ -1,59 +1,10 @@ import SyncData from "../syncData"; import {ByteVector, StringType} from "../../byteVector"; +import {FrameFlags} from "../enums"; import {CorruptFileError, NotImplementedError} from "../../errors"; import {FrameIdentifier, FrameIdentifiers} from "../frameIdentifiers"; import {Guards, NumberUtils} from "../../utils"; -/** - * Indicates the flags applied to a {@link Id3v2FrameHeader} object. - */ -export enum Id3v2FrameFlags { - /** - * Header contains no flags. - */ - None = 0, - - /** - * Frame is to be deleted if the tag is altered. - */ - TagAlterPreservation = 0x4000, - - /** - * Frame is to be deleted if the file is altered. - */ - FileAlterPreservation = 0x2000, - - /** - * Frame is read-only and should not be altered. - */ - ReadOnly = 0x1000, - - /** - * Frame has a grouping identity. - */ - GroupingIdentity = 0x0040, - - /** - * Frame data is compressed. - */ - Compression = 0x0008, - - /** - * Frame data is encrypted. - */ - Encryption = 0x0004, - - /** - * Frame data has been unsynchronized using the ID3v2 unsynchronization scheme. - */ - Unsynchronized = 0x0002, - - /** - * Frame has a data length indicator. - */ - DataLengthIndicator = 0x0001 -} - /** * This class provides a representation of an ID3v2 frame header which can be read from and * written to disk. @@ -64,32 +15,31 @@ export enum Id3v2FrameFlags { * when reading the frame, these optional fields are processed as well. Use {@link flags} to * determine if the frame contains these optional fields. */ -export class Id3v2FrameHeader { +export default class FrameHeader { private readonly _frameId: FrameIdentifier; private _dataLength: number; private _encryptionId: number; - private _flags: Id3v2FrameFlags; + private _flags: FrameFlags; private _frameSize: number; private _groupId: number; /** * Constructs and initializes a new instance by processing the data for the frame header. * @param id Identifier of the frame - * @param flags Flags to assign to the frame (if omitted, defaults to - * {@link Id3v2FrameFlags.None}) + * @param flags Flags to assign to the frame (if omitted, defaults to {@link FrameFlags.None}) * @param frameSize Size of the frame in bytes, excluding the size of the header (if omitted, * defaults to 0) */ // @TODO: This shouldn't be public? - public constructor(id: FrameIdentifier, flags: Id3v2FrameFlags = Id3v2FrameFlags.None, frameSize: number = 0) { + public constructor(id: FrameIdentifier, flags: FrameFlags = FrameFlags.None, frameSize: number = 0) { Guards.truthy(id, "id"); Guards.uint(frameSize, "frameSize"); this._frameId = id; this._frameSize = frameSize; - if (NumberUtils.hasFlag(flags, (Id3v2FrameFlags.Compression | Id3v2FrameFlags.Encryption))) { + if (NumberUtils.hasFlag(flags, (FrameFlags.Compression | FrameFlags.Encryption))) { throw new NotImplementedError("Argument invalid: Encryption and compression are not supported"); } @@ -97,14 +47,14 @@ export class Id3v2FrameHeader { } /** - * Constructs and initializes a new instance of {@link Id3v2FrameHeader} by reading it from raw + * Constructs and initializes a new instance of {@link FrameHeader} by reading it from raw * header data of a specified version. * @param data Raw data to build the new instance from. * If the data size is smaller than the size of a full header, the data is just treated as * a frame identifier and the remaining values are zeroed. @TODO: Why?? Why needs that functionality? * @param version ID3v2 version with which the data in `data` was encoded. */ - public static fromData(data: ByteVector, version: number): Id3v2FrameHeader { + public static fromData(data: ByteVector, version: number): FrameHeader { Guards.truthy(data, "data"); Guards.byte(version, "version"); Guards.betweenInclusive(version, 2, 4, "version"); @@ -176,7 +126,7 @@ export class Id3v2FrameHeader { break; } - return new Id3v2FrameHeader(frameId, flags, frameSize); + return new FrameHeader(frameId, flags, frameSize); } /** @@ -184,8 +134,8 @@ export class Id3v2FrameHeader { * provided frame identifier. * @param id Identifier for the frame */ - public static fromFrameIdentifier(id: FrameIdentifier): Id3v2FrameHeader { - return new Id3v2FrameHeader(id, Id3v2FrameFlags.None, 0); + public static fromFrameIdentifier(id: FrameIdentifier): FrameHeader { + return new FrameHeader(id, FrameFlags.None, 0); } // #region Properties @@ -212,7 +162,7 @@ export class Id3v2FrameHeader { * `undefined` if not set. */ public get encryptionId(): number|undefined { - return NumberUtils.hasFlag(this.flags, Id3v2FrameFlags.Encryption) + return NumberUtils.hasFlag(this.flags, FrameFlags.Encryption) ? this._encryptionId : undefined; } @@ -227,19 +177,19 @@ export class Id3v2FrameHeader { throw new NotImplementedError("Encryption and compression are not supported"); } else { this._encryptionId = value; - this._flags &= ~Id3v2FrameFlags.Encryption; + this._flags &= ~FrameFlags.Encryption; } } /** * Gets the flags applied to the current instance. */ - public get flags(): Id3v2FrameFlags { return this._flags; } + public get flags(): FrameFlags { return this._flags; } /** * @TODO: It should not be necessary to update the flags manually like this. * @internal */ - public set flags(value: Id3v2FrameFlags) { this._flags = value; } + public set flags(value: FrameFlags) { this._flags = value; } /** * Gets the identifier of the frame described by the current instance. @@ -266,7 +216,7 @@ export class Id3v2FrameHeader { * `undefined` if not set. */ public get groupId(): number | undefined { - return NumberUtils.hasFlag(this.flags, Id3v2FrameFlags.GroupingIdentity) + return NumberUtils.hasFlag(this.flags, FrameFlags.GroupingIdentity) ? this._groupId : undefined; } @@ -279,14 +229,14 @@ export class Id3v2FrameHeader { Guards.byteOptional(value, "value"); this._groupId = value; if (value !== undefined) { - this._flags |= Id3v2FrameFlags.GroupingIdentity; + this._flags |= FrameFlags.GroupingIdentity; } else { - this._flags &= ~Id3v2FrameFlags.GroupingIdentity; + this._flags &= ~FrameFlags.GroupingIdentity; } } public get isUnsynchronizationApplied(): boolean { - return NumberUtils.hasFlag(this._flags, Id3v2FrameFlags.Unsynchronized); + return NumberUtils.hasFlag(this._flags, FrameFlags.Unsynchronized); } // #endregion @@ -319,29 +269,29 @@ export class Id3v2FrameHeader { case 2: break; case 3: - if (NumberUtils.hasFlag(this._flags, Id3v2FrameFlags.Compression)) { + if (NumberUtils.hasFlag(this._flags, FrameFlags.Compression)) { this._dataLength = this.getFieldBytes(payloadBytes, position, 4).toUint(); position += 4; } - if (NumberUtils.hasFlag(this._flags, Id3v2FrameFlags.Encryption)) { + if (NumberUtils.hasFlag(this._flags, FrameFlags.Encryption)) { this._encryptionId = this.getFieldBytes(payloadBytes, position, 1).get(0); position++; } - if (NumberUtils.hasFlag(this._flags, Id3v2FrameFlags.GroupingIdentity)) { + if (NumberUtils.hasFlag(this._flags, FrameFlags.GroupingIdentity)) { this._groupId = this.getFieldBytes(payloadBytes, position, 1).get(0); position++; } break; case 4: - if (NumberUtils.hasFlag(this._flags, Id3v2FrameFlags.GroupingIdentity)) { + if (NumberUtils.hasFlag(this._flags, FrameFlags.GroupingIdentity)) { this._groupId = this.getFieldBytes(payloadBytes, position, 1).get(0); position++; } - if (NumberUtils.hasFlag(this._flags, Id3v2FrameFlags.Encryption)) { + if (NumberUtils.hasFlag(this._flags, FrameFlags.Encryption)) { this._encryptionId = this.getFieldBytes(payloadBytes, position, 1).get(0); position++; } - if (NumberUtils.hasFlag(this._flags, Id3v2FrameFlags.DataLengthIndicator)) { + if (NumberUtils.hasFlag(this._flags, FrameFlags.DataLengthIndicator)) { this._dataLength = SyncData.toUint(this.getFieldBytes(payloadBytes, position, 4)); position += 4; } @@ -353,8 +303,8 @@ export class Id3v2FrameHeader { return position; } - public clone(identifier?: FrameIdentifier): Id3v2FrameHeader { - const clone = new Id3v2FrameHeader(identifier ?? this.frameId); + public clone(identifier?: FrameIdentifier): FrameHeader { + const clone = new FrameHeader(identifier ?? this.frameId); clone._dataLength = this._dataLength; clone._encryptionId = this._encryptionId; clone._frameSize = this._frameSize; @@ -406,24 +356,24 @@ export class Id3v2FrameHeader { case 2: break; case 3: - if (NumberUtils.hasFlag(this._flags, Id3v2FrameFlags.Compression)) { + if (NumberUtils.hasFlag(this._flags, FrameFlags.Compression)) { throw new NotImplementedError("Compression is not supported."); } - if (NumberUtils.hasFlag(this._flags, Id3v2FrameFlags.Encryption)) { + if (NumberUtils.hasFlag(this._flags, FrameFlags.Encryption)) { throw new NotImplementedError("Encryption is not supported"); } - if (NumberUtils.hasFlag(this._flags, Id3v2FrameFlags.GroupingIdentity)) { + if (NumberUtils.hasFlag(this._flags, FrameFlags.GroupingIdentity)) { fieldVectors.push(ByteVector.fromByte(this._groupId)); } break; case 4: - if (NumberUtils.hasFlag(this._flags, Id3v2FrameFlags.GroupingIdentity)) { + if (NumberUtils.hasFlag(this._flags, FrameFlags.GroupingIdentity)) { fieldVectors.push(ByteVector.fromByte(this._groupId)); } - if (NumberUtils.hasFlag(this._flags, Id3v2FrameFlags.Encryption)) { + if (NumberUtils.hasFlag(this._flags, FrameFlags.Encryption)) { throw new NotImplementedError("Encryption is not supported"); } - if (NumberUtils.hasFlag(this._flags, Id3v2FrameFlags.DataLengthIndicator)) { + if (NumberUtils.hasFlag(this._flags, FrameFlags.DataLengthIndicator)) { fieldVectors.push(SyncData.fromUint(this._dataLength)); } break; diff --git a/src/id3v2/frames/genreFrame.ts b/src/id3v2/frames/genreFrame.ts index d0d597dd..e9431310 100644 --- a/src/id3v2/frames/genreFrame.ts +++ b/src/id3v2/frames/genreFrame.ts @@ -1,9 +1,9 @@ import Frame from "./frame"; +import FrameHeader from "./frameHeader"; import Genres from "../../genres"; import Id3v2Settings from "../id3v2Settings"; import {ByteVector, StringType} from "../../byteVector"; import {CorruptFileError} from "../../errors"; -import {Id3v2FrameHeader} from "./frameHeader"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards, StringUtils} from "../../utils"; @@ -21,7 +21,7 @@ export default class GenreFrame extends Frame { // #region Constructors - private constructor(header: Id3v2FrameHeader) { + private constructor(header: FrameHeader) { super(header); } @@ -31,7 +31,7 @@ export default class GenreFrame extends Frame { * @param fieldBytes Bytes that contain the fields of the frame * @param version ID3v2 version the frame was originally encoded with */ - public static fromFieldBytes(header: Id3v2FrameHeader, fieldBytes: ByteVector, version: number): GenreFrame { + public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: number): GenreFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); Guards.byte(version, "version"); @@ -126,7 +126,7 @@ export default class GenreFrame extends Frame { * {@link Id3v2Settings.defaultEncoding}. */ public static fromFields(text?: string[], encoding?: StringType): GenreFrame { - const frame = new GenreFrame(new Id3v2FrameHeader(FrameIdentifiers.TCON)); + const frame = new GenreFrame(new FrameHeader(FrameIdentifiers.TCON)); frame._textFields = text ?? []; frame._encoding = encoding ?? Id3v2Settings.defaultEncoding; diff --git a/src/id3v2/frames/musicCdIdentifierFrame.ts b/src/id3v2/frames/musicCdIdentifierFrame.ts index 6df87460..3b55fa54 100644 --- a/src/id3v2/frames/musicCdIdentifierFrame.ts +++ b/src/id3v2/frames/musicCdIdentifierFrame.ts @@ -1,6 +1,6 @@ import Frame from "./frame"; +import FrameHeader from "./frameHeader"; import {ByteVector} from "../../byteVector"; -import {Id3v2FrameHeader} from "./frameHeader"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; @@ -13,7 +13,7 @@ import {ArrayUtils, Guards} from "../../utils"; export default class MusicCdIdentifierFrame extends Frame { private _data: ByteVector; - private constructor(header: Id3v2FrameHeader) { + private constructor(header: FrameHeader) { super(header); } @@ -24,7 +24,7 @@ export default class MusicCdIdentifierFrame extends Frame { * @param version ID3v2 version the frame was originally encoded with */ public static fromFieldBytes( - header: Id3v2FrameHeader, + header: FrameHeader, fieldBytes: ByteVector, version: number ): MusicCdIdentifierFrame { @@ -43,7 +43,7 @@ export default class MusicCdIdentifierFrame extends Frame { * {@link ByteVector}. */ public static fromFields(data?: ByteVector): MusicCdIdentifierFrame { - const frame = new MusicCdIdentifierFrame(new Id3v2FrameHeader(FrameIdentifiers.MCDI)); + const frame = new MusicCdIdentifierFrame(new FrameHeader(FrameIdentifiers.MCDI)); frame._data = data ?? ByteVector.empty(); return frame; diff --git a/src/id3v2/frames/playCountFrame.ts b/src/id3v2/frames/playCountFrame.ts index 83b22bf2..e910f30b 100644 --- a/src/id3v2/frames/playCountFrame.ts +++ b/src/id3v2/frames/playCountFrame.ts @@ -1,7 +1,7 @@ import Frame from "./frame"; +import FrameHeader from "./frameHeader"; import {ByteVector} from "../../byteVector"; import {CorruptFileError, NotSupportedError} from "../../errors"; -import {Id3v2FrameHeader} from "./frameHeader"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; @@ -11,7 +11,7 @@ import {ArrayUtils, Guards} from "../../utils"; export default class PlayCountFrame extends Frame { private _playCount: bigint; - private constructor(header: Id3v2FrameHeader) { + private constructor(header: FrameHeader) { super(header); this._playCount = BigInt(0); } @@ -24,7 +24,7 @@ export default class PlayCountFrame extends Frame { * @param fieldBytes Bytes that contain the body of the frame * @param version ID3v2 version the frame was originally encoded with */ - public static fromFieldBytes(header: Id3v2FrameHeader, fieldBytes: ByteVector, version: number): PlayCountFrame { + public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: number): PlayCountFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); Guards.byte(version, "version"); @@ -51,7 +51,7 @@ export default class PlayCountFrame extends Frame { public static fromFields(playCount: bigint = BigInt(0)): PlayCountFrame { Guards.ulong(playCount, "playCount"); - const frame = new PlayCountFrame(new Id3v2FrameHeader(FrameIdentifiers.PCNT)); + const frame = new PlayCountFrame(new FrameHeader(FrameIdentifiers.PCNT)); frame._playCount = playCount; return frame; @@ -83,7 +83,7 @@ export default class PlayCountFrame extends Frame { /** @inheritDoc */ public clone(): Frame { - const frame = new PlayCountFrame(new Id3v2FrameHeader(FrameIdentifiers.PCNT)); + const frame = new PlayCountFrame(new FrameHeader(FrameIdentifiers.PCNT)); frame.playCount = this.playCount; return frame; } diff --git a/src/id3v2/frames/popularimeterFrame.ts b/src/id3v2/frames/popularimeterFrame.ts index 2a962432..3ca31fd9 100644 --- a/src/id3v2/frames/popularimeterFrame.ts +++ b/src/id3v2/frames/popularimeterFrame.ts @@ -1,7 +1,7 @@ import Frame from "./frame"; +import FrameHeader from "./frameHeader"; import {ByteVector, StringType} from "../../byteVector"; import {CorruptFileError, NotSupportedError} from "../../errors"; -import {Id3v2FrameHeader} from "./frameHeader"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; @@ -15,7 +15,7 @@ export default class PopularimeterFrame extends Frame { // #region Constructors - private constructor(header: Id3v2FrameHeader) { + private constructor(header: FrameHeader) { super(header); } @@ -26,7 +26,7 @@ export default class PopularimeterFrame extends Frame { * @param version ID3v2 version the frame was originally encoded with */ public static fromFieldBytes( - header: Id3v2FrameHeader, + header: FrameHeader, fieldBytes: ByteVector, version: number ): PopularimeterFrame { @@ -78,7 +78,7 @@ export default class PopularimeterFrame extends Frame { Guards.byteOptional(rating, "rating"); Guards.ulongOptional(playCount, "playCount"); - const frame = new PopularimeterFrame(new Id3v2FrameHeader(FrameIdentifiers.POPM)); + const frame = new PopularimeterFrame(new FrameHeader(FrameIdentifiers.POPM)); frame._playCount = playCount; frame._rating = rating ?? 0; frame._user = user ?? ""; diff --git a/src/id3v2/frames/privateFrame.ts b/src/id3v2/frames/privateFrame.ts index 3eff87b7..01614979 100644 --- a/src/id3v2/frames/privateFrame.ts +++ b/src/id3v2/frames/privateFrame.ts @@ -1,7 +1,7 @@ import Frame from "./frame"; +import FrameHeader from "./frameHeader"; import {ByteVector, StringType} from "../../byteVector"; import {CorruptFileError, NotImplementedError} from "../../errors"; -import {Id3v2FrameHeader} from "./frameHeader"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; @@ -16,7 +16,7 @@ export default class PrivateFrame extends Frame { // #region Constructors - private constructor(header: Id3v2FrameHeader) { + private constructor(header: FrameHeader) { super(header); } @@ -27,7 +27,7 @@ export default class PrivateFrame extends Frame { * @param fieldBytes Bytes that contain the fields of the frame * @param version ID3v2 version the frame was originally encoded with */ - public static fromFieldBytes(header: Id3v2FrameHeader, fieldBytes: ByteVector, version: number): PrivateFrame { + public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: number): PrivateFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); Guards.byte(version, "version"); @@ -55,7 +55,7 @@ export default class PrivateFrame extends Frame { * an empty {@link ByteVector}. */ public static fromFields(owner?: string, privateData?: ByteVector): PrivateFrame { - const frame = new PrivateFrame(new Id3v2FrameHeader(FrameIdentifiers.PRIV)); + const frame = new PrivateFrame(new FrameHeader(FrameIdentifiers.PRIV)); frame._owner = owner ?? ""; frame._privateData = privateData ?? ByteVector.empty(); diff --git a/src/id3v2/frames/relativeVolumeFrame.ts b/src/id3v2/frames/relativeVolumeFrame.ts index 24863795..2a841188 100644 --- a/src/id3v2/frames/relativeVolumeFrame.ts +++ b/src/id3v2/frames/relativeVolumeFrame.ts @@ -1,59 +1,10 @@ import Frame from "./frame"; +import FrameHeader from "./frameHeader"; import {ByteVector, StringType} from "../../byteVector"; -import {Id3v2FrameHeader} from "./frameHeader"; +import {ChannelType} from "../enums"; +import {CorruptFileError} from "../../errors"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards, NumberUtils} from "../../utils"; -import {CorruptFileError} from "../../errors"; - -/** - * Type of channel data to get from or set to a {@link RelativeVolumeFrame} object - */ -export enum ChannelType { - /** - * Channel data for some other speaker - */ - Other = 0x00, - - /** - * Channel data for the master volume - */ - MasterVolume = 0x01, - - /** - * Channel data for the front right speaker - */ - FrontRight = 0x02, - - /** - * Channel data for front left speaker - */ - FrontLeft = 0x03, - - /** - * Channel data for center right speaker - */ - BackRight = 0x04, - - /** - * Channel data for back left speaker - */ - BackLeft = 0x05, - - /** - * Channel data for front center speaker - */ - FrontCentre = 0x06, - - /** - * Channel data for back center speaker - */ - BackCenter = 0x07, - - /** - * Channel data for subwoofer - */ - Subwoofer = 0x08 -} /** * Represents the relative volume data that applies to a specific channel of the audio. @@ -204,7 +155,7 @@ export class RelativeVolumeFrame extends Frame { // #region Constructors - private constructor(header: Id3v2FrameHeader) { + private constructor(header: FrameHeader) { super(header); // Initialize the channel data array @@ -220,11 +171,7 @@ export class RelativeVolumeFrame extends Frame { * @param fieldBytes Bytes that contain the body of the frame * @param version ID3v2 version the frame was originally encoded with */ - public static fromFieldBytes( - header: Id3v2FrameHeader, - fieldBytes: ByteVector, - version: number - ): RelativeVolumeFrame { + public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: number): RelativeVolumeFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); Guards.byte(version, "version"); @@ -278,7 +225,7 @@ export class RelativeVolumeFrame extends Frame { * not provided, the internal channel data will be unset for all channels. */ public static fromFields(identification?: string, channels?: ChannelData[]): RelativeVolumeFrame { - const frame = new RelativeVolumeFrame(new Id3v2FrameHeader(FrameIdentifiers.RVA2)); + const frame = new RelativeVolumeFrame(new FrameHeader(FrameIdentifiers.RVA2)); frame._identification = identification ?? ""; if (!!channels) { // Replace blank channel data with the provided channel data. diff --git a/src/id3v2/frames/synchronizedLyricsFrame.ts b/src/id3v2/frames/synchronizedLyricsFrame.ts index f699e97f..ba53d0b6 100644 --- a/src/id3v2/frames/synchronizedLyricsFrame.ts +++ b/src/id3v2/frames/synchronizedLyricsFrame.ts @@ -1,11 +1,11 @@ import Frame from "./frame"; +import FrameHeader from "./frameHeader"; import Id3v2Settings from "../id3v2Settings"; import {ByteVector, StringType} from "../../byteVector"; +import {SynchronizedTextType, TimestampFormat} from "../enums"; import {CorruptFileError} from "../../errors"; -import {Id3v2FrameHeader} from "./frameHeader"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; -import {SynchronizedTextType, TimestampFormat} from "../utilTypes"; /** * This structure contains a single entry in a {@link SynchronizedLyricsFrame} object. @@ -83,7 +83,7 @@ export class SynchronizedLyricsFrame extends Frame { // #region Constructors - private constructor(header: Id3v2FrameHeader) { + private constructor(header: FrameHeader) { super(header); } @@ -94,7 +94,7 @@ export class SynchronizedLyricsFrame extends Frame { * @param version ID3v2 version the frame was originally encoded with */ public static fromFieldBytes( - header: Id3v2FrameHeader, + header: FrameHeader, fieldBytes: ByteVector, version: number ): SynchronizedLyricsFrame { @@ -193,7 +193,7 @@ export class SynchronizedLyricsFrame extends Frame { encoding?: StringType, timestampFormat?: TimestampFormat ): SynchronizedLyricsFrame { - const frame = new SynchronizedLyricsFrame(new Id3v2FrameHeader(FrameIdentifiers.SYLT)); + const frame = new SynchronizedLyricsFrame(new FrameHeader(FrameIdentifiers.SYLT)); frame._description = description ?? ""; frame._format = timestampFormat ?? TimestampFormat.Unknown; frame._language = language ?? "XXX"; // @TODO: Should this be `unk`? diff --git a/src/id3v2/frames/termsOfUseFrame.ts b/src/id3v2/frames/termsOfUseFrame.ts index 4b308d2e..31e05fa1 100644 --- a/src/id3v2/frames/termsOfUseFrame.ts +++ b/src/id3v2/frames/termsOfUseFrame.ts @@ -1,8 +1,8 @@ import Frame from "./frame"; +import FrameHeader from "./frameHeader"; import Id3v2Settings from "../id3v2Settings"; import {ByteVector, StringType} from "../../byteVector"; import {CorruptFileError} from "../../errors"; -import {Id3v2FrameHeader} from "./frameHeader"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; @@ -13,7 +13,7 @@ export default class TermsOfUseFrame extends Frame { // #region Constructors - private constructor(header: Id3v2FrameHeader) { + private constructor(header: FrameHeader) { super(header); } @@ -23,7 +23,7 @@ export default class TermsOfUseFrame extends Frame { * @param fieldBytes Bytes that contain the fields of the frame * @param version ID3v2 version the frame was originally encoded with */ - public static fromFieldBytes(header: Id3v2FrameHeader, fieldBytes: ByteVector, version: number): TermsOfUseFrame { + public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: number): TermsOfUseFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); Guards.byte(version, "version"); @@ -54,7 +54,7 @@ export default class TermsOfUseFrame extends Frame { * defaults to {@link Id3v2Settings.defaultEncoding} */ public static fromFields(text?: string, language?: string, textEncoding?: StringType): TermsOfUseFrame { - const f = new TermsOfUseFrame(new Id3v2FrameHeader(FrameIdentifiers.USER)); + const f = new TermsOfUseFrame(new FrameHeader(FrameIdentifiers.USER)); f._language = language ?? "XXX"; // @TODO: Should this be "unk"? f._text = text ?? ""; f._textEncoding = textEncoding ?? Id3v2Settings.defaultEncoding; diff --git a/src/id3v2/frames/textInformationFrame.ts b/src/id3v2/frames/textInformationFrame.ts index c59bb6ba..13f92bf4 100644 --- a/src/id3v2/frames/textInformationFrame.ts +++ b/src/id3v2/frames/textInformationFrame.ts @@ -1,10 +1,10 @@ import Frame from "./frame"; +import FrameHeader from "./frameHeader"; import Id3v2Settings from "../id3v2Settings"; import {ByteVector, StringType} from "../../byteVector"; -import {Id3v2FrameHeader} from "./frameHeader"; +import {CorruptFileError} from "../../errors"; import {FrameIdentifier, FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; -import {CorruptFileError} from "../../errors"; /** * This class provides support for ID3v2 text information frames (section 4.2) covering `T000` to @@ -148,7 +148,7 @@ export default class TextInformationFrame extends Frame { // #region Constructors - private constructor(header: Id3v2FrameHeader) { + private constructor(header: FrameHeader) { super(header); } @@ -158,11 +158,7 @@ export default class TextInformationFrame extends Frame { * @param fieldBytes Bytes that contain the fields of the frame * @param version ID3v2 version the frame was originally encoded with */ - public static fromFieldBytes( - header: Id3v2FrameHeader, - fieldBytes: ByteVector, - version: number - ): TextInformationFrame { + public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: number): TextInformationFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); Guards.byte(version, "version"); @@ -218,7 +214,7 @@ export default class TextInformationFrame extends Frame { ): TextInformationFrame { Guards.truthy(identifier, "identifier"); - const frame = new TextInformationFrame(new Id3v2FrameHeader(identifier)); + const frame = new TextInformationFrame(new FrameHeader(identifier)); frame._encoding = textEncoding ?? Id3v2Settings.defaultEncoding; frame._textFields = text ?? []; @@ -293,11 +289,11 @@ export default class TextInformationFrame extends Frame { } const output = ByteVector.empty(); - let frame = new TextInformationFrame(new Id3v2FrameHeader(FrameIdentifiers.TYER)); + let frame = new TextInformationFrame(new FrameHeader(FrameIdentifiers.TYER)); frame.text = [text.substring(0, 4)]; output.addByteVector(frame.render(version)); - frame = new TextInformationFrame(new Id3v2FrameHeader(FrameIdentifiers.TDAT)); + frame = new TextInformationFrame(new FrameHeader(FrameIdentifiers.TDAT)); frame.text = [text.substring(5, 7) + text.substring(8, 10)]; output.addByteVector(frame.render(version)); @@ -305,7 +301,7 @@ export default class TextInformationFrame extends Frame { return output; } - frame = new TextInformationFrame(new Id3v2FrameHeader(FrameIdentifiers.TIME)); + frame = new TextInformationFrame(new FrameHeader(FrameIdentifiers.TIME)); frame.text = [text.substring(11, 13) + text.substring(14, 16)]; output.addByteVector(frame.render(version)); diff --git a/src/id3v2/frames/uniqueFileIdentifierFrame.ts b/src/id3v2/frames/uniqueFileIdentifierFrame.ts index d1438461..a20247d4 100644 --- a/src/id3v2/frames/uniqueFileIdentifierFrame.ts +++ b/src/id3v2/frames/uniqueFileIdentifierFrame.ts @@ -1,7 +1,7 @@ import Frame from "./frame"; +import FrameHeader from "./frameHeader"; import {ByteVector, StringType} from "../../byteVector"; import {CorruptFileError} from "../../errors"; -import {Id3v2FrameHeader} from "./frameHeader"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; @@ -14,7 +14,7 @@ export default class UniqueFileIdentifierFrame extends Frame { // #region Constructors - private constructor(header: Id3v2FrameHeader) { + private constructor(header: FrameHeader) { super(header); } @@ -25,7 +25,7 @@ export default class UniqueFileIdentifierFrame extends Frame { * @param version ID3v2 version the frame was originally encoded with */ public static fromFieldBytes( - header: Id3v2FrameHeader, + header: FrameHeader, fieldBytes: ByteVector, version: number ): UniqueFileIdentifierFrame { @@ -61,7 +61,7 @@ export default class UniqueFileIdentifierFrame extends Frame { throw new Error("Argument out of range: Identifier cannot be longer than 64 bytes"); } - const frame = new UniqueFileIdentifierFrame(new Id3v2FrameHeader(FrameIdentifiers.UFID)); + const frame = new UniqueFileIdentifierFrame(new FrameHeader(FrameIdentifiers.UFID)); frame._owner = owner ?? ""; frame._identifier = identifier ?? ByteVector.empty(); @@ -103,7 +103,7 @@ export default class UniqueFileIdentifierFrame extends Frame { /** @inheritDoc */ public clone(): Frame { - const frame = new UniqueFileIdentifierFrame(new Id3v2FrameHeader(FrameIdentifiers.UFID)); + const frame = new UniqueFileIdentifierFrame(new FrameHeader(FrameIdentifiers.UFID)); frame._owner = this._owner; frame._identifier = this._identifier?.toByteVector(); return frame; diff --git a/src/id3v2/frames/unknownFrame.ts b/src/id3v2/frames/unknownFrame.ts index 740d58ed..067b34bb 100644 --- a/src/id3v2/frames/unknownFrame.ts +++ b/src/id3v2/frames/unknownFrame.ts @@ -1,6 +1,6 @@ import Frame from "./frame"; +import FrameHeader from "./frameHeader"; import {ByteVector} from "../../byteVector"; -import {Id3v2FrameHeader} from "./frameHeader"; import {FrameIdentifier} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; @@ -8,7 +8,7 @@ import {ArrayUtils, Guards} from "../../utils"; * Fallback type when no other frame class works for a given frame. */ export default class UnknownFrame extends Frame { - private constructor(header: Id3v2FrameHeader) { + private constructor(header: FrameHeader) { super(header); } @@ -18,7 +18,7 @@ export default class UnknownFrame extends Frame { * @param fieldBytes Bytes that contain the body of the frame * @param version ID3v2 version the frame was originally encoded with */ - public static fromFieldBytes(header: Id3v2FrameHeader, fieldBytes: ByteVector, version: number): UnknownFrame { + public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: number): UnknownFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); Guards.byte(version, "version"); @@ -37,7 +37,7 @@ export default class UnknownFrame extends Frame { public static fromFields(identifier: FrameIdentifier, data?: ByteVector): UnknownFrame { Guards.truthy(identifier, "identifier"); - const frame = new UnknownFrame(new Id3v2FrameHeader(identifier)); + const frame = new UnknownFrame(new FrameHeader(identifier)); frame.data = data ?? ByteVector.empty(); return frame; diff --git a/src/id3v2/frames/unsynchronizedLyricsFrame.ts b/src/id3v2/frames/unsynchronizedLyricsFrame.ts index 584cc545..e0c74004 100644 --- a/src/id3v2/frames/unsynchronizedLyricsFrame.ts +++ b/src/id3v2/frames/unsynchronizedLyricsFrame.ts @@ -1,8 +1,8 @@ import Frame from "./frame"; +import FrameHeader from "./frameHeader"; import Id3v2Settings from "../id3v2Settings"; import {ByteVector, StringType} from "../../byteVector"; import {CorruptFileError} from "../../errors"; -import {Id3v2FrameHeader} from "./frameHeader"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; @@ -17,7 +17,7 @@ export default class UnsynchronizedLyricsFrame extends Frame { // #region Constructors - private constructor(header: Id3v2FrameHeader) { + private constructor(header: FrameHeader) { super(header); } @@ -28,7 +28,7 @@ export default class UnsynchronizedLyricsFrame extends Frame { * @param version ID3v2 version the frame was originally encoded with */ public static fromFieldBytes( - header: Id3v2FrameHeader, + header: FrameHeader, fieldBytes: ByteVector, version: number ): UnsynchronizedLyricsFrame { @@ -83,7 +83,7 @@ export default class UnsynchronizedLyricsFrame extends Frame { language?: string, encoding?: StringType ): UnsynchronizedLyricsFrame { - const frame = new UnsynchronizedLyricsFrame(new Id3v2FrameHeader(FrameIdentifiers.USLT)); + const frame = new UnsynchronizedLyricsFrame(new FrameHeader(FrameIdentifiers.USLT)); frame._description = description ?? ""; frame._language = language ?? "XXX"; frame._text = text ?? ""; diff --git a/src/id3v2/frames/urlLinkFrame.ts b/src/id3v2/frames/urlLinkFrame.ts index df1a528a..172d0fa7 100644 --- a/src/id3v2/frames/urlLinkFrame.ts +++ b/src/id3v2/frames/urlLinkFrame.ts @@ -1,6 +1,6 @@ import Frame from "./frame"; +import FrameHeader from "./frameHeader"; import {ByteVector, StringType} from "../../byteVector"; -import {Id3v2FrameHeader} from "./frameHeader"; import {FrameIdentifier} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; @@ -36,7 +36,7 @@ export default class UrlLinkFrame extends Frame { // #region Constructors - private constructor(header: Id3v2FrameHeader) { + private constructor(header: FrameHeader) { super(header); } @@ -46,7 +46,7 @@ export default class UrlLinkFrame extends Frame { * @param fieldBytes Bytes that contain the fields of the frame * @param version ID3v2 version the frame was originally encoded with */ - public static fromFieldBytes(header: Id3v2FrameHeader, fieldBytes: ByteVector, version: number): UrlLinkFrame { + public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: number): UrlLinkFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); Guards.byte(version, "version"); @@ -68,7 +68,7 @@ export default class UrlLinkFrame extends Frame { public static fromFields(ident: FrameIdentifier, text?: string): UrlLinkFrame { Guards.truthy(ident, "ident"); - const frame = new UrlLinkFrame(new Id3v2FrameHeader(ident)); + const frame = new UrlLinkFrame(new FrameHeader(ident)); frame._url = text ?? ""; return frame; diff --git a/src/id3v2/frames/userTextInformationFrame.ts b/src/id3v2/frames/userTextInformationFrame.ts index 4eabddac..afff5f00 100644 --- a/src/id3v2/frames/userTextInformationFrame.ts +++ b/src/id3v2/frames/userTextInformationFrame.ts @@ -1,8 +1,8 @@ import Frame from "./frame"; +import FrameHeader from "./frameHeader"; import Id3v2Settings from "../id3v2Settings"; import {ByteVector, StringType} from "../../byteVector"; import {CorruptFileError} from "../../errors"; -import {Id3v2FrameHeader} from "./frameHeader"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; @@ -13,7 +13,7 @@ export default class UserTextInformationFrame extends Frame { // #region Constructors - private constructor(header: Id3v2FrameHeader) { + private constructor(header: FrameHeader) { super(header); } @@ -24,7 +24,7 @@ export default class UserTextInformationFrame extends Frame { * @param version ID3v2 version the frame was originally encoded with */ public static fromFieldBytes( - header: Id3v2FrameHeader, + header: FrameHeader, fieldBytes: ByteVector, version: number ): UserTextInformationFrame { @@ -70,7 +70,7 @@ export default class UserTextInformationFrame extends Frame { */ public static fromFields(description?: string, text?: string[], encoding?: StringType ): UserTextInformationFrame { - const frame = new UserTextInformationFrame(new Id3v2FrameHeader(FrameIdentifiers.TXXX)); + const frame = new UserTextInformationFrame(new FrameHeader(FrameIdentifiers.TXXX)); frame._encoding = encoding ?? Id3v2Settings.defaultEncoding; frame._description = description ?? ""; frame._textFields = text ?? []; diff --git a/src/id3v2/frames/userUrlLinkFrame.ts b/src/id3v2/frames/userUrlLinkFrame.ts index 1c362b09..e7bac4f8 100644 --- a/src/id3v2/frames/userUrlLinkFrame.ts +++ b/src/id3v2/frames/userUrlLinkFrame.ts @@ -1,7 +1,7 @@ import Frame from "./frame"; +import FrameHeader from "./frameHeader"; import Id3v2Settings from "../id3v2Settings"; import {ByteVector, StringType} from "../../byteVector"; -import {Id3v2FrameHeader} from "./frameHeader"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; @@ -15,7 +15,7 @@ export default class UserUrlLinkFrame extends Frame { // #region Constructors - private constructor(header: Id3v2FrameHeader) { + private constructor(header: FrameHeader) { super(header); } @@ -25,7 +25,7 @@ export default class UserUrlLinkFrame extends Frame { * @param fieldBytes Bytes that contain the fields of the frame * @param version ID3v2 version the frame was originally encoded with */ - public static fromFieldBytes(header: Id3v2FrameHeader, fieldBytes: ByteVector, version: number): UserUrlLinkFrame { + public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: number): UserUrlLinkFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); Guards.byte(version, "version"); @@ -80,7 +80,7 @@ export default class UserUrlLinkFrame extends Frame { * @param url Optional, URL to store in the frame. If omitted, defaults to `""`. */ public static fromFields(description?: string, url?: string): UserUrlLinkFrame { - const frame = new UserUrlLinkFrame(new Id3v2FrameHeader(FrameIdentifiers.WXXX)); + const frame = new UserUrlLinkFrame(new FrameHeader(FrameIdentifiers.WXXX)); frame._description = description ?? ""; frame._url = url ?? ""; return frame; diff --git a/src/id3v2/id3v2Tag.ts b/src/id3v2/id3v2Tag.ts index 5a8217d1..953103c8 100644 --- a/src/id3v2/id3v2Tag.ts +++ b/src/id3v2/id3v2Tag.ts @@ -2,22 +2,22 @@ import AttachmentFrame from "./frames/attachmentFrame"; import CommentsFrame from "./frames/commentsFrame"; import Frame from "./frames/frame"; import GenreFrame from "./frames/genreFrame"; -import Id3v2ExtendedHeader from "./id3v2ExtendedHeader"; -import Id3v2TagFooter from "./id3v2TagFooter"; +import Id3v2ExtendedHeader from "./tagHeaderExtended"; import Id3v2Settings from "./id3v2Settings"; import SyncData from "./syncData"; +import TagFooter from "./tagFooter"; +import TagHeader from "./tagHeader"; import TextInformationFrame from "./frames/textInformationFrame"; import UniqueFileIdentifierFrame from "./frames/uniqueFileIdentifierFrame"; import UnsynchronizedLyricsFrame from "./frames/unsynchronizedLyricsFrame"; import UrlLinkFrame from "./frames/urlLinkFrame"; import UserTextInformationFrame from "./frames/userTextInformationFrame"; import {ByteVector, StringType} from "../byteVector"; +import {FrameFlags, TagFlags} from "./enums"; import {CorruptFileError, NotImplementedError, NotSupportedError} from "../errors"; import {File, ReadStyle} from "../file"; import {Id3v2FrameFactory} from "./frames/frameFactory"; import {FrameIdentifier, FrameIdentifiers} from "./frameIdentifiers"; -import {Id3v2FrameFlags} from "./frames/frameHeader"; -import {Id3v2TagHeader, Id3v2TagHeaderFlags} from "./id3v2TagHeader"; import {IPicture} from "../picture"; import {Tag, TagTypes} from "../tag"; import {DateUtils, Guards, NumberUtils} from "../utils"; @@ -31,7 +31,7 @@ export default class Id3v2Tag extends Tag { private _extendedHeader: Id3v2ExtendedHeader; private _frameList: Frame[] = []; - private _header: Id3v2TagHeader; + private _header: TagHeader; private _performersRole: string[]; // #region Constructors @@ -45,7 +45,7 @@ export default class Id3v2Tag extends Tag { */ public static fromEmpty(): Id3v2Tag { const tag = new Id3v2Tag(); - tag._header = new Id3v2TagHeader(0, 0, Id3v2TagHeaderFlags.None, 0); + tag._header = new TagHeader(0, 0, TagFlags.None, 0); return tag; } @@ -62,7 +62,7 @@ export default class Id3v2Tag extends Tag { } const tag = new Id3v2Tag(); - tag._header = Id3v2TagHeader.fromData(data); + tag._header = TagHeader.fromData(data); // If the tag size is 0, then this is an invalid tag. Tags must contain at least one frame if (tag._header.tagSize === 0) { @@ -143,13 +143,13 @@ export default class Id3v2Tag extends Tag { /** * Gets the header flags applied to the current instance. */ - public get flags(): Id3v2TagHeaderFlags { return this._header.flags; } + public get flags(): TagFlags { return this._header.flags; } /** * Sets the header flags applied to the current instance - * @param value Bitwise combined {@link Id3v2TagHeaderFlags} value containing flags applied to the + * @param value Bitwise combined {@link TagFlags} value containing flags applied to the * current instance. */ - public set flags(value: Id3v2TagHeaderFlags) { this._header.flags = value; } + public set flags(value: TagFlags) { this._header.flags = value; } /** * Gets all frames contained in the current instance. @@ -1117,23 +1117,23 @@ export default class Id3v2Tag extends Tag { // We need to render the "tag data" first so that we have to correct size to render in the // tag's header. The "tag data" (everything that is included in Header.tagSize) includes // the extended header, frames and padding, but does not include the tag's header or footer - const hasFooter = (this._header.flags & Id3v2TagHeaderFlags.FooterPresent) !== 0; - const unsyncAtFrameLevel = (this._header.flags & Id3v2TagHeaderFlags.Unsynchronization) !== 0 + const hasFooter = (this._header.flags & TagFlags.FooterPresent) !== 0; + const unsyncAtFrameLevel = (this._header.flags & TagFlags.Unsynchronization) !== 0 && this.version >= 4; - const unsyncAtTagLevel = (this._header.flags & Id3v2TagHeaderFlags.Unsynchronization) !== 0 + const unsyncAtTagLevel = (this._header.flags & TagFlags.Unsynchronization) !== 0 && this.version < 4; this._header.majorVersion = hasFooter ? 4 : this.version; // TODO: Render the extended header - this._header.flags &= ~Id3v2TagHeaderFlags.ExtendedHeader; + this._header.flags &= ~TagFlags.ExtendedHeader; // Loop through the frames rendering them and adding them to tag data const renderedFrames = this._frameList.map((frame) => { if (unsyncAtFrameLevel) { - frame.flags |= Id3v2FrameFlags.Unsynchronized; + frame.flags |= FrameFlags.Unsynchronized; } - if ((frame.flags & Id3v2FrameFlags.TagAlterPreservation) !== 0 ) { + if ((frame.flags & FrameFlags.TagAlterPreservation) !== 0 ) { return undefined; } @@ -1176,7 +1176,7 @@ export default class Id3v2Tag extends Tag { let footerBytes; if (hasFooter) { - footerBytes = Id3v2TagFooter.fromHeader(this._header).render(); + footerBytes = TagFooter.fromHeader(this._header).render(); } return ByteVector.concatenate( @@ -1217,7 +1217,7 @@ export default class Id3v2Tag extends Tag { // Determine if the entire tag needs to be resynchronized. // @TODO: How important is it to check if the version is < 4? const fullTagUnsync = this.version < 4 && - NumberUtils.hasFlag(this._header.flags, Id3v2TagHeaderFlags.Unsynchronization); + NumberUtils.hasFlag(this._header.flags, TagFlags.Unsynchronization); // Resynchronize the entire tag if required if (fullTagUnsync) { @@ -1231,7 +1231,7 @@ export default class Id3v2Tag extends Tag { // Determine if the entire tag needs to be resynchronized. // @TODO: How important is it to check if the version is < 4? const fullTagUnsync = this.version < 4 && - NumberUtils.hasFlag(this._header.flags, Id3v2TagHeaderFlags.Unsynchronization); + NumberUtils.hasFlag(this._header.flags, TagFlags.Unsynchronization); // 1) Resynchronize the entire tag if required if (fullTagUnsync) { @@ -1246,7 +1246,7 @@ export default class Id3v2Tag extends Tag { let position = offset; // 2) Read extended header if required - if (NumberUtils.hasFlag(this._header.flags, Id3v2TagHeaderFlags.ExtendedHeader)) { + if (NumberUtils.hasFlag(this._header.flags, TagFlags.ExtendedHeader)) { // Extended header exists, read it and skip over it this._extendedHeader = Id3v2ExtendedHeader.fromFile(file, position, this.version); position += this._extendedHeader.size; @@ -1293,7 +1293,7 @@ export default class Id3v2Tag extends Tag { let position = 0; // 1) Check for extended header - if (NumberUtils.hasFlag(this._header.flags, Id3v2TagHeaderFlags.ExtendedHeader)) { + if (NumberUtils.hasFlag(this._header.flags, TagFlags.ExtendedHeader)) { // Extended header exists, read it and skip over it this._extendedHeader = Id3v2ExtendedHeader.fromData(data, this.version); position += this._extendedHeader.size; @@ -1338,7 +1338,7 @@ export default class Id3v2Tag extends Tag { file.seek(position); const headerBlock = file.readBlock(Id3v2Settings.headerSize); - this._header = Id3v2TagHeader.fromData(headerBlock); + this._header = TagHeader.fromData(headerBlock); // If the tag size is 0, then this is an invalid tag. Tags must contain at least one frame. if (this._header.tagSize === 0) { @@ -1353,7 +1353,7 @@ export default class Id3v2Tag extends Tag { file.seek(position - Id3v2Settings.footerSize); const footerBlock = file.readBlock(Id3v2Settings.footerSize); - const footer = Id3v2TagFooter.fromData(footerBlock); + const footer = TagFooter.fromData(footerBlock); position -= footer.completeTagSize; this.readFromStart(file, position, style); diff --git a/src/id3v2/id3v2TagFooter.ts b/src/id3v2/tagFooter.ts similarity index 87% rename from src/id3v2/id3v2TagFooter.ts rename to src/id3v2/tagFooter.ts index 8edc4b35..2bc2d7ec 100644 --- a/src/id3v2/id3v2TagFooter.ts +++ b/src/id3v2/tagFooter.ts @@ -1,21 +1,22 @@ import Id3v2Settings from "./id3v2Settings"; import SyncData from "./syncData"; +import TagHeader from "./tagHeader"; import {ByteVector, StringType} from "../byteVector"; +import {TagFlags} from "./enums"; import {CorruptFileError} from "../errors"; -import {Id3v2TagHeader, Id3v2TagHeaderFlags} from "./id3v2TagHeader"; import {Guards, NumberUtils} from "../utils"; /** * This class provides a representation of an ID3v2 tag footer which can be read from and written * to disk. */ -export default class Id3v2TagFooter { +export default class TagFooter { /** * Identifier used to recognize an ID3v2 footer. */ public static readonly FILE_IDENTIFIER = ByteVector.fromString("3DI", StringType.Latin1).makeReadOnly(); - private _flags: Id3v2TagHeaderFlags = Id3v2TagHeaderFlags.FooterPresent; + private _flags: TagFlags = TagFlags.FooterPresent; private _majorVersion: number = 0; private _revisionNumber: number = 0; private _tagSize: number = 0; @@ -24,16 +25,16 @@ export default class Id3v2TagFooter { * Constructs and initializes a new instance by reading it from raw footer data. * @param data Raw data to build the instance from */ - public static fromData(data: ByteVector): Id3v2TagFooter { + public static fromData(data: ByteVector): TagFooter { Guards.truthy(data, "data"); if (data.length < Id3v2Settings.footerSize) { throw new CorruptFileError("Provided data is smaller than object size."); } - if (!data.startsWith(Id3v2TagFooter.FILE_IDENTIFIER)) { + if (!data.startsWith(TagFooter.FILE_IDENTIFIER)) { throw new CorruptFileError("Provided data does not start with the file identifier"); } - const footer = new Id3v2TagFooter(); + const footer = new TagFooter(); footer._majorVersion = data.get(3); footer._revisionNumber = data.get(4); footer._flags = data.get(5); @@ -65,13 +66,13 @@ export default class Id3v2TagFooter { * same tag. * @param header Header from which to base the new footer */ - public static fromHeader(header: Id3v2TagHeader): Id3v2TagFooter { + public static fromHeader(header: TagHeader): TagFooter { Guards.truthy(header, "header"); - const footer = new Id3v2TagFooter(); + const footer = new TagFooter(); footer._majorVersion = header.majorVersion; footer._revisionNumber = header.revisionNumber; - footer._flags = header.flags | Id3v2TagHeaderFlags.FooterPresent; + footer._flags = header.flags | TagFlags.FooterPresent; footer._tagSize = header.tagSize; return footer; @@ -90,18 +91,18 @@ export default class Id3v2TagFooter { /** * Gets the flags applied to the current instance. */ - public get flags(): Id3v2TagHeaderFlags { return this._flags; } + public get flags(): TagFlags { return this._flags; } /** * Sets the flags applied to the current instance. * @param value Bitwise combined {@link Id3v2TagHeaderFlags} value containing the flags to apply * to the current instance. */ - public set flags(value: Id3v2TagHeaderFlags) { - const version3Flags = Id3v2TagHeaderFlags.ExtendedHeader | Id3v2TagHeaderFlags.ExperimentalIndicator; + public set flags(value: TagFlags) { + const version3Flags = TagFlags.ExtendedHeader | TagFlags.ExperimentalIndicator; if (NumberUtils.hasFlag(value, version3Flags) && this.majorVersion < 3) { throw new Error("Feature only supported in version 2.3+"); } - const version4Flags = Id3v2TagHeaderFlags.FooterPresent; + const version4Flags = TagFlags.FooterPresent; if (NumberUtils.hasFlag(value, version4Flags) && this.majorVersion < 4) { throw new Error("Feature only supported in version 2.4+"); } @@ -174,7 +175,7 @@ export default class Id3v2TagFooter { */ public render(): ByteVector { return ByteVector.concatenate( - Id3v2TagFooter.FILE_IDENTIFIER, + TagFooter.FILE_IDENTIFIER, this.majorVersion, this.revisionNumber, this.flags, diff --git a/src/id3v2/id3v2TagHeader.ts b/src/id3v2/tagHeader.ts similarity index 80% rename from src/id3v2/id3v2TagHeader.ts rename to src/id3v2/tagHeader.ts index 3039fb62..a39e8af3 100644 --- a/src/id3v2/id3v2TagHeader.ts +++ b/src/id3v2/tagHeader.ts @@ -1,51 +1,21 @@ import Id3v2Settings from "./id3v2Settings"; import SyncData from "./syncData"; import {ByteVector, StringType} from "../byteVector"; +import {TagFlags} from "./enums"; import {CorruptFileError} from "../errors"; import {Guards, NumberUtils} from "../utils"; -/** - * Indicates the flags applied to a {@link Id3v2TagHeader} object. - */ -export enum Id3v2TagHeaderFlags { - /** - * The header contains no flags. - */ - None = 0x0, - - /** - * The tag described by the header contains a footer. - */ - FooterPresent = 0x10, - - /** - * The tag described by the header is experimental. - */ - ExperimentalIndicator = 0x20, - - /** - * The tag described by the header contains an extended header. - */ - ExtendedHeader = 0x40, - - /** - * The tag described by the header has been unsynchronized using the ID3v2 unsynchronization - * scheme. - */ - Unsynchronization = 0x80, -} - /** * This class provides a representation of an ID3v2 tag header which can be read from and written * to disk. */ -export class Id3v2TagHeader { +export default class TagHeader { /** * The identifier used to recognize an ID3v2 header. */ public static readonly FILE_IDENTIFIER = ByteVector.fromString("ID3", StringType.Latin1).makeReadOnly(); - private _flags: Id3v2TagHeaderFlags = Id3v2TagHeaderFlags.None; + private _flags: TagFlags = TagFlags.None; private _majorVersion: number = 0; private _revisionNumber: number = 0; private _tagSize: number = 0; @@ -60,7 +30,7 @@ export class Id3v2TagHeader { * @param tagSize Size of the tag in bytes as it currently exists on the disk. See {@link tagSize}. * @internal */ - public constructor(majorVersion: number, revisionVersion: number, flags: Id3v2TagHeaderFlags, tagSize: number) { + public constructor(majorVersion: number, revisionVersion: number, flags: TagFlags, tagSize: number) { this._majorVersion = majorVersion; this.flags = flags; @@ -72,12 +42,12 @@ export class Id3v2TagHeader { * Constructs and initializes a new instance by reading it from the raw header data. * @param data Object containing the raw data to build the new instance from. */ - public static fromData(data: ByteVector): Id3v2TagHeader { + public static fromData(data: ByteVector): TagHeader { Guards.truthy(data, "data"); if (data.length < Id3v2Settings.headerSize) { throw new CorruptFileError("Provided data is smaller than object size"); } - if (!data.startsWith(Id3v2TagHeader.FILE_IDENTIFIER)) { + if (!data.startsWith(TagHeader.FILE_IDENTIFIER)) { throw new CorruptFileError("Provided data does not start with the file identifier"); } @@ -104,7 +74,7 @@ export class Id3v2TagHeader { } const tagSize = SyncData.toUint(data.subarray(6, 4)); - return new Id3v2TagHeader(majorVersion, revisionNumber, flags, tagSize); + return new TagHeader(majorVersion, revisionNumber, flags, tagSize); } // #endregion @@ -116,7 +86,7 @@ export class Id3v2TagHeader { * and footer. */ public get completeTagSize(): number { - return NumberUtils.hasFlag(this._flags, Id3v2TagHeaderFlags.FooterPresent) + return NumberUtils.hasFlag(this._flags, TagFlags.FooterPresent) ? this.tagSize + Id3v2Settings.headerSize + Id3v2Settings.footerSize : this.tagSize + Id3v2Settings.headerSize; } @@ -124,19 +94,19 @@ export class Id3v2TagHeader { /** * Gets the flags applied to the current instance. */ - public get flags(): Id3v2TagHeaderFlags { return this._flags; } + public get flags(): TagFlags { return this._flags; } /** * Sets the flags applied to the current instance. * @param value Bitwise combined {@link Id3v2TagHeaderFlags} value containing the flags to apply to the * current instance. */ - public set flags(value: Id3v2TagHeaderFlags) { + public set flags(value: TagFlags) { // @TODO: Does it make sense to check for flags for major version <4? - const version3Flags = Id3v2TagHeaderFlags.ExtendedHeader | Id3v2TagHeaderFlags.ExperimentalIndicator; + const version3Flags = TagFlags.ExtendedHeader | TagFlags.ExperimentalIndicator; if (NumberUtils.hasFlag(value, version3Flags) && this.majorVersion < 3) { throw new Error("Feature only supported in version 2.3+"); } - const version4Flags = Id3v2TagHeaderFlags.FooterPresent; + const version4Flags = TagFlags.FooterPresent; if (NumberUtils.hasFlag(value, version4Flags) && this.majorVersion < 4) { throw new Error("Feature only supported in version 2.4+"); } @@ -164,10 +134,10 @@ export class Id3v2TagHeader { // @TODO: do we need to support setting to versions <4? if (value < 3) { - this._flags &= ~(Id3v2TagHeaderFlags.ExtendedHeader | Id3v2TagHeaderFlags.ExperimentalIndicator); + this._flags &= ~(TagFlags.ExtendedHeader | TagFlags.ExperimentalIndicator); } if (value < 4) { - this._flags &= ~Id3v2TagHeaderFlags.FooterPresent; + this._flags &= ~TagFlags.FooterPresent; } this._majorVersion = value; @@ -216,7 +186,7 @@ export class Id3v2TagHeader { */ public render(): ByteVector { return ByteVector.concatenate( - Id3v2TagHeader.FILE_IDENTIFIER, + TagHeader.FILE_IDENTIFIER, this.majorVersion, this.revisionNumber, this.flags, diff --git a/src/id3v2/id3v2ExtendedHeader.ts b/src/id3v2/tagHeaderExtended.ts similarity index 91% rename from src/id3v2/id3v2ExtendedHeader.ts rename to src/id3v2/tagHeaderExtended.ts index 98e32ad8..80212e25 100644 --- a/src/id3v2/id3v2ExtendedHeader.ts +++ b/src/id3v2/tagHeaderExtended.ts @@ -8,7 +8,7 @@ import {File} from "../file"; * This class is a filler until support for reading and writing the ID3v2 extended header is * implemented. */ -export default class Id3v2ExtendedHeader { +export default class TagHeaderExtended { private _size: number = 0; private constructor() { /* private to enforce construction via static methods */ } @@ -18,14 +18,14 @@ export default class Id3v2ExtendedHeader { * @param data Raw extended header structure * @param version ID3v2 version. Must be an unsigned 8-bit integer. */ - public static fromData(data: ByteVector, version: number): Id3v2ExtendedHeader { + public static fromData(data: ByteVector, version: number): TagHeaderExtended { Guards.truthy(data, "data"); Guards.byte(version, "version"); if (data.length < 4) { throw new CorruptFileError("Provided data is smaller than extended header size field"); } - const header = new Id3v2ExtendedHeader(); + const header = new TagHeaderExtended(); // Read extended header size const declaredSize = version === 3 @@ -42,12 +42,12 @@ export default class Id3v2ExtendedHeader { * @param position Offset into the file where the extended header begins. * @param version ID3v2 version. Must be an unsigned 8-bit integer. */ - public static fromFile(file: File, position: number, version: number): Id3v2ExtendedHeader { + public static fromFile(file: File, position: number, version: number): TagHeaderExtended { Guards.truthy(file, "file"); Guards.safeUint(position, "position"); Guards.byte(version, "version"); - const header = new Id3v2ExtendedHeader(); + const header = new TagHeaderExtended(); // Read extended header size file.seek(position); @@ -70,8 +70,8 @@ export default class Id3v2ExtendedHeader { /** * Constructs and initializes a new instance with no contents. */ - public static fromEmpty(): Id3v2ExtendedHeader { - return new Id3v2ExtendedHeader(); + public static fromEmpty(): TagHeaderExtended { + return new TagHeaderExtended(); } /** diff --git a/src/id3v2/utilTypes.ts b/src/id3v2/utilTypes.ts index 70055a55..3f2ff2d6 100644 --- a/src/id3v2/utilTypes.ts +++ b/src/id3v2/utilTypes.ts @@ -1,199 +1,5 @@ -/** - * Specifies the type of text contained in a synchronized lyrics frame - */ -export enum SynchronizedTextType { - /** - * Text is some other type of text - */ - Other = 0x00, - /** - * Text contains lyrical data - */ - Lyrics = 0x01, - /** - * Text contains a transcription - */ - TextTranscription = 0x02, - /** - * Text lists the movements in the piece - */ - Movement = 0x03, - /** - * Text describes events that occur - */ - Events = 0x04, - /** - * Text contains chord changes that occur in the music - */ - Chord = 0x05, - - /** - * Text contains trivia or "pop up" information about the media - */ - Trivia = 0x06, - - /** - * Text contains URLs for relevant webpages - */ - WebpageUrls = 0x07, - - /** - * Text contains URLs for relevant images - */ - ImageUrls = 0x08 -} - -/** - * Specifies the timestamp format used by a few frame types. - */ -export enum TimestampFormat { - /** - * Timestamp is of unknown format - */ - Unknown = 0x00, - - /** - * Timestamp represents the number of MPEG frames since the beginning of the audio stream - */ - AbsoluteMpegFrames = 0x01, - - /** - * Timestamp represents the number of milliseconds since the beginning of the audio stream - */ - AbsoluteMilliseconds = 0x02 -} - -/** - * Indicates what type of event the event represents. - */ -export enum EventType { - /** - * Padding - no meaning - */ - Padding = 0x00, - - /** - * End of initial silence - */ - EndOfInitialSilence = 0x01, - - /** - * Start of the intro - */ - IntroStart = 0x02, - - /** - * Start of the main part of the song - */ - MainPartStart = 0x03, - - /** - * Start of the outro - */ - OutroStart = 0x04, - - /** - * End of the outro - */ - OutroEnd = 0x05, - - /** - * Start of the verse - */ - VerseStart = 0x06, - - /** - * Start of the refrain - */ - RefrainStart = 0x07, - - /** - * Start of the interlude - */ - InterludeStart = 0x08, - - /** - * Start of the theme - */ - ThemeStart = 0x09, - - /** - * Start of a variation - */ - VariationStart = 0x0A, - - /** - * Indicates a key change event - */ - KeyChange = 0x0B, - - /** - * Indicates a tempo/time signature change event - */ - TimeChange = 0x0C, - - /** - * Indicates momentary unwanted noise (snap, crackle, and pop) - */ - MomentaryUnwantedNoise = 0x0D, - - /** - * Start of sustained noise - */ - SustainedNoise = 0x0E, - - /** - * End of sustained noise - */ - SustainedNoiseEnd = 0x0F, - - /** - * End of the intro - */ - IntroEnd = 0x10, - - /** - * End of the main part of the song - */ - MainPartEnd = 0x11, - - /** - * End of the verse - */ - VerseEnd = 0x12, - - /** - * End of the refrain - */ - RefrainEnd = 0x13, - - /** - * End of the main theme - */ - ThemeEnd = 0x14, - - /** - * Start of profanity - */ - Profanity = 0x15, - - /** - * End of profanity - */ - ProfanityEnd = 0x16, - - /** - * End of audio - */ - AudioEnd = 0xFD, - - /** - * End of the audio file - */ - AudioFileEnd = 0xFE -} diff --git a/src/index.ts b/src/index.ts index 8d0a71de..43ac71c0 100644 --- a/src/index.ts +++ b/src/index.ts @@ -71,20 +71,23 @@ export {default as FlacTag} from "./flac/flacTag"; export {default as Id3v1Tag} from "./id3v1/id3v1Tag"; // ID3v2 /////////////////////////////////////////////////////////////////// -export {default as Id3v2ExtendedHeader} from "./id3v2/id3v2ExtendedHeader"; +export { + ChannelType as Id3v2RelativeVolumeFrameChannelType, + EventType as Id3v2EventType, + FrameFlags as Id3v2FrameFlags, + SynchronizedTextType as Id3v2SynchronizedTextType, + TagFlags as Id3v2TagHeaderFlags, + TimestampFormat as Id3v2TimestampFormat +} from "./id3v2/enums"; export { FrameIdentifier as Id3v2FrameIdentifier, FrameIdentifiers as Id3v2FrameIdentifiers, } from "./id3v2/frameIdentifiers"; export {default as Id3v2Settings} from "./id3v2/id3v2Settings"; export {default as Id3v2Tag} from "./id3v2/id3v2Tag"; -export {default as Id3v2TagFooter} from "./id3v2/id3v2TagFooter"; -export {Id3v2TagHeader, Id3v2TagHeaderFlags} from "./id3v2/id3v2TagHeader"; -export { - SynchronizedTextType as Id3v2SynchronizedTextType, - TimestampFormat as Id3v2TimestampFormat, - EventType as Id3v2EventType -} from "./id3v2/utilTypes"; +export {default as Id3v2TagFooter} from "./id3v2/tagFooter"; +export {default as Id3v2TagHeader} from "./id3v2/tagHeader"; +export {default as Id3v2ExtendedHeader} from "./id3v2/tagHeaderExtended"; // Frames export {default as Id3v2AttachmentFrame} from "./id3v2/frames/attachmentFrame"; @@ -98,7 +101,7 @@ export { FrameCreator as Id3v2FrameCreator, Id3v2FrameFactory } from "./id3v2/frames/frameFactory"; -export {Id3v2FrameFlags, Id3v2FrameHeader} from "./id3v2/frames/frameHeader"; +export {default as Id3v2FrameHeader} from "./id3v2/frames/frameHeader"; export {default as Id3v2GenreFrame} from "./id3v2/frames/genreFrame"; export {default as Id3v2MusicCdIdentifierFrame} from "./id3v2/frames/musicCdIdentifierFrame"; export {default as Id3v2PlayCountFrame} from "./id3v2/frames/playCountFrame"; @@ -106,7 +109,6 @@ export {default as Id3v2PopularimeterFrame} from "./id3v2/frames/popularimeterFr export {default as Id3v2PrivateFrame} from "./id3v2/frames/privateFrame"; export { ChannelData as Id3v2RelativeVolumeFrameChannelData, - ChannelType as Id3v2RelativeVolumeFrameChannelType, RelativeVolumeFrame as Id3v2RelativeVolumeFrame } from "./id3v2/frames/relativeVolumeFrame"; export { diff --git a/src/sandwich/endTag.ts b/src/sandwich/endTag.ts index 13e932b9..ac4e8487 100644 --- a/src/sandwich/endTag.ts +++ b/src/sandwich/endTag.ts @@ -3,13 +3,13 @@ import CombinedTag from "../combinedTag"; import Id3v2Settings from "../id3v2/id3v2Settings"; import Id3v1Tag from "../id3v1/id3v1Tag"; import Id3v2Tag from "../id3v2/id3v2Tag"; -import Id3v2TagFooter from "../id3v2/id3v2TagFooter"; +import Id3v2TagFooter from "../id3v2/tagFooter"; import TagParser from "./tagParsers"; import {ApeTagFooter} from "../ape/apeTagFooter"; import {ByteVector} from "../byteVector"; import {CorruptFileError, UnsupportedFormatError} from "../errors"; import {File, ReadStyle} from "../file"; -import {Id3v2TagHeaderFlags} from "../id3v2/id3v2TagHeader"; +import {TagFlags as Id3v2TagFlags} from "../id3v2/enums"; import {Tag, TagTypes} from "../tag"; import {Guards} from "../utils"; @@ -57,7 +57,7 @@ export default class EndTag extends CombinedTag { const id3v2Tag = Id3v2Tag.fromEmpty(); // @TODO: have default version be configurable id3v2Tag.version = 4; - id3v2Tag.flags |= Id3v2TagHeaderFlags.FooterPresent; + id3v2Tag.flags |= Id3v2TagFlags.FooterPresent; tag = id3v2Tag; break; default: diff --git a/src/sandwich/startTag.ts b/src/sandwich/startTag.ts index 4f6538a5..cc812873 100644 --- a/src/sandwich/startTag.ts +++ b/src/sandwich/startTag.ts @@ -1,13 +1,13 @@ import ApeTag from "../ape/apeTag"; import CombinedTag from "../combinedTag"; import Id3v2Tag from "../id3v2/id3v2Tag"; +import Id3v2TagHeader from "../id3v2/tagHeader"; import Id3v2Settings from "../id3v2/id3v2Settings"; import TagParser from "./tagParsers"; import {ApeTagFooter} from "../ape/apeTagFooter"; import {ByteVector} from "../byteVector"; import {CorruptFileError, UnsupportedFormatError} from "../errors"; import {File, ReadStyle} from "../file"; -import {Id3v2TagHeader} from "../id3v2/id3v2TagHeader"; import {Tag, TagTypes} from "../tag"; import {Guards} from "../utils"; diff --git a/test-unit/combinedTagTests.ts b/test-unit/combinedTagTests.ts index 71532d8c..434ba59b 100644 --- a/test-unit/combinedTagTests.ts +++ b/test-unit/combinedTagTests.ts @@ -1,15 +1,15 @@ import {suite, test} from "@testdeck/mocha"; import {assert} from "chai"; +import {Mock} from "typemoq"; import ApeTag from "../src/ape/apeTag"; import CombinedTag from "../src/combinedTag"; import Id3v2Tag from "../src/id3v2/id3v2Tag"; import PropertyTests from "./utilities/propertyTests"; import XiphComment from "../src/xiph/xiphComment"; +import {IPicture} from "../src/picture"; import {Tag, TagTypes} from "../src/tag"; import {TagTesters, Testers} from "./utilities/testers"; -import {Mock} from "typemoq"; -import {IPicture} from "../src"; @suite class CombinedTag_MethodTests { @test diff --git a/test-unit/flac/flacFileTests.ts b/test-unit/flac/flacFileTests.ts index d6661e5f..038b5b49 100644 --- a/test-unit/flac/flacFileTests.ts +++ b/test-unit/flac/flacFileTests.ts @@ -8,17 +8,17 @@ import FlacStreamHeader from "../../src/flac/flacStreamHeader"; import FlacTag from "../../src/flac/flacTag"; import Id3v1Tag from "../../src/id3v1/id3v1Tag"; import Id3v2Tag from "../../src/id3v2/id3v2Tag"; +import {TagFlags as Id3v2TagFlags} from "../../src/id3v2/enums"; import XiphComment from "../../src/xiph/xiphComment"; import XiphPicture from "../../src/xiph/xiphPicture"; import {default as TestFile} from "../utilities/testFile"; import {ByteVector, StringType} from "../../src/byteVector"; import {FileAccessMode, ReadStyle} from "../../src/file"; import {IFileAbstraction} from "../../src/fileAbstraction"; -import {Id3v2TagHeaderFlags} from "../../src/id3v2/id3v2TagHeader"; import {FlacBlock, FlacBlockType} from "../../src/flac/flacBlock"; +import {Picture} from "../../src/picture"; import {TagTypes} from "../../src/tag"; import {Testers} from "../utilities/testers"; -import {Picture} from "../../src"; @suite class Flac_File_ConstructorTests { @test @@ -871,7 +871,7 @@ import {Picture} from "../../src"; const id3v2Tag = Id3v2Tag.fromEmpty(); id3v2Tag.version = 4; if (isAtEndOfFile) { - id3v2Tag.flags |= Id3v2TagHeaderFlags.FooterPresent; + id3v2Tag.flags |= Id3v2TagFlags.FooterPresent; } id3v2Tag.title = "foo"; return id3v2Tag; diff --git a/test-unit/id3v2/attachmentsFrameTests.ts b/test-unit/id3v2/attachmentsFrameTests.ts index 0e341022..74cbc456 100644 --- a/test-unit/id3v2/attachmentsFrameTests.ts +++ b/test-unit/id3v2/attachmentsFrameTests.ts @@ -5,11 +5,12 @@ import {assert} from "chai"; import AttachmentFrame from "../../src/id3v2/frames/attachmentFrame"; import Frame from "../../src/id3v2/frames/frame"; import FrameConstructorTests from "./frameConstructorTests"; +import FrameHeader from "../../src/id3v2/frames/frameHeader"; import Id3v2Settings from "../../src/id3v2/id3v2Settings"; import PropertyTests from "../utilities/propertyTests"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "../../src/id3v2/frames/frameHeader"; +import {FrameFlags} from "../../src/id3v2/enums"; import {FrameIdentifier, FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {IPicture, Picture, PictureType} from "../../src/picture"; import {Testers} from "../utilities/testers"; @@ -64,7 +65,7 @@ const verifyFrame = ( } @suite class Id3v2_AttachmentFrame_ConstructorTests extends FrameConstructorTests { - get fromFieldBytes(): (h: Id3v2FrameHeader, d: ByteVector, v: number) => Frame { + get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { return AttachmentFrame.fromFieldBytes; } @@ -147,7 +148,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(StringType.Latin1), // Description delimiter testData // Picture bytes ); - const header = new Id3v2FrameHeader(FrameIdentifiers.APIC, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.APIC, FrameFlags.None, fieldBytes.length); // Act const frame = AttachmentFrame.fromFieldBytes(header, fieldBytes, version); @@ -179,7 +180,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(StringType.UTF16BE), // Description delimiter testData // Picture bytes ); - const header = new Id3v2FrameHeader(FrameIdentifiers.APIC, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.APIC, FrameFlags.None, fieldBytes.length); // Act const frame = AttachmentFrame.fromFieldBytes(header, fieldBytes, version); @@ -210,7 +211,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(encoding), // Description delimiter testData // Picture bytes ); - const header = new Id3v2FrameHeader(FrameIdentifiers.APIC, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.APIC, FrameFlags.None, fieldBytes.length); // Act const frame = AttachmentFrame.fromFieldBytes(header, fieldBytes, 2); @@ -244,7 +245,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(StringType.Latin1), // Description delimiter testData // Attachment bytes ); - const header = new Id3v2FrameHeader(FrameIdentifiers.GEOB, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.GEOB, FrameFlags.None, fieldBytes.length); // Act const frame = AttachmentFrame.fromFieldBytes(header, fieldBytes, version); @@ -278,7 +279,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(StringType.UTF16BE), // Description delimiter testData // Attachment bytes ); - const header = new Id3v2FrameHeader(FrameIdentifiers.GEOB, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.GEOB, FrameFlags.None, fieldBytes.length); // Act const frame = AttachmentFrame.fromFieldBytes(header, fieldBytes, version); @@ -449,7 +450,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(StringType.UTF16BE), // Description delimiter testData // Picture bytes ); - const header = new Id3v2FrameHeader(FrameIdentifiers.APIC, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.APIC, FrameFlags.None, fieldBytes.length); const frame = AttachmentFrame.fromFieldBytes(header, fieldBytes, 4); // Act @@ -600,7 +601,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(StringType.UTF16), // Description delimiter data // Picture bytes ); - const header = new Id3v2FrameHeader(FrameIdentifiers.APIC, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.APIC, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(2), fieldBytes); Testers.bvEqual(output, expected); } @@ -623,7 +624,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(StringType.UTF16), // Description delimiter data // Picture bytes ); - const header = new Id3v2FrameHeader(FrameIdentifiers.APIC, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.APIC, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(2), fieldBytes); Testers.bvEqual(output, expected); } @@ -647,7 +648,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(StringType.UTF16), // Description delimiter data // Picture bytes ); - const header = new Id3v2FrameHeader(FrameIdentifiers.APIC, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.APIC, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(3), fieldBytes); Testers.bvEqual(output, expected); } @@ -671,7 +672,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(StringType.Latin1), // Description delimiter data // Picture bytes ); - const header = new Id3v2FrameHeader(FrameIdentifiers.APIC, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.APIC, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(4), fieldBytes); Testers.bvEqual(output, expected); } @@ -694,7 +695,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(StringType.UTF16), // Description delimiter data // Attachment bytes ); - const header = new Id3v2FrameHeader(FrameIdentifiers.GEOB, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.GEOB, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(version), fieldBytes); Testers.bvEqual(output, expected); } @@ -715,7 +716,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(Id3v2Settings.defaultEncoding), // Description delimiter data // Attachment bytes ); - const header = new Id3v2FrameHeader(FrameIdentifiers.GEOB, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.GEOB, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(4), fieldBytes); Testers.bvEqual(output, expected); } @@ -739,7 +740,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(StringType.UTF16), // Description delimiter data // Attachment bytes ); - const header = new Id3v2FrameHeader(FrameIdentifiers.GEOB, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.GEOB, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(version), fieldBytes); Testers.bvEqual(output, expected); } @@ -762,7 +763,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(Id3v2Settings.defaultEncoding), // Description delimiter data // Attachment bytes ); - const header = new Id3v2FrameHeader(FrameIdentifiers.GEOB, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.GEOB, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(4), fieldBytes); Testers.bvEqual(output, expected); } @@ -787,7 +788,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(StringType.UTF16), // Description delimiter data // Attachment bytes ) - const header = new Id3v2FrameHeader(FrameIdentifiers.GEOB, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.GEOB, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(version), fieldBytes); Testers.bvEqual(output, expected); } @@ -811,7 +812,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(Id3v2Settings.defaultEncoding), // Description delimiter data // Attachment bytes ) - const header = new Id3v2FrameHeader(FrameIdentifiers.GEOB, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.GEOB, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(4), fieldBytes); Testers.bvEqual(output, expected); } @@ -837,7 +838,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(StringType.UTF16), // Description delimiter data // Attachment bytes ); - const header = new Id3v2FrameHeader(FrameIdentifiers.GEOB, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.GEOB, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(version), fieldBytes); Testers.bvEqual(output, expected); } @@ -862,7 +863,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(Id3v2Settings.defaultEncoding), // Description delimiter data // Attachment bytes ); - const header = new Id3v2FrameHeader(FrameIdentifiers.GEOB, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.GEOB, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(4), fieldBytes); Testers.bvEqual(output, expected); } diff --git a/test-unit/id3v2/commentsFrameTests.ts b/test-unit/id3v2/commentsFrameTests.ts index b05be20a..801d27cb 100644 --- a/test-unit/id3v2/commentsFrameTests.ts +++ b/test-unit/id3v2/commentsFrameTests.ts @@ -4,12 +4,13 @@ import {assert} from "chai"; import CommentsFrame from "../../src/id3v2/frames/commentsFrame"; import Frame from "../../src/id3v2/frames/frame"; import FrameConstructorTests from "./frameConstructorTests"; +import FrameHeader from "../../src/id3v2/frames/frameHeader"; import Id3v2Settings from "../../src/id3v2/id3v2Settings"; import PropertyTests from "../utilities/propertyTests"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector, StringType} from "../../src/byteVector"; +import {FrameFlags} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "../../src/id3v2/frames/frameHeader"; import {Testers} from "../utilities/testers"; const verifyFrame = ( @@ -30,7 +31,7 @@ const verifyFrame = ( } @suite class Id3v2_CommentsFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: Id3v2FrameHeader, fb: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, fb: ByteVector, v: number) => Frame { return CommentsFrame.fromFieldBytes; } @@ -40,7 +41,7 @@ const verifyFrame = ( public fromFieldBytes_tooFewBytes_throws(version: number) { // Arrange const fieldBytes = ByteVector.fromByte(StringType.Latin1); - const header = new Id3v2FrameHeader(FrameIdentifiers.COMM, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.COMM, FrameFlags.None, fieldBytes.length); // Act/Assert assert.throws(() => { CommentsFrame.fromFieldBytes(header, fieldBytes, version); }); @@ -55,7 +56,7 @@ const verifyFrame = ( StringType.Latin1, // Encoding ByteVector.fromString("eng", StringType.Latin1), // Language ); - const header = new Id3v2FrameHeader(FrameIdentifiers.COMM, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.COMM, FrameFlags.None, fieldBytes.length); // Act @@ -75,7 +76,7 @@ const verifyFrame = ( ByteVector.fromString("eng", StringType.Latin1), // Language ByteVector.fromString("fux", StringType.Latin1) // Description -> will be used as comments ); - const header = new Id3v2FrameHeader(FrameIdentifiers.COMM, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.COMM, FrameFlags.None, fieldBytes.length); // Act @@ -96,7 +97,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(StringType.Latin1), // Delimiter ByteVector.fromString("fux", StringType.Latin1) // Comment ); - const header = new Id3v2FrameHeader(FrameIdentifiers.COMM, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.COMM, FrameFlags.None, fieldBytes.length); // Act @@ -118,7 +119,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(StringType.Latin1), // Delimiter ByteVector.fromString("bux", StringType.Latin1) // Comment ); - const header = new Id3v2FrameHeader(FrameIdentifiers.COMM, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.COMM, FrameFlags.None, fieldBytes.length); // Act const frame = CommentsFrame.fromFieldBytes(header, fieldBytes, version); @@ -138,7 +139,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(encoding), // Delimiter ByteVector.fromString("bux", encoding) // Comment ); - const header = new Id3v2FrameHeader(FrameIdentifiers.COMM, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.COMM, FrameFlags.None, fieldBytes.length); // Act const frame = CommentsFrame.fromFieldBytes(header, fieldBytes, 4); @@ -356,7 +357,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(encoding), // Delimiter ByteVector.fromString("foo", encoding) // Comment text ); - const header = new Id3v2FrameHeader(FrameIdentifiers.COMM, Id3v2FrameFlags.None, expectedFieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.COMM, FrameFlags.None, expectedFieldBytes.length); const expectedBytes = ByteVector.concatenate(header.render(version), expectedFieldBytes); Testers.bvEqual(output, expectedBytes); } @@ -381,7 +382,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(outputEncoding), // Delimiter ByteVector.fromString("foo", outputEncoding) // Comment text ); - const header = new Id3v2FrameHeader(FrameIdentifiers.COMM, Id3v2FrameFlags.None, expectedFieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.COMM, FrameFlags.None, expectedFieldBytes.length); const expectedBytes = ByteVector.concatenate(header.render(version), expectedFieldBytes); Testers.bvEqual(output, expectedBytes); } @@ -403,7 +404,7 @@ const verifyFrame = ( ByteVector.fromString("foo", StringType.Latin1), // Description ByteVector.getTextDelimiter(StringType.Latin1), // Delimiter ); - const header = new Id3v2FrameHeader(FrameIdentifiers.COMM, Id3v2FrameFlags.None, expectedFieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.COMM, FrameFlags.None, expectedFieldBytes.length); const expectedBytes = ByteVector.concatenate(header.render(4), expectedFieldBytes); Testers.bvEqual(result, expectedBytes); } @@ -425,7 +426,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(StringType.Latin1), // Delimiter ByteVector.fromString("foo", StringType.Latin1), // Comment text ); - const header = new Id3v2FrameHeader(FrameIdentifiers.COMM, Id3v2FrameFlags.None, expectedFieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.COMM, FrameFlags.None, expectedFieldBytes.length); const expectedBytes = ByteVector.concatenate(header.render(4), expectedFieldBytes); Testers.bvEqual(result, expectedBytes); } diff --git a/test-unit/id3v2/eventTimeCodeFrameTests.ts b/test-unit/id3v2/eventTimeCodeFrameTests.ts index 8813ff64..a3dfe4f4 100644 --- a/test-unit/id3v2/eventTimeCodeFrameTests.ts +++ b/test-unit/id3v2/eventTimeCodeFrameTests.ts @@ -3,20 +3,20 @@ import {assert} from "chai"; import Frame from "../../src/id3v2/frames/frame"; import FrameConstructorTests from "./frameConstructorTests"; +import FrameHeader from "../../src/id3v2/frames/frameHeader"; import PropertyTests from "../utilities/propertyTests"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector} from "../../src/byteVector"; +import {EventType, FrameFlags, TimestampFormat} from "../../src/id3v2/enums"; import {EventTimeCode, EventTimeCodeFrame} from "../../src/id3v2/frames/eventTimeCodeFrame"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "../../src/id3v2/frames/frameHeader"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; -import {EventType, TimestampFormat} from "../../src/id3v2/utilTypes"; const assertFrame = (frame: EventTimeCodeFrame, e: EventTimeCode[], t: TimestampFormat) => { assert.isOk(frame); assert.instanceOf(frame, EventTimeCodeFrame); assert.strictEqual(frame.frameId, FrameIdentifiers.ETCO); - assert.isTrue((frame.flags | Id3v2FrameFlags.FileAlterPreservation) > 0); + assert.isTrue((frame.flags | FrameFlags.FileAlterPreservation) > 0); assert.deepStrictEqual(frame.events, e); assert.strictEqual(frame.timestampFormat, t); @@ -99,7 +99,7 @@ const assertFrame = (frame: EventTimeCodeFrame, e: EventTimeCode[], t: Timestamp } @suite class Id3v2_EventTimeCodeFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: Id3v2FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { return EventTimeCodeFrame.fromFieldBytes; } @@ -109,7 +109,7 @@ const assertFrame = (frame: EventTimeCodeFrame, e: EventTimeCode[], t: Timestamp public fromFieldBytes_notEnoughBytes(version: number) { // Arrange const fieldBytes = ByteVector.empty(); - const header = new Id3v2FrameHeader(FrameIdentifiers.ETCO, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.ETCO, FrameFlags.None, fieldBytes.length); // Act / Assert assert.throws(() => { EventTimeCodeFrame.fromFieldBytes(header, fieldBytes, version); }); @@ -121,7 +121,7 @@ const assertFrame = (frame: EventTimeCodeFrame, e: EventTimeCode[], t: Timestamp public fromFieldBytes_noEvents(version: number) { // Arrange const fieldBytes = ByteVector.fromByte(TimestampFormat.AbsoluteMilliseconds); - const header = new Id3v2FrameHeader(FrameIdentifiers.ETCO, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.ETCO, FrameFlags.None, fieldBytes.length); // Act const frame = EventTimeCodeFrame.fromFieldBytes(header, fieldBytes, version); @@ -142,7 +142,7 @@ const assertFrame = (frame: EventTimeCodeFrame, e: EventTimeCode[], t: Timestamp event1.render(), // Event 1 event2.render() // Event 2 ); - const header = new Id3v2FrameHeader(FrameIdentifiers.ETCO, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.ETCO, FrameFlags.None, fieldBytes.length); // Act const frame = EventTimeCodeFrame.fromFieldBytes(header, fieldBytes, version); @@ -163,7 +163,7 @@ const assertFrame = (frame: EventTimeCodeFrame, e: EventTimeCode[], t: Timestamp event1.render(), // Event 1 event2.render().subarray(0, 3) // Event 2 (incomplete) ); - const header = new Id3v2FrameHeader(FrameIdentifiers.ETCO, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.ETCO, FrameFlags.None, fieldBytes.length); // Act / Assert assert.throws(() => EventTimeCodeFrame.fromFieldBytes(header, fieldBytes, version)); @@ -339,9 +339,9 @@ const assertFrame = (frame: EventTimeCodeFrame, e: EventTimeCode[], t: Timestamp assert.isOk(output); const fieldBytes = ByteVector.fromByte(TimestampFormat.AbsoluteMpegFrames); - const header = new Id3v2FrameHeader( + const header = new FrameHeader( FrameIdentifiers.ETCO, - Id3v2FrameFlags.FileAlterPreservation, + FrameFlags.FileAlterPreservation, fieldBytes.length ); const expected = ByteVector.concatenate(header.render(version), fieldBytes); @@ -371,9 +371,9 @@ const assertFrame = (frame: EventTimeCodeFrame, e: EventTimeCode[], t: Timestamp event1.render(), // Event 1 event2.render() // Event 2 ); - const header = new Id3v2FrameHeader( + const header = new FrameHeader( FrameIdentifiers.ETCO, - Id3v2FrameFlags.FileAlterPreservation, + FrameFlags.FileAlterPreservation, fieldBytes.length ); const expected = ByteVector.concatenate(header.render(version), fieldBytes); diff --git a/test-unit/id3v2/frameConstructorTests.ts b/test-unit/id3v2/frameConstructorTests.ts index 600e201b..d23534df 100644 --- a/test-unit/id3v2/frameConstructorTests.ts +++ b/test-unit/id3v2/frameConstructorTests.ts @@ -1,14 +1,14 @@ import {test} from "@testdeck/mocha"; import Frame from "../../src/id3v2/frames/frame"; +import FrameHeader from "../../src/id3v2/frames/frameHeader"; import {ByteVector} from "../../src/byteVector"; -import {Id3v2FrameHeader} from "../../src/id3v2/frames/frameHeader"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; export default abstract class FrameConstructorTests { - public abstract get fromFieldBytes(): (h: Id3v2FrameHeader, d: ByteVector, v: number) => Frame; + public abstract get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame; @test public fromFieldBytes_falsyHeader_throws() { @@ -16,13 +16,13 @@ export default abstract class FrameConstructorTests { const data = ByteVector.empty(); // Act/Assert - Testers.testTruthy((v: Id3v2FrameHeader) => { this.fromFieldBytes(v, data, 4); }); + Testers.testTruthy((v: FrameHeader) => { this.fromFieldBytes(v, data, 4); }); } @test public fromFieldBytes_falsyFieldBytes_throws() { // Arrange - const header = new Id3v2FrameHeader(FrameIdentifiers.WCOM); + const header = new FrameHeader(FrameIdentifiers.WCOM); // Act/Assert Testers.testTruthy((v: ByteVector) => { this.fromFieldBytes(header, v, 4); }); @@ -32,7 +32,7 @@ export default abstract class FrameConstructorTests { public fromFieldBytes_invalidVersion_throws() { // Arrange const data = ByteVector.empty(); - const header = new Id3v2FrameHeader(FrameIdentifiers.WCOM); + const header = new FrameHeader(FrameIdentifiers.WCOM); // Act/Assert Testers.testByte((v: number) => { this.fromFieldBytes(header, data, v); }); diff --git a/test-unit/id3v2/frameFactoryTests.ts b/test-unit/id3v2/frameFactoryTests.ts index 5fea1233..9efb163c 100644 --- a/test-unit/id3v2/frameFactoryTests.ts +++ b/test-unit/id3v2/frameFactoryTests.ts @@ -5,6 +5,7 @@ import {It, Mock, Times} from "typemoq"; import AttachmentFrame from "../../src/id3v2/frames/attachmentFrame"; import CommentsFrame from "../../src/id3v2/frames/commentsFrame"; import Frame from "../../src/id3v2/frames/frame"; +import FrameHeader from "../../src/id3v2/frames/frameHeader"; import MusicCdIdentifierFrame from "../../src/id3v2/frames/musicCdIdentifierFrame"; import PlayCountFrame from "../../src/id3v2/frames/playCountFrame"; import PopularimeterFrame from "../../src/id3v2/frames/popularimeterFrame"; @@ -19,16 +20,15 @@ import UrlLinkFrame from "../../src/id3v2/frames/urlLinkFrame"; import UserTextInformationFrame from "../../src/id3v2/frames/userTextInformationFrame"; import UserUrlLinkFrame from "../../src/id3v2/frames/userUrlLinkFrame"; import {ByteVector, StringType} from "../../src/byteVector"; +import {FrameFlags, TimestampFormat} from "../../src/id3v2/enums"; import {EventTimeCodeFrame} from "../../src/id3v2/frames/eventTimeCodeFrame"; import {File} from "../../src/file"; import {FrameCreator, Id3v2FrameFactory} from "../../src/id3v2/frames/frameFactory"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "../../src/id3v2/frames/frameHeader"; import {FrameIdentifier, FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {PictureType} from "../../src/picture"; import {RelativeVolumeFrame} from "../../src/id3v2/frames/relativeVolumeFrame"; import {SynchronizedLyricsFrame} from "../../src/id3v2/frames/synchronizedLyricsFrame"; import {Testers} from "../utilities/testers"; -import {TimestampFormat} from "../../src/id3v2/utilTypes"; import {NumberUtils} from "../../src/utils"; @suite class FrameFactoryTests { @@ -83,7 +83,7 @@ import {NumberUtils} from "../../src/utils"; @params(4, "v4") public createFrameFromFile_noHeader(version: number) { // Arrange - const size = Id3v2FrameHeader.getBaseSize(version); + const size = FrameHeader.getBaseSize(version); const data = ByteVector.fromSize(size - 1); const file = TestFile.getFile(data); @@ -96,7 +96,7 @@ import {NumberUtils} from "../../src/utils"; @params(4, "v4") public createFrameFromFile_noHeaderAfterOffset(version: number) { // Arrange - const size = Id3v2FrameHeader.getBaseSize(version); + const size = FrameHeader.getBaseSize(version); const data = ByteVector.fromSize(size + 9, 0x00); const file = TestFile.getFile(data); @@ -109,7 +109,7 @@ import {NumberUtils} from "../../src/utils"; @params(4, "v4") public createFrameFromFile_padding(version: number) { // Arrange - const size = Id3v2FrameHeader.getBaseSize(version); + const size = FrameHeader.getBaseSize(version); const data = ByteVector.fromSize(size + 1, 0x00); const file = TestFile.getFile(data); @@ -382,7 +382,7 @@ import {NumberUtils} from "../../src/utils"; public createFrameFromFile_customThrows() { // Arrange const fieldBytes = ByteVector.fromByteArray([0x01, 0x02, 0x03]); - const header = new Id3v2FrameHeader(FrameIdentifiers.RVRB, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.RVRB, FrameFlags.None, fieldBytes.length); const data = ByteVector.concatenate(header.render(3), fieldBytes); const file = TestFile.getFile(data); @@ -415,7 +415,7 @@ import {NumberUtils} from "../../src/utils"; const data = frame.render(4); const file = TestFile.getFile(data); - const fieldBytes = data.subarray(Id3v2FrameHeader.getBaseSize(4)); + const fieldBytes = data.subarray(FrameHeader.getBaseSize(4)); const mockCreator = Mock.ofType(); mockCreator.setup((c) => c(It.isValue(fieldBytes), It.isValue(0), It.isAny(), It.isValue(4))) @@ -451,7 +451,7 @@ import {NumberUtils} from "../../src/utils"; const data = frame.render(4); const file = TestFile.getFile(data); - const fieldBytes = data.subarray(Id3v2FrameHeader.getBaseSize(4)); + const fieldBytes = data.subarray(FrameHeader.getBaseSize(4)); const mockCreator = Mock.ofType(); mockCreator.setup((c) => c(It.isValue(fieldBytes), It.isValue(0), It.isAny(), It.isValue(4))) @@ -486,7 +486,7 @@ import {NumberUtils} from "../../src/utils"; public createFrameFromFile_fieldBytesHeaderMismatch(version: number) { // Arrange const fieldBytes = ByteVector.fromSize(10); - const header = new Id3v2FrameHeader(FrameIdentifiers.RVRB, Id3v2FrameFlags.None, fieldBytes.length + 5); + const header = new FrameHeader(FrameIdentifiers.RVRB, FrameFlags.None, fieldBytes.length + 5); const data = ByteVector.concatenate(header.render(version), fieldBytes); const file = TestFile.getFile(data); @@ -499,7 +499,7 @@ import {NumberUtils} from "../../src/utils"; // Arrange // Note: Tag-level unsynchronization is only available in ID3v2.3 const fieldBytes = ByteVector.fromSize(10); - const header = new Id3v2FrameHeader(FrameIdentifiers.RVRB, Id3v2FrameFlags.Unsynchronized, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.RVRB, FrameFlags.Unsynchronized, fieldBytes.length); const data = ByteVector.concatenate(header.render(3), fieldBytes); const file = TestFile.getFile(data); @@ -512,7 +512,7 @@ import {NumberUtils} from "../../src/utils"; assert.strictEqual(result.totalSize, data.length); assert.isOk(result.frame); - assert.isFalse(NumberUtils.hasFlag(result.frame.flags, Id3v2FrameFlags.Unsynchronized)); + assert.isFalse(NumberUtils.hasFlag(result.frame.flags, FrameFlags.Unsynchronized)); } @test @@ -520,7 +520,7 @@ import {NumberUtils} from "../../src/utils"; // Arrange // Note: Frame-level unsynchronization is only available in ID3v2.4 const fieldBytes = ByteVector.fromByteArray([0xFF, 0x00, 0xE0]); - const header = new Id3v2FrameHeader(FrameIdentifiers.RVRB, Id3v2FrameFlags.Unsynchronized, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.RVRB, FrameFlags.Unsynchronized, fieldBytes.length); const data = ByteVector.concatenate(header.render(4), fieldBytes); const file = TestFile.getFile(data); @@ -534,7 +534,7 @@ import {NumberUtils} from "../../src/utils"; assert.isOk(result.frame); assert.instanceOf((result.frame), UnknownFrame); - assert.isTrue(NumberUtils.hasFlag(result.frame.flags, Id3v2FrameFlags.Unsynchronized)) + assert.isTrue(NumberUtils.hasFlag(result.frame.flags, FrameFlags.Unsynchronized)) Testers.bvEqual((result.frame).data, ByteVector.fromByteArray([0xFF, 0xE0])); } @@ -545,9 +545,9 @@ import {NumberUtils} from "../../src/utils"; // Note: v2 does not support extended frame header const fieldBytes = ByteVector.fromSize(10); const extendedHeaderBytes = ByteVector.fromByte(0x12); - const header = new Id3v2FrameHeader( + const header = new FrameHeader( FrameIdentifiers.RVRB, - Id3v2FrameFlags.GroupingIdentity, + FrameFlags.GroupingIdentity, fieldBytes.length + extendedHeaderBytes.length ); const data = ByteVector.concatenate(header.render(version), extendedHeaderBytes, fieldBytes); @@ -599,7 +599,7 @@ import {NumberUtils} from "../../src/utils"; @params(4, "v4") public createFrameFromTagBytes_noHeader(version: number) { // Arrange - const size = Id3v2FrameHeader.getBaseSize(version); + const size = FrameHeader.getBaseSize(version); const data = ByteVector.fromSize(size - 1); // Act / Assert @@ -611,7 +611,7 @@ import {NumberUtils} from "../../src/utils"; @params(4, "v4") public createFrameFroMTagBytes_noHeaderAfterOffset(version: number) { // Arrange - const size = Id3v2FrameHeader.getBaseSize(version); + const size = FrameHeader.getBaseSize(version); const data = ByteVector.fromSize(size + 9, 0x00); // Act / Assert @@ -623,7 +623,7 @@ import {NumberUtils} from "../../src/utils"; @params(4, "v4") public createFrameFromTagBytes_padding(version: number) { // Arrange - const size = Id3v2FrameHeader.getBaseSize(version); + const size = FrameHeader.getBaseSize(version); const data = ByteVector.fromSize(size + 1, 0x00); // Act @@ -885,7 +885,7 @@ import {NumberUtils} from "../../src/utils"; public createFrameFromTagBytes_customThrows() { // Arrange const fieldBytes = ByteVector.fromByteArray([0x01, 0x02, 0x03]); - const header = new Id3v2FrameHeader(FrameIdentifiers.RVRB, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.RVRB, FrameFlags.None, fieldBytes.length); const data = ByteVector.concatenate(header.render(3), fieldBytes); const mockCreator = Mock.ofType(); @@ -916,7 +916,7 @@ import {NumberUtils} from "../../src/utils"; const frame = PlayCountFrame.fromFields(BigInt(123)); const data = frame.render(4); - const fieldBytes = data.subarray(Id3v2FrameHeader.getBaseSize(4)); + const fieldBytes = data.subarray(FrameHeader.getBaseSize(4)); const mockCreator = Mock.ofType(); mockCreator.setup((c) => c(It.isValue(fieldBytes), It.isValue(0), It.isAny(), It.isValue(4))) @@ -951,7 +951,7 @@ import {NumberUtils} from "../../src/utils"; const frame = UnknownFrame.fromFields(FrameIdentifiers.RVRB, ByteVector.fromByteArray([0x01, 0x02, 0x03])); const data = frame.render(4); - const fieldBytes = data.subarray(Id3v2FrameHeader.getBaseSize(4)); + const fieldBytes = data.subarray(FrameHeader.getBaseSize(4)); const mockCreator = Mock.ofType(); mockCreator.setup((c) => c(It.isValue(fieldBytes), It.isValue(0), It.isAny(), It.isValue(4))) @@ -986,7 +986,7 @@ import {NumberUtils} from "../../src/utils"; public createFrameFromTagBytes_fieldBytesHeaderMismatch(version: number) { // Arrange const fieldBytes = ByteVector.fromSize(10); - const header = new Id3v2FrameHeader(FrameIdentifiers.RVRB, Id3v2FrameFlags.None, fieldBytes.length + 5); + const header = new FrameHeader(FrameIdentifiers.RVRB, FrameFlags.None, fieldBytes.length + 5); const data = ByteVector.concatenate(header.render(version), fieldBytes); // Act / Assert @@ -998,7 +998,7 @@ import {NumberUtils} from "../../src/utils"; // Arrange // Note: Tag-level unsynchronization is only available in ID3v2.3 const fieldBytes = ByteVector.fromSize(10); - const header = new Id3v2FrameHeader(FrameIdentifiers.RVRB, Id3v2FrameFlags.Unsynchronized, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.RVRB, FrameFlags.Unsynchronized, fieldBytes.length); const data = ByteVector.concatenate(header.render(3), fieldBytes); // Act @@ -1010,7 +1010,7 @@ import {NumberUtils} from "../../src/utils"; assert.strictEqual(result.totalSize, data.length); assert.isOk(result.frame); - assert.isFalse(NumberUtils.hasFlag(result.frame.flags, Id3v2FrameFlags.Unsynchronized)); + assert.isFalse(NumberUtils.hasFlag(result.frame.flags, FrameFlags.Unsynchronized)); } @test @@ -1018,7 +1018,7 @@ import {NumberUtils} from "../../src/utils"; // Arrange // Note: Frame-level unsynchronization is only available in ID3v2.4 const fieldBytes = ByteVector.fromByteArray([0xFF, 0x00, 0xE0]); - const header = new Id3v2FrameHeader(FrameIdentifiers.RVRB, Id3v2FrameFlags.Unsynchronized, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.RVRB, FrameFlags.Unsynchronized, fieldBytes.length); const data = ByteVector.concatenate(header.render(4), fieldBytes); // Act @@ -1031,7 +1031,7 @@ import {NumberUtils} from "../../src/utils"; assert.isOk(result.frame); assert.instanceOf((result.frame), UnknownFrame); - assert.isTrue(NumberUtils.hasFlag(result.frame.flags, Id3v2FrameFlags.Unsynchronized)) + assert.isTrue(NumberUtils.hasFlag(result.frame.flags, FrameFlags.Unsynchronized)) Testers.bvEqual((result.frame).data, ByteVector.fromByteArray([0xFF, 0xE0])); } @@ -1042,9 +1042,9 @@ import {NumberUtils} from "../../src/utils"; // Note: v2 does not support extended frame header const fieldBytes = ByteVector.fromSize(10); const extendedHeaderBytes = ByteVector.fromByte(0x12); - const header = new Id3v2FrameHeader( + const header = new FrameHeader( FrameIdentifiers.RVRB, - Id3v2FrameFlags.GroupingIdentity, + FrameFlags.GroupingIdentity, fieldBytes.length + extendedHeaderBytes.length ); const data = ByteVector.concatenate(header.render(version), extendedHeaderBytes, fieldBytes); @@ -1065,7 +1065,7 @@ import {NumberUtils} from "../../src/utils"; // #endregion private static getTestData(frameIdentifier: FrameIdentifier, fieldBytes: ByteVector): ByteVector { - const header = new Id3v2FrameHeader(frameIdentifier, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(frameIdentifier, FrameFlags.None, fieldBytes.length); return ByteVector.concatenate(header.render(4), fieldBytes); } @@ -1086,7 +1086,7 @@ import {NumberUtils} from "../../src/utils"; assert.ok(frame); assert.instanceOf(frame, classType); - const expectedSize = frame.size + Id3v2FrameHeader.getBaseSize(id3v2Version) + const expectedSize = frame.size + FrameHeader.getBaseSize(id3v2Version) assert.strictEqual(output.totalSize, expectedSize); } } diff --git a/test-unit/id3v2/frameHeaderTests.ts b/test-unit/id3v2/frameHeaderTests.ts index 4a916863..14006791 100644 --- a/test-unit/id3v2/frameHeaderTests.ts +++ b/test-unit/id3v2/frameHeaderTests.ts @@ -1,11 +1,12 @@ import {params, suite, test} from "@testdeck/mocha"; import {assert} from "chai"; +import FrameHeader from "../../src/id3v2/frames/frameHeader"; +import PropertyTests from "../utilities/propertyTests"; import {ByteVector, StringType} from "../../src/byteVector"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "../../src/id3v2/frames/frameHeader"; import {Allow, Testers} from "../utilities/testers"; +import {FrameFlags} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; -import PropertyTests from "../utilities/propertyTests"; import {NumberUtils} from "../../src/utils"; @suite class FrameHeaderTests { @@ -17,10 +18,10 @@ import {NumberUtils} from "../../src/utils"; const testBytes = ByteVector.empty(); // Act / Assert - Testers.testTruthy((v: ByteVector) => Id3v2FrameHeader.fromData(v, 3)); - Testers.testUint((v) => Id3v2FrameHeader.fromData(testBytes, v)); - assert.throws(() => Id3v2FrameHeader.fromData(testBytes, 1)); - assert.throws(() => Id3v2FrameHeader.fromData(testBytes, 5)); + Testers.testTruthy((v: ByteVector) => FrameHeader.fromData(v, 3)); + Testers.testUint((v) => FrameHeader.fromData(testBytes, v)); + assert.throws(() => FrameHeader.fromData(testBytes, 1)); + assert.throws(() => FrameHeader.fromData(testBytes, 5)); } @test @@ -29,7 +30,7 @@ import {NumberUtils} from "../../src/utils"; const testBytes = ByteVector.fromSize(2); // Act / Assert - assert.throws(() => Id3v2FrameHeader.fromData(testBytes, 2)); + assert.throws(() => FrameHeader.fromData(testBytes, 2)); } @test @@ -38,7 +39,7 @@ import {NumberUtils} from "../../src/utils"; const testBytes = ByteVector.fromString("TT1", StringType.Latin1); // Act - const header = Id3v2FrameHeader.fromData(testBytes, 2); + const header = FrameHeader.fromData(testBytes, 2); // Assert assert.isOk(header); @@ -53,7 +54,7 @@ import {NumberUtils} from "../../src/utils"; const testBytes = ByteVector.fromString("NON", StringType.Latin1); // Act - const header = Id3v2FrameHeader.fromData(testBytes, 2); + const header = FrameHeader.fromData(testBytes, 2); // Assert assert.isOk(header); @@ -68,7 +69,7 @@ import {NumberUtils} from "../../src/utils"; const testBytes = ByteVector.fromSize(3); // Act / Assert - assert.throws(() => Id3v2FrameHeader.fromData(testBytes, 3)); + assert.throws(() => FrameHeader.fromData(testBytes, 3)); } @test @@ -77,7 +78,7 @@ import {NumberUtils} from "../../src/utils"; const testBytes = ByteVector.fromString("TIT1", StringType.Latin1); // Act - const header = Id3v2FrameHeader.fromData(testBytes, 3); + const header = FrameHeader.fromData(testBytes, 3); // Assert assert.isOk(header); @@ -92,7 +93,7 @@ import {NumberUtils} from "../../src/utils"; const testBytes = ByteVector.fromString("NON1", StringType.Latin1); // Act - const header = Id3v2FrameHeader.fromData(testBytes, 3); + const header = FrameHeader.fromData(testBytes, 3); // Assert assert.isOk(header); @@ -107,7 +108,7 @@ import {NumberUtils} from "../../src/utils"; const testBytes = ByteVector.fromSize(3); // Act / Assert - assert.throws(() => Id3v2FrameHeader.fromData(testBytes, 4)); + assert.throws(() => FrameHeader.fromData(testBytes, 4)); } @test @@ -116,7 +117,7 @@ import {NumberUtils} from "../../src/utils"; const testBytes = ByteVector.fromString("TIT1", StringType.Latin1); // Act - const header = Id3v2FrameHeader.fromData(testBytes, 4); + const header = FrameHeader.fromData(testBytes, 4); // Assert assert.isOk(header); @@ -131,7 +132,7 @@ import {NumberUtils} from "../../src/utils"; const testBytes = ByteVector.fromString("NON1", StringType.Latin1); // Act - const header = Id3v2FrameHeader.fromData(testBytes, 4); + const header = FrameHeader.fromData(testBytes, 4); // Assert assert.isOk(header); @@ -147,7 +148,7 @@ import {NumberUtils} from "../../src/utils"; @test public dataLength_invalid() { // Arrange - const header = new Id3v2FrameHeader(FrameIdentifiers.APIC); + const header = new FrameHeader(FrameIdentifiers.APIC); // Act / Assert Testers.testSafeUint((v: number) => header.dataLength = v, Allow.Undefined); @@ -156,7 +157,7 @@ import {NumberUtils} from "../../src/utils"; @test public dataLength_valid() { // Arrange - const header = new Id3v2FrameHeader(FrameIdentifiers.APIC); + const header = new FrameHeader(FrameIdentifiers.APIC); const set = (v: number) => header.dataLength = v; const get = () => header.dataLength; @@ -169,7 +170,7 @@ import {NumberUtils} from "../../src/utils"; @test public encryptionId_throws() { // Arrange - const header = new Id3v2FrameHeader(FrameIdentifiers.APIC); + const header = new FrameHeader(FrameIdentifiers.APIC); // Act / Assert assert.throws(() => header.encryptionId = 123); @@ -178,7 +179,7 @@ import {NumberUtils} from "../../src/utils"; @test public frameSize_invalid() { // Arrange - const header = new Id3v2FrameHeader(FrameIdentifiers.APIC); + const header = new FrameHeader(FrameIdentifiers.APIC); // Act / Assert Testers.testSafeUint((v: number) => header.frameSize = v); @@ -187,7 +188,7 @@ import {NumberUtils} from "../../src/utils"; @test public frameSize_valid() { // Arrange - const header = new Id3v2FrameHeader(FrameIdentifiers.APIC); + const header = new FrameHeader(FrameIdentifiers.APIC); const set = (v: number) => header.frameSize = v; const get = () => header.frameSize; @@ -198,7 +199,7 @@ import {NumberUtils} from "../../src/utils"; @test public groupId_invalid() { // Arrange - const header = new Id3v2FrameHeader(FrameIdentifiers.APIC); + const header = new FrameHeader(FrameIdentifiers.APIC); // Act / Assert Testers.testByte((v: number) => header.groupId = v); @@ -207,30 +208,30 @@ import {NumberUtils} from "../../src/utils"; @test public groupId_valid() { // Arrange - const header = new Id3v2FrameHeader(FrameIdentifiers.APIC); + const header = new FrameHeader(FrameIdentifiers.APIC); const set = (v: number) => header.groupId = v; const get = () => header.groupId; // Act / Assert assert.isUndefined(header.groupId); - assert.isFalse(NumberUtils.hasFlag(header.flags, Id3v2FrameFlags.GroupingIdentity)); + assert.isFalse(NumberUtils.hasFlag(header.flags, FrameFlags.GroupingIdentity)); PropertyTests.propertyRoundTrip(set, get, 123); - assert.isTrue(NumberUtils.hasFlag(header.flags, Id3v2FrameFlags.GroupingIdentity)); + assert.isTrue(NumberUtils.hasFlag(header.flags, FrameFlags.GroupingIdentity)); PropertyTests.propertyRoundTrip(set, get, undefined); - assert.isFalse(NumberUtils.hasFlag(header.flags, Id3v2FrameFlags.GroupingIdentity)); + assert.isFalse(NumberUtils.hasFlag(header.flags, FrameFlags.GroupingIdentity)); PropertyTests.propertyRoundTrip(set, get, 234); - assert.isTrue(NumberUtils.hasFlag(header.flags, Id3v2FrameFlags.GroupingIdentity)); + assert.isTrue(NumberUtils.hasFlag(header.flags, FrameFlags.GroupingIdentity)); } @params(true, "true") @params(false, "false") public isUnsynchronizationApplied(hasFlag: boolean) { // Arrange - const flags = hasFlag ? Id3v2FrameFlags.Unsynchronized : Id3v2FrameFlags.None; - const header = new Id3v2FrameHeader(FrameIdentifiers.APIC, flags); + const flags = hasFlag ? FrameFlags.Unsynchronized : FrameFlags.None; + const header = new FrameHeader(FrameIdentifiers.APIC, flags); // Act const result = header.isUnsynchronizationApplied; @@ -248,7 +249,7 @@ import {NumberUtils} from "../../src/utils"; @params([4, 10], "v4") public getBaseSize([version, size]: [number, number]) { // Act - const result = Id3v2FrameHeader.getBaseSize(version); + const result = FrameHeader.getBaseSize(version); // Assert assert.strictEqual(result, size); @@ -257,7 +258,7 @@ import {NumberUtils} from "../../src/utils"; @test public clone_withoutIdentifier() { // Arrange - const header = new Id3v2FrameHeader(FrameIdentifiers.GEOB); + const header = new FrameHeader(FrameIdentifiers.GEOB); header.dataLength = 123; // header.encryptionId = 234; header.flags = 0xABCD; @@ -277,9 +278,9 @@ import {NumberUtils} from "../../src/utils"; @params(0x0000, "none") @params(0xFFFF, "all") - public readExtendedHeaderFromPayloadBytes_v2(flags: Id3v2FrameFlags) { + public readExtendedHeaderFromPayloadBytes_v2(flags: FrameFlags) { // Arrange - const header = new Id3v2FrameHeader(FrameIdentifiers.APIC); + const header = new FrameHeader(FrameIdentifiers.APIC); header.flags = flags; // Act @@ -293,35 +294,35 @@ import {NumberUtils} from "../../src/utils"; } @params([ - Id3v2FrameFlags.None, + FrameFlags.None, 0, undefined, undefined, undefined ], "None") @params([ - Id3v2FrameFlags.Compression, + FrameFlags.Compression, 4, 0x01020304, undefined, undefined ], "__C") @params([ - Id3v2FrameFlags.Encryption, + FrameFlags.Encryption, 1, undefined, 0x01, undefined ], "_E_") @params([ - Id3v2FrameFlags.Encryption|Id3v2FrameFlags.Compression, + FrameFlags.Encryption|FrameFlags.Compression, 5, 0x01020304, 0x05, undefined ], "_EC") @params([ - Id3v2FrameFlags.GroupingIdentity, + FrameFlags.GroupingIdentity, 1, undefined, undefined, 0x01 ], "G__") @params([ - Id3v2FrameFlags.GroupingIdentity|Id3v2FrameFlags.Compression, + FrameFlags.GroupingIdentity|FrameFlags.Compression, 5, 0x01020304, undefined, 0x05 ], "G_C") @params([ - Id3v2FrameFlags.GroupingIdentity|Id3v2FrameFlags.Encryption, + FrameFlags.GroupingIdentity|FrameFlags.Encryption, 2, undefined, 0x01, 0x02 ], "GE_") @params([ - Id3v2FrameFlags.GroupingIdentity|Id3v2FrameFlags.Encryption|Id3v2FrameFlags.Compression, + FrameFlags.GroupingIdentity|FrameFlags.Encryption|FrameFlags.Compression, 6, 0x01020304, 0x05, 0x06 ], "GEC") @params([ @@ -330,10 +331,10 @@ import {NumberUtils} from "../../src/utils"; ], "All") public readExtendedHeaderFromPayloadBytes_v3( [flags, length, dataLength, encryptionId, groupId]: - [Id3v2FrameFlags, number, number|undefined, number|undefined, number|undefined] + [FrameFlags, number, number|undefined, number|undefined, number|undefined] ) { // Arrange - const header = new Id3v2FrameHeader(FrameIdentifiers.APIC); + const header = new FrameHeader(FrameIdentifiers.APIC); header.flags = flags; const extendedBytes = ByteVector.fromByteArray([0x01, 0x02, 0x03, 0x04, 0x05, 0x06]); @@ -349,35 +350,35 @@ import {NumberUtils} from "../../src/utils"; } @params([ - Id3v2FrameFlags.None, + FrameFlags.None, 0, undefined, undefined, undefined ], "None") @params([ - Id3v2FrameFlags.GroupingIdentity, + FrameFlags.GroupingIdentity, 1, 0x01, undefined, undefined ], "__G") @params([ - Id3v2FrameFlags.Encryption, + FrameFlags.Encryption, 1, undefined, 0x01, undefined ], "_E_") @params([ - Id3v2FrameFlags.Encryption|Id3v2FrameFlags.GroupingIdentity, + FrameFlags.Encryption|FrameFlags.GroupingIdentity, 2, 0x01, 0x02, undefined ], "_EG") @params([ - Id3v2FrameFlags.DataLengthIndicator, + FrameFlags.DataLengthIndicator, 4, undefined, undefined, 0x00208184 ], "D__") @params([ - Id3v2FrameFlags.DataLengthIndicator|Id3v2FrameFlags.GroupingIdentity, + FrameFlags.DataLengthIndicator|FrameFlags.GroupingIdentity, 5, 0x01, undefined, 0x0040C205 ], "D_G") @params([ - Id3v2FrameFlags.DataLengthIndicator|Id3v2FrameFlags.Encryption, + FrameFlags.DataLengthIndicator|FrameFlags.Encryption, 5, undefined, 0x01, 0x0040C205 ], "DE_") @params([ - Id3v2FrameFlags.DataLengthIndicator|Id3v2FrameFlags.Encryption|Id3v2FrameFlags.GroupingIdentity, + FrameFlags.DataLengthIndicator|FrameFlags.Encryption|FrameFlags.GroupingIdentity, 6, 0x01, 0x02, 0x00610286 ], "GEC") @params([ @@ -386,9 +387,9 @@ import {NumberUtils} from "../../src/utils"; ], "All") public readExtendedHeaderFromPayloadBytes_v4( [flags, length, groupId, encryptionId, dataLength]: - [Id3v2FrameFlags, number, number|undefined, number|undefined, number|undefined]) { + [FrameFlags, number, number|undefined, number|undefined, number|undefined]) { // Arrange - const header = new Id3v2FrameHeader(FrameIdentifiers.APIC); + const header = new FrameHeader(FrameIdentifiers.APIC); header.flags = flags; const extendedBytes = ByteVector.fromByteArray([0x01, 0x02, 0x03, 0x04, 0x05, 0x06]); @@ -406,9 +407,9 @@ import {NumberUtils} from "../../src/utils"; @test public readExtendedHeaderFromPayloadBytes_notEnoughBytes() { // Arrange - const header = new Id3v2FrameHeader( + const header = new FrameHeader( FrameIdentifiers.APIC, - Id3v2FrameFlags.DataLengthIndicator + FrameFlags.DataLengthIndicator ); const extendedBytes = ByteVector.fromByteArray([0x00, 0x00, 0x02]); @@ -422,9 +423,9 @@ import {NumberUtils} from "../../src/utils"; @test public renderExtendedHeader_v4_dataLengthIndicatorIsSyncSafe() { // Arrange - const header = new Id3v2FrameHeader( + const header = new FrameHeader( FrameIdentifiers.APIC, - Id3v2FrameFlags.DataLengthIndicator + FrameFlags.DataLengthIndicator ); header.dataLength = 0x100; diff --git a/test-unit/id3v2/frameTests.ts b/test-unit/id3v2/frameTests.ts index 2c258081..5a0890d0 100644 --- a/test-unit/id3v2/frameTests.ts +++ b/test-unit/id3v2/frameTests.ts @@ -2,9 +2,10 @@ import {suite, test} from "@testdeck/mocha"; import {assert} from "chai"; import Frame from "../../src/id3v2/frames/frame"; +import FrameHeader from "../../src/id3v2/frames/frameHeader"; import PropertyTests from "../utilities/propertyTests"; import {ByteVector} from "../../src/byteVector"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "../../src/id3v2/frames/frameHeader"; +import {FrameFlags} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -15,7 +16,7 @@ class TestFrame extends Frame { ByteVector.fromSize(10, 0x00) ); - public constructor(header: Id3v2FrameHeader) { + public constructor(header: FrameHeader) { super(header); } @@ -36,7 +37,7 @@ class TestFrame extends Frame { @test public encryptionId_invalidValues() { // Arrange - const header = new Id3v2FrameHeader(FrameIdentifiers.TXXX); + const header = new FrameHeader(FrameIdentifiers.TXXX); const frame = new TestFrame(header); const set = (v: number) => { frame.encryptionId = v; }; @@ -49,7 +50,7 @@ class TestFrame extends Frame { @test public encryptionId() { // Arrange - const header = new Id3v2FrameHeader(FrameIdentifiers.TXXX, Id3v2FrameFlags.FileAlterPreservation); + const header = new FrameHeader(FrameIdentifiers.TXXX, FrameFlags.FileAlterPreservation); const frame = new TestFrame(header); const get = () => frame.encryptionId; const set = (v: number) => { frame.encryptionId = v; }; @@ -58,16 +59,16 @@ class TestFrame extends Frame { assert.isUndefined(frame.encryptionId); PropertyTests.propertyThrows(set, 0x88); - assert.strictEqual(frame.flags, Id3v2FrameFlags.FileAlterPreservation); + assert.strictEqual(frame.flags, FrameFlags.FileAlterPreservation); PropertyTests.propertyRoundTrip(set, get, undefined); - assert.strictEqual(frame.flags, Id3v2FrameFlags.FileAlterPreservation); + assert.strictEqual(frame.flags, FrameFlags.FileAlterPreservation); } @test public groupId_invalidValues() { // Arrange - const header = new Id3v2FrameHeader(FrameIdentifiers.TXXX); + const header = new FrameHeader(FrameIdentifiers.TXXX); const frame = new TestFrame(header); const set = (v: number) => { frame.groupId = v; }; @@ -80,7 +81,7 @@ class TestFrame extends Frame { @test public groupId() { // Arrange - const header = new Id3v2FrameHeader(FrameIdentifiers.TXXX, Id3v2FrameFlags.FileAlterPreservation); + const header = new FrameHeader(FrameIdentifiers.TXXX, FrameFlags.FileAlterPreservation); const frame = new TestFrame(header); const get = () => frame.groupId; const set = (v: number) => { frame.groupId = v; }; @@ -89,16 +90,16 @@ class TestFrame extends Frame { assert.isUndefined(frame.groupId); PropertyTests.propertyRoundTrip(set, get, 0x88); - assert.strictEqual(frame.flags, Id3v2FrameFlags.FileAlterPreservation | Id3v2FrameFlags.GroupingIdentity); + assert.strictEqual(frame.flags, FrameFlags.FileAlterPreservation | FrameFlags.GroupingIdentity); PropertyTests.propertyRoundTrip(set, get, undefined); - assert.strictEqual(frame.flags, Id3v2FrameFlags.FileAlterPreservation); + assert.strictEqual(frame.flags, FrameFlags.FileAlterPreservation); } @test public render_dataLengthIndicator() { // Arrange - const header = new Id3v2FrameHeader(FrameIdentifiers.TXXX, Id3v2FrameFlags.DataLengthIndicator); + const header = new FrameHeader(FrameIdentifiers.TXXX, FrameFlags.DataLengthIndicator); const frame = new TestFrame(header); // Act @@ -116,7 +117,7 @@ class TestFrame extends Frame { @test public render_groupingIdentity() { // Arrange - const header = new Id3v2FrameHeader(FrameIdentifiers.TXXX, Id3v2FrameFlags.GroupingIdentity); + const header = new FrameHeader(FrameIdentifiers.TXXX, FrameFlags.GroupingIdentity); const frame = new TestFrame(header); frame.groupId = 0x88; diff --git a/test-unit/id3v2/genreFrameTests.ts b/test-unit/id3v2/genreFrameTests.ts index 8423545a..025ea860 100644 --- a/test-unit/id3v2/genreFrameTests.ts +++ b/test-unit/id3v2/genreFrameTests.ts @@ -3,11 +3,12 @@ import {assert} from "chai"; import Frame from "../../src/id3v2/frames/frame"; import FrameConstructorTests from "./frameConstructorTests"; +import FrameHeader from "../../src/id3v2/frames/frameHeader"; import GenreFrame from "../../src/id3v2/frames/genreFrame"; import Id3v2Settings from "../../src/id3v2/id3v2Settings"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "../../src/id3v2/frames/frameHeader"; +import {FrameFlags} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -453,7 +454,7 @@ class Id3v2_GenreFrameTests extends FrameConstructorTests { const fieldBytes = payload instanceof ByteVector ? payload : ByteVector.concatenate(StringType.UTF16BE, ByteVector.fromString(payload, StringType.UTF16BE)); - const header = new Id3v2FrameHeader(FrameIdentifiers.TCON, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.TCON, FrameFlags.None, fieldBytes.length); // Act const frame = GenreFrame.fromFieldBytes(header, fieldBytes, tagVersion); @@ -493,7 +494,7 @@ class Id3v2_GenreFrameTests extends FrameConstructorTests { StringType.UTF16BE, ByteVector.fromString(expected, StringType.UTF16BE) ); - const expectedHeader = new Id3v2FrameHeader(FrameIdentifiers.TCON, Id3v2FrameFlags.None, expectedBody.length); + const expectedHeader = new FrameHeader(FrameIdentifiers.TCON, FrameFlags.None, expectedBody.length); const expectedBytes = ByteVector.concatenate(expectedHeader.render(tagVersion), expectedBody); Testers.bvEqual(result, expectedBytes); @@ -520,7 +521,7 @@ class Id3v2_GenreFrameTests extends FrameConstructorTests { StringType.UTF16BE, ... this.getDelimitedStrings(expected) ); - const expectedHeader = new Id3v2FrameHeader(FrameIdentifiers.TCON, Id3v2FrameFlags.None, expectedBody.length); + const expectedHeader = new FrameHeader(FrameIdentifiers.TCON, FrameFlags.None, expectedBody.length); const expectedBytes = ByteVector.concatenate(expectedHeader.render(4), expectedBody); Testers.bvEqual(result, expectedBytes); diff --git a/test-unit/id3v2/id3v2TagTests.ts b/test-unit/id3v2/id3v2TagTests.ts index e8ebdf48..60ab14eb 100644 --- a/test-unit/id3v2/id3v2TagTests.ts +++ b/test-unit/id3v2/id3v2TagTests.ts @@ -7,28 +7,27 @@ import CommentsFrame from "../../src/id3v2/frames/commentsFrame"; import GenreFrame from "../../src/id3v2/frames/genreFrame"; import Id3v2Settings from "../../src/id3v2/id3v2Settings"; import Id3v2Tag from "../../src/id3v2/id3v2Tag"; -import Id3v2TagFooter from "../../src/id3v2/id3v2TagFooter"; +import Id3v2TagFooter from "../../src/id3v2/tagFooter"; import PlayCountFrame from "../../src/id3v2/frames/playCountFrame"; import PrivateFrame from "../../src/id3v2/frames/privateFrame"; import PropertyTests from "../utilities/propertyTests"; import SyncData from "../../src/id3v2/syncData"; +import TagHeader from "../../src/id3v2/tagHeader"; import TestFile from "../utilities/testFile"; import TextInformationFrame from "../../src/id3v2/frames/textInformationFrame"; import UniqueFileIdentifierFrame from "../../src/id3v2/frames/uniqueFileIdentifierFrame"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import UnsynchronizedLyricsFrame from "../../src/id3v2/frames/unsynchronizedLyricsFrame"; -import UrlLinkFrame from "../../src/id3v2/frames/urlLinkFrame"; import UserTextInformationFrame from "../../src/id3v2/frames/userTextInformationFrame"; import {ByteVector, StringType} from "../../src/byteVector"; +import {TagFlags} from "../../src/id3v2/enums"; import {File, ReadStyle} from "../../src/file"; -import {Id3v2FrameFlags} from "../../src/id3v2/frames/frameHeader"; import {FrameIdentifier, FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; -import {Id3v2TagHeader, Id3v2TagHeaderFlags} from "../../src/id3v2/id3v2TagHeader"; import {IPicture} from "../../src/picture"; import {TagTypes} from "../../src/tag"; import {Testers} from "../utilities/testers"; -const getTestTagHeader = (version: number, flags: Id3v2TagHeaderFlags, tagSize: number): ByteVector => { +const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): ByteVector => { return ByteVector.concatenate( ByteVector.fromString("ID3", StringType.Latin1), version, 0x00, @@ -56,7 +55,7 @@ const getTestTagHeader = (version: number, flags: Id3v2TagHeaderFlags, tagSize: @test public fromData_emptyTag() { // Arrange - const data = getTestTagHeader(4, Id3v2TagHeaderFlags.None, 0); + const data = getTestTagHeader(4, TagFlags.None, 0); // Act const output = Id3v2Tag.fromData(data); @@ -70,7 +69,7 @@ const getTestTagHeader = (version: number, flags: Id3v2TagHeaderFlags, tagSize: public fromData_dataTooShortForTagLength() { // Arrange const data = ByteVector.concatenate( - getTestTagHeader(4, Id3v2TagHeaderFlags.None, 5), + getTestTagHeader(4, TagFlags.None, 5), 0x00, 0x00 ); @@ -87,7 +86,7 @@ const getTestTagHeader = (version: number, flags: Id3v2TagHeaderFlags, tagSize: UnknownFrame.fromFields(FrameIdentifiers.RVRB, ByteVector.empty()).render(4), // Empty frame ByteVector.fromSize(5) // Padding ); - const tagHeader = getTestTagHeader(4, Id3v2TagHeaderFlags.None, frameBytes.length); + const tagHeader = getTestTagHeader(4, TagFlags.None, frameBytes.length); const data = ByteVector.concatenate(tagHeader, frameBytes); // Act @@ -120,7 +119,7 @@ const getTestTagHeader = (version: number, flags: Id3v2TagHeaderFlags, tagSize: // Arrange const frame1 = PlayCountFrame.fromFields().render(4); const data = ByteVector.concatenate( - getTestTagHeader(4, Id3v2TagHeaderFlags.ExtendedHeader, frame1.length + 10), + getTestTagHeader(4, TagFlags.ExtendedHeader, frame1.length + 10), SyncData.fromUint(10), 0x01, 0x00, @@ -145,7 +144,7 @@ const getTestTagHeader = (version: number, flags: Id3v2TagHeaderFlags, tagSize: // Arrange const frame1 = PlayCountFrame.fromFields(BigInt(123)).render(4); const data = ByteVector.concatenate( - getTestTagHeader(3, Id3v2TagHeaderFlags.Unsynchronization, frame1.length), + getTestTagHeader(3, TagFlags.Unsynchronization, frame1.length), frame1 ); SyncData.unsyncByteVector(data); @@ -190,7 +189,7 @@ const getTestTagHeader = (version: number, flags: Id3v2TagHeaderFlags, tagSize: @test public fromFileStart_emptyTag() { // Arrange - const data = getTestTagHeader(4, Id3v2TagHeaderFlags.None, 0); + const data = getTestTagHeader(4, TagFlags.None, 0); const file = TestFile.getFile(data); // Act @@ -210,7 +209,7 @@ const getTestTagHeader = (version: number, flags: Id3v2TagHeaderFlags, tagSize: UnknownFrame.fromFields(FrameIdentifiers.RVRB).render(4), // Empty frame ByteVector.fromSize(5) // Padding ); - const headerBytes = getTestTagHeader(4, Id3v2TagHeaderFlags.None, frameBytes.length); + const headerBytes = getTestTagHeader(4, TagFlags.None, frameBytes.length); const data = ByteVector.concatenate(ByteVector.fromSize(offset), headerBytes, frameBytes); const file = TestFile.getFile(data); @@ -250,7 +249,7 @@ const getTestTagHeader = (version: number, flags: Id3v2TagHeaderFlags, tagSize: PropertyTests.propertyRoundTrip( (v) => { tag.flags = v; }, () => tag.flags, - Id3v2TagHeaderFlags.ExperimentalIndicator + TagFlags.ExperimentalIndicator ); } @@ -1648,7 +1647,7 @@ const getTestTagHeader = (version: number, flags: Id3v2TagHeaderFlags, tagSize: frame2.render(4), ByteVector.fromSize(1024, 0x00) ); - const header = new Id3v2TagHeader(4, 0, Id3v2TagHeaderFlags.None, frameBytes.length); + const header = new TagHeader(4, 0, TagFlags.None, frameBytes.length); const expected = ByteVector.concatenate(header.render(), frameBytes); Testers.bvEqual(output, expected); @@ -1659,7 +1658,7 @@ const getTestTagHeader = (version: number, flags: Id3v2TagHeaderFlags, tagSize: // Arrange const tag = Id3v2Tag.fromEmpty(); tag.version = 4; - tag.flags = Id3v2TagHeaderFlags.FooterPresent; + tag.flags = TagFlags.FooterPresent; const frame1 = TextInformationFrame.fromFields(FrameIdentifiers.TCOM); const frame2 = TextInformationFrame.fromFields(FrameIdentifiers.TCON); @@ -1673,7 +1672,7 @@ const getTestTagHeader = (version: number, flags: Id3v2TagHeaderFlags, tagSize: frame1.render(4), frame2.render(4) ); - const header = new Id3v2TagHeader(4, 0, Id3v2TagHeaderFlags.FooterPresent, frameBytes.length); + const header = new TagHeader(4, 0, TagFlags.FooterPresent, frameBytes.length); const expected = ByteVector.concatenate( header.render(), frameBytes, @@ -1691,7 +1690,7 @@ const getTestTagHeader = (version: number, flags: Id3v2TagHeaderFlags, tagSize: const tag = Id3v2Tag.fromEmpty(); tag.version = 4; - tag.flags = Id3v2TagHeaderFlags.Unsynchronization; + tag.flags = TagFlags.Unsynchronization; tag.frames.push(frame1, frame2); // Act @@ -1703,7 +1702,7 @@ const getTestTagHeader = (version: number, flags: Id3v2TagHeaderFlags, tagSize: frame2.render(4), ByteVector.fromSize(1024) ); - const header = new Id3v2TagHeader(4, 0, Id3v2TagHeaderFlags.Unsynchronization, frameBytes.length); + const header = new TagHeader(4, 0, TagFlags.Unsynchronization, frameBytes.length); const expected = ByteVector.concatenate(header.render(), frameBytes); Testers.bvEqual(output, expected); @@ -1717,7 +1716,7 @@ const getTestTagHeader = (version: number, flags: Id3v2TagHeaderFlags, tagSize: const tag = Id3v2Tag.fromEmpty(); tag.version = 3; - tag.flags = Id3v2TagHeaderFlags.Unsynchronization; + tag.flags = TagFlags.Unsynchronization; tag.frames.push(frame1, frame2); // Act @@ -1729,7 +1728,7 @@ const getTestTagHeader = (version: number, flags: Id3v2TagHeaderFlags, tagSize: frame2.render(3), ByteVector.fromSize(1024) )); - const header = new Id3v2TagHeader(3, 0, Id3v2TagHeaderFlags.Unsynchronization, frameData.length); + const header = new TagHeader(3, 0, TagFlags.Unsynchronization, frameData.length); const expected = ByteVector.concatenate(header.render(), frameData); Testers.bvEqual(output, expected); diff --git a/test-unit/id3v2/musicCdIdentifierFrameTests.ts b/test-unit/id3v2/musicCdIdentifierFrameTests.ts index 28318024..61e5848a 100644 --- a/test-unit/id3v2/musicCdIdentifierFrameTests.ts +++ b/test-unit/id3v2/musicCdIdentifierFrameTests.ts @@ -3,16 +3,17 @@ import {assert} from "chai"; import Frame from "../../src/id3v2/frames/frame"; import FrameConstructorTests from "./frameConstructorTests"; +import FrameHeader from "../../src/id3v2/frames/frameHeader"; import MusicCdIdentifierFrame from "../../src/id3v2/frames/musicCdIdentifierFrame"; import PropertyTests from "../utilities/propertyTests"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "../../src/id3v2/frames/frameHeader"; +import {FrameFlags} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @suite class Id3v2_MusicCdIdentifierFrameTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: Id3v2FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { return MusicCdIdentifierFrame.fromFieldBytes; } @@ -22,7 +23,7 @@ import {Testers} from "../utilities/testers"; public fromFieldBytes_validParams(version: number) { // Arrange const fieldBytes = ByteVector.fromString("foo bar baz", StringType.UTF8); - const header = new Id3v2FrameHeader(FrameIdentifiers.MCDI, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.MCDI, FrameFlags.None, fieldBytes.length); // Act const frame = MusicCdIdentifierFrame.fromFieldBytes(header, fieldBytes, version); @@ -68,7 +69,7 @@ import {Testers} from "../utilities/testers"; public clone_returnsCopy(version: number) { // Arrange const fieldBytes = ByteVector.fromString("foo bar baz", StringType.UTF8); - const header = new Id3v2FrameHeader(FrameIdentifiers.MCDI, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.MCDI, FrameFlags.None, fieldBytes.length); const frame = MusicCdIdentifierFrame.fromFieldBytes(header, fieldBytes, version); // Act @@ -165,7 +166,7 @@ import {Testers} from "../utilities/testers"; public render_returnsByteVector(version: number) { // Arrange const fieldBytes = ByteVector.fromString("foo bar baz", StringType.UTF8); - const header = new Id3v2FrameHeader(FrameIdentifiers.MCDI, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.MCDI, FrameFlags.None, fieldBytes.length); const frame = MusicCdIdentifierFrame.fromFieldBytes(header, fieldBytes, version); // Act diff --git a/test-unit/id3v2/playCountFrameTests.ts b/test-unit/id3v2/playCountFrameTests.ts index 74250b62..d8c6c707 100644 --- a/test-unit/id3v2/playCountFrameTests.ts +++ b/test-unit/id3v2/playCountFrameTests.ts @@ -3,11 +3,12 @@ import {assert} from "chai"; import Frame from "../../src/id3v2/frames/frame"; import FrameConstructorTests from "./frameConstructorTests"; +import FrameHeader from "../../src/id3v2/frames/frameHeader"; import PlayCountFrame from "../../src/id3v2/frames/playCountFrame"; import PropertyTests from "../utilities/propertyTests"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector} from "../../src/byteVector"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "../../src/id3v2/frames/frameHeader"; +import {FrameFlags} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -20,7 +21,7 @@ const assertFrame = (frame: PlayCountFrame, p: bigint) => { } @suite class Id3v2_PlayCountFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: Id3v2FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { return PlayCountFrame.fromFieldBytes; } @@ -30,7 +31,7 @@ const assertFrame = (frame: PlayCountFrame, p: bigint) => { public fromFieldBytes_tooBig(version: number) { // Arrange const fieldBytes = ByteVector.fromByteArray([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09]); - const header = new Id3v2FrameHeader(FrameIdentifiers.PCNT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.PCNT, FrameFlags.None, fieldBytes.length); // Act / Assert assert.throws(() => PlayCountFrame.fromFieldBytes(header, fieldBytes, version)); @@ -42,7 +43,7 @@ const assertFrame = (frame: PlayCountFrame, p: bigint) => { public fromFieldBytes_tooSmall(version: number) { // Arrange const fieldBytes = ByteVector.fromByteArray([0x01, 0x02, 0x03]); - const header = new Id3v2FrameHeader(FrameIdentifiers.PCNT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.PCNT, FrameFlags.None, fieldBytes.length); // Act / Assert assert.throws(() => PlayCountFrame.fromFieldBytes(header, fieldBytes, version)); @@ -54,7 +55,7 @@ const assertFrame = (frame: PlayCountFrame, p: bigint) => { public fromFieldBytes_fourBytePlayCount(version: number) { // Arrange const fieldBytes = ByteVector.fromUint(1234); - const header = new Id3v2FrameHeader(FrameIdentifiers.PCNT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.PCNT, FrameFlags.None, fieldBytes.length); // Act const frame = PlayCountFrame.fromFieldBytes(header, fieldBytes, version); @@ -69,7 +70,7 @@ const assertFrame = (frame: PlayCountFrame, p: bigint) => { public fromFieldBytes_sixBytePlayCount(version: number) { // Arrange const fieldBytes = ByteVector.fromByteArray([0x01, 0x02, 0x03, 0x04, 0x05, 0x06]); - const header = new Id3v2FrameHeader(FrameIdentifiers.PCNT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.PCNT, FrameFlags.None, fieldBytes.length); // Act const frame = PlayCountFrame.fromFieldBytes(header, fieldBytes, version); @@ -84,7 +85,7 @@ const assertFrame = (frame: PlayCountFrame, p: bigint) => { public fromFieldBytes_eightBytePlayCount(version: number) { // Arrange const fieldBytes = ByteVector.fromByteArray([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]); - const header = new Id3v2FrameHeader(FrameIdentifiers.PCNT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.PCNT, FrameFlags.None, fieldBytes.length); // Act const frame = PlayCountFrame.fromFieldBytes(header, fieldBytes, version); @@ -235,7 +236,7 @@ const assertFrame = (frame: PlayCountFrame, p: bigint) => { assert.isOk(output); const fieldBytes = ByteVector.fromUint(1234); - const header = new Id3v2FrameHeader(FrameIdentifiers.PCNT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.PCNT, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(version), fieldBytes); Testers.bvEqual(output, expected); } @@ -254,7 +255,7 @@ const assertFrame = (frame: PlayCountFrame, p: bigint) => { assert.isOk(output); const fieldBytes = ByteVector.fromByteArray([0x01, 0x02, 0x03, 0x04, 0x05, 0x06]); - const header = new Id3v2FrameHeader(FrameIdentifiers.PCNT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.PCNT, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(version), fieldBytes); Testers.bvEqual(output, expected); } @@ -273,7 +274,7 @@ const assertFrame = (frame: PlayCountFrame, p: bigint) => { assert.isOk(output); const fieldBytes = ByteVector.fromByteArray([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]); - const header = new Id3v2FrameHeader(FrameIdentifiers.PCNT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.PCNT, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(version), fieldBytes); Testers.bvEqual(output, expected); } diff --git a/test-unit/id3v2/popularimeterFrameTests.ts b/test-unit/id3v2/popularimeterFrameTests.ts index 4c1fd6db..cef25544 100644 --- a/test-unit/id3v2/popularimeterFrameTests.ts +++ b/test-unit/id3v2/popularimeterFrameTests.ts @@ -3,11 +3,12 @@ import {assert} from "chai"; import Frame from "../../src/id3v2/frames/frame"; import FrameConstructorTests from "./frameConstructorTests"; +import FrameHeader from "../../src/id3v2/frames/frameHeader"; import PopularimeterFrame from "../../src/id3v2/frames/popularimeterFrame"; import PropertyTests from "../utilities/propertyTests"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "../../src/id3v2/frames/frameHeader"; +import {FrameFlags} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -22,7 +23,7 @@ const assertFrame = (frame: PopularimeterFrame, u: string, p: bigint, r: number) } @suite class Id3v2_PopularimeterFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: Id3v2FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { return PopularimeterFrame.fromFieldBytes; } @@ -32,7 +33,7 @@ const assertFrame = (frame: PopularimeterFrame, u: string, p: bigint, r: number) public fromFieldBytes_noDelimiter(version: number) { // Arrange const fieldBytes = ByteVector.fromByteArray([0x01, 0x02, 0x03]); - const header = new Id3v2FrameHeader(FrameIdentifiers.POPM, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.POPM, FrameFlags.None, fieldBytes.length); // Act / Assert assert.throws(() => { PopularimeterFrame.fromFieldBytes(header, fieldBytes, version); }); @@ -46,7 +47,7 @@ const assertFrame = (frame: PopularimeterFrame, u: string, p: bigint, r: number) const fieldBytes = ByteVector.concatenate( ByteVector.fromString("foo@example.com", StringType.Latin1), 0x00 // Owner + delimiter ); - const header = new Id3v2FrameHeader(FrameIdentifiers.POPM, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.POPM, FrameFlags.None, fieldBytes.length); // Act / Assert assert.throws(() => { PopularimeterFrame.fromFieldBytes(header, fieldBytes, version); }); @@ -62,7 +63,7 @@ const assertFrame = (frame: PopularimeterFrame, u: string, p: bigint, r: number) 0xAB, // Rating 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09 // Play counter (too big) ); - const header = new Id3v2FrameHeader(FrameIdentifiers.POPM, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.POPM, FrameFlags.None, fieldBytes.length); // Act / Assert assert.throws(() => { PopularimeterFrame.fromFieldBytes(header, fieldBytes, version); }); @@ -80,7 +81,7 @@ const assertFrame = (frame: PopularimeterFrame, u: string, p: bigint, r: number) ByteVector.fromByteArray(playCountBytes) // Play counter (too small) ); - const header = new Id3v2FrameHeader(FrameIdentifiers.POPM, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.POPM, FrameFlags.None, fieldBytes.length); // Act const frame = PopularimeterFrame.fromFieldBytes(header, fieldBytes, 4); @@ -99,7 +100,7 @@ const assertFrame = (frame: PopularimeterFrame, u: string, p: bigint, r: number) 0xAB, // Rating ByteVector.fromUint(1234) // Play counter ); - const header = new Id3v2FrameHeader(FrameIdentifiers.POPM, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.POPM, FrameFlags.None, fieldBytes.length); // Act const frame = PopularimeterFrame.fromFieldBytes(header, fieldBytes, version); @@ -118,7 +119,7 @@ const assertFrame = (frame: PopularimeterFrame, u: string, p: bigint, r: number) 0xAB, // Rating ByteVector.fromByteArray([0x01, 0x02, 0x03, 0x04, 0x05, 0x06]) // Play counter ); - const header = new Id3v2FrameHeader(FrameIdentifiers.POPM, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.POPM, FrameFlags.None, fieldBytes.length); // Act const frame = PopularimeterFrame.fromFieldBytes(header, fieldBytes, version); @@ -137,7 +138,7 @@ const assertFrame = (frame: PopularimeterFrame, u: string, p: bigint, r: number) 0xAB, // Rating ByteVector.fromByteArray([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]) // Play counter ); - const header = new Id3v2FrameHeader(FrameIdentifiers.POPM, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.POPM, FrameFlags.None, fieldBytes.length); // Act const frame = PopularimeterFrame.fromFieldBytes(header, fieldBytes, version); @@ -337,7 +338,7 @@ const assertFrame = (frame: PopularimeterFrame, u: string, p: bigint, r: number) ByteVector.fromString("foo@example.com", StringType.Latin1), 0x00, // Owner + delimiter 0xAB // Rating ); - const header = new Id3v2FrameHeader(FrameIdentifiers.POPM, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.POPM, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(version), fieldBytes); Testers.bvEqual(output, expected); } @@ -360,7 +361,7 @@ const assertFrame = (frame: PopularimeterFrame, u: string, p: bigint, r: number) 0xAB, // Rating ByteVector.fromUint(1234) // Play counter ); - const header = new Id3v2FrameHeader(FrameIdentifiers.POPM, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.POPM, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(version), fieldBytes); Testers.bvEqual(output, expected); } @@ -383,7 +384,7 @@ const assertFrame = (frame: PopularimeterFrame, u: string, p: bigint, r: number) 0xAB, // Rating ByteVector.fromByteArray([0x01, 0x02, 0x03, 0x04, 0x05, 0x06]) // Play counter ); - const header = new Id3v2FrameHeader(FrameIdentifiers.POPM, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.POPM, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(version), fieldBytes); Testers.bvEqual(output, expected); } @@ -406,7 +407,7 @@ const assertFrame = (frame: PopularimeterFrame, u: string, p: bigint, r: number) 0xAB, // Rating ByteVector.fromByteArray([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]) // Play counter ); - const header = new Id3v2FrameHeader(FrameIdentifiers.POPM, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.POPM, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(version), fieldBytes); Testers.bvEqual(output, expected); } diff --git a/test-unit/id3v2/privateFrameTests.ts b/test-unit/id3v2/privateFrameTests.ts index 67978d9e..1330e0f2 100644 --- a/test-unit/id3v2/privateFrameTests.ts +++ b/test-unit/id3v2/privateFrameTests.ts @@ -3,11 +3,12 @@ import {assert} from "chai"; import Frame from "../../src/id3v2/frames/frame"; import FrameConstructorTests from "./frameConstructorTests"; +import FrameHeader from "../../src/id3v2/frames/frameHeader"; import PropertyTests from "../utilities/propertyTests"; import PrivateFrame from "../../src/id3v2/frames/privateFrame"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "../../src/id3v2/frames/frameHeader"; +import {FrameFlags} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -21,7 +22,7 @@ const assertFrame = (frame: PrivateFrame, o: string, d: ByteVector) => { } @suite class Id3v2_PrivateFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: Id3v2FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { return PrivateFrame.fromFieldBytes; } @@ -29,7 +30,7 @@ const assertFrame = (frame: PrivateFrame, o: string, d: ByteVector) => { public fromFieldBytes_tooFewBytes_throws() { // Arrange const fieldBytes = ByteVector.empty(); - const header = new Id3v2FrameHeader(FrameIdentifiers.PRIV, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.PRIV, FrameFlags.None, fieldBytes.length); // Act / Assert assert.throws(() => { PrivateFrame.fromFieldBytes(header, fieldBytes, 4); }); @@ -44,7 +45,7 @@ const assertFrame = (frame: PrivateFrame, o: string, d: ByteVector) => { ByteVector.fromString("fux", StringType.Latin1), // Owner 0x00 // Separator ); - const header = new Id3v2FrameHeader(FrameIdentifiers.PRIV, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.PRIV, FrameFlags.None, fieldBytes.length); // Act const frame = PrivateFrame.fromFieldBytes(header, fieldBytes, version); @@ -63,7 +64,7 @@ const assertFrame = (frame: PrivateFrame, o: string, d: ByteVector) => { 0x00, // Separator dataBytes // Data ); - const header = new Id3v2FrameHeader(FrameIdentifiers.PRIV, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.PRIV, FrameFlags.None, fieldBytes.length); // Act const frame = PrivateFrame.fromFieldBytes(header, fieldBytes, version); @@ -83,7 +84,7 @@ const assertFrame = (frame: PrivateFrame, o: string, d: ByteVector) => { 0x00, // Separator dataBytes // Data ); - const header = new Id3v2FrameHeader(FrameIdentifiers.PRIV, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.PRIV, FrameFlags.None, fieldBytes.length); // Act const frame = PrivateFrame.fromFieldBytes(header, fieldBytes, version); @@ -251,7 +252,7 @@ const assertFrame = (frame: PrivateFrame, o: string, d: ByteVector) => { 0x00, // Separator dataBytes // Data ); - const header = new Id3v2FrameHeader(FrameIdentifiers.PRIV, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.PRIV, FrameFlags.None, fieldBytes.length); const frame = PrivateFrame.fromFieldBytes(header, fieldBytes, version); // Act @@ -271,7 +272,7 @@ const assertFrame = (frame: PrivateFrame, o: string, d: ByteVector) => { ByteVector.fromString("fux", StringType.Latin1), // Owner 0x00 // Separator ); - const header = new Id3v2FrameHeader(FrameIdentifiers.PRIV, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.PRIV, FrameFlags.None, fieldBytes.length); const frame = PrivateFrame.fromFieldBytes(header, fieldBytes, 4); // Act @@ -292,7 +293,7 @@ const assertFrame = (frame: PrivateFrame, o: string, d: ByteVector) => { 0x00, // Separator dataBytes // Data ); - const header = new Id3v2FrameHeader(FrameIdentifiers.PRIV, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.PRIV, FrameFlags.None, fieldBytes.length); const frame = PrivateFrame.fromFieldBytes(header, fieldBytes, 4); // Act diff --git a/test-unit/id3v2/relativeVolumeFrameTests.ts b/test-unit/id3v2/relativeVolumeFrameTests.ts index 4aec1bef..aa191d6c 100644 --- a/test-unit/id3v2/relativeVolumeFrameTests.ts +++ b/test-unit/id3v2/relativeVolumeFrameTests.ts @@ -3,11 +3,12 @@ import {assert} from "chai"; import Frame from "../../src/id3v2/frames/frame"; import FrameConstructorTests from "./frameConstructorTests"; +import FrameHeader from "../../src/id3v2/frames/frameHeader"; import PropertyTests from "../utilities/propertyTests"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; -import {ChannelData, ChannelType, RelativeVolumeFrame} from "../../src/id3v2/frames/relativeVolumeFrame"; +import {ChannelData, RelativeVolumeFrame} from "../../src/id3v2/frames/relativeVolumeFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "../../src/id3v2/frames/frameHeader"; +import {ChannelType, FrameFlags} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -283,7 +284,7 @@ const assertFrame = (frame: RelativeVolumeFrame, c: ChannelData[], i: string) => } @suite class Id3v2_RelativeVolumeFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: Id3v2FrameHeader, b: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, b: ByteVector, v: number) => Frame { return RelativeVolumeFrame.fromFieldBytes; } @@ -293,7 +294,7 @@ const assertFrame = (frame: RelativeVolumeFrame, c: ChannelData[], i: string) => public fromFieldBytes_emptyFrame_throws(version: number) { // Arrange const fieldBytes = ByteVector.empty(); - const header = new Id3v2FrameHeader(FrameIdentifiers.RVA2, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.RVA2, FrameFlags.None, fieldBytes.length); // Act / Assert assert.throws(() => RelativeVolumeFrame.fromFieldBytes(header, fieldBytes, version)); @@ -305,7 +306,7 @@ const assertFrame = (frame: RelativeVolumeFrame, c: ChannelData[], i: string) => public fromFieldBytes_identifierOnly(version: number) { // Arrange const fieldBytes = ByteVector.concatenate(ByteVector.fromString("foobarbaz", StringType.Latin1), 0x00); - const header = new Id3v2FrameHeader(FrameIdentifiers.RVA2, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.RVA2, FrameFlags.None, fieldBytes.length); // Act const frame = RelativeVolumeFrame.fromFieldBytes(header, fieldBytes, version); @@ -326,7 +327,7 @@ const assertFrame = (frame: RelativeVolumeFrame, c: ChannelData[], i: string) => 0x20, // Bits representing peak (32) 0x01, 0x02, 0x03, 0x04 // Peak volume ); - const header = new Id3v2FrameHeader(FrameIdentifiers.RVA2, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.RVA2, FrameFlags.None, fieldBytes.length); // Act const frame = RelativeVolumeFrame.fromFieldBytes(header, fieldBytes, version); @@ -357,7 +358,7 @@ const assertFrame = (frame: RelativeVolumeFrame, c: ChannelData[], i: string) => 0x20, // Bits representing peak (32) 0x02, 0x03, 0x04, 0x05 // Peak volume ); - const header = new Id3v2FrameHeader(FrameIdentifiers.RVA2, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.RVA2, FrameFlags.None, fieldBytes.length); // Act const frame = RelativeVolumeFrame.fromFieldBytes(header, fieldBytes, version); @@ -391,7 +392,7 @@ const assertFrame = (frame: RelativeVolumeFrame, c: ChannelData[], i: string) => ChannelType.BackRight, // Channel type ByteVector.fromShort(234), // Volume adjustment ); - const header = new Id3v2FrameHeader(FrameIdentifiers.RVA2, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.RVA2, FrameFlags.None, fieldBytes.length); // Act const frame = RelativeVolumeFrame.fromFieldBytes(header, fieldBytes, version); @@ -422,7 +423,7 @@ const assertFrame = (frame: RelativeVolumeFrame, c: ChannelData[], i: string) => 0x30, // Bits representing peak (48) 0x02, 0x03, 0x04, 0x05 // Peak volume (not enough) ); - const header = new Id3v2FrameHeader(FrameIdentifiers.RVA2, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.RVA2, FrameFlags.None, fieldBytes.length); // Act const frame = RelativeVolumeFrame.fromFieldBytes(header, fieldBytes, version); @@ -640,7 +641,7 @@ const assertFrame = (frame: RelativeVolumeFrame, c: ChannelData[], i: string) => // Assert const fieldBytes = ByteVector.concatenate(ByteVector.fromString("foobarbaz", StringType.Latin1), 0x00); - const header = new Id3v2FrameHeader(FrameIdentifiers.RVA2, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.RVA2, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(version), fieldBytes); Testers.bvEqual(output, expected); } @@ -667,7 +668,7 @@ const assertFrame = (frame: RelativeVolumeFrame, c: ChannelData[], i: string) => ByteVector.fromString("foobarbaz", StringType.Latin1), 0x00, // Identifier + delimiter cd1.render() // Channel data ); - const header = new Id3v2FrameHeader(FrameIdentifiers.RVA2, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.RVA2, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(version), fieldBytes); Testers.bvEqual(result, expected); } @@ -702,7 +703,7 @@ const assertFrame = (frame: RelativeVolumeFrame, c: ChannelData[], i: string) => cd2.render(), // Channel data cd1.render() // Channel data ); - const header = new Id3v2FrameHeader(FrameIdentifiers.RVA2, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.RVA2, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(version), fieldBytes); Testers.bvEqual(result, expected); } diff --git a/test-unit/id3v2/synchronizedLyricsFrameTests.ts b/test-unit/id3v2/synchronizedLyricsFrameTests.ts index ddcf582b..78d0a9cc 100644 --- a/test-unit/id3v2/synchronizedLyricsFrameTests.ts +++ b/test-unit/id3v2/synchronizedLyricsFrameTests.ts @@ -3,15 +3,15 @@ import {assert} from "chai"; import Frame from "../../src/id3v2/frames/frame"; import FrameConstructorTests from "./frameConstructorTests"; +import FrameHeader from "../../src/id3v2/frames/frameHeader"; import Id3v2Settings from "../../src/id3v2/id3v2Settings"; import PropertyTests from "../utilities/propertyTests"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "../../src/id3v2/frames/frameHeader"; +import {FrameFlags, SynchronizedTextType, TimestampFormat} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {SynchronizedLyricsFrame, SynchronizedText} from "../../src/id3v2/frames/synchronizedLyricsFrame"; import {Testers} from "../utilities/testers"; -import {SynchronizedTextType, TimestampFormat} from "../../src/id3v2/utilTypes"; const assertFrame = ( frame: SynchronizedLyricsFrame, @@ -66,7 +66,7 @@ const assertFrame = ( } @suite class Id3v2_SynchronizedLyricsFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: Id3v2FrameHeader, d:ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d:ByteVector, v: number) => Frame { return SynchronizedLyricsFrame.fromFieldBytes; } @@ -76,7 +76,7 @@ const assertFrame = ( public fromFieldBytes_notEnoughBytes(version: number) { // Arrange const fieldBytes = ByteVector.fromByteArray([0x00, 0x00, 0x00, 0x00, 0x00]); - const header = new Id3v2FrameHeader(FrameIdentifiers.SYLT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.SYLT, FrameFlags.None, fieldBytes.length); // Act / Assert assert.throws(() => { SynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, version); }); @@ -94,7 +94,7 @@ const assertFrame = ( SynchronizedTextType.Other, // Content type ByteVector.fromString("foobarbaz", StringType.Latin1), // Content descriptor (unterminated) ); - const header = new Id3v2FrameHeader(FrameIdentifiers.SYLT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.SYLT, FrameFlags.None, fieldBytes.length); // Act / Assert assert.throws(() => { SynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, version); }); @@ -114,7 +114,7 @@ const assertFrame = ( ByteVector.getTextDelimiter(StringType.Latin1), // Delimiter ByteVector.fromString("fux", StringType.Latin1) // Lyric (unterminated) ); - const header = new Id3v2FrameHeader(FrameIdentifiers.SYLT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.SYLT, FrameFlags.None, fieldBytes.length); // Act / Assert assert.throws(() => { SynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, version); }); @@ -138,7 +138,7 @@ const assertFrame = ( content1.render(StringType.Latin1), // Lyric 1 content2.render(StringType.Latin1).subarray(0, 5), // Lyric 2 (incomplete) ); - const header = new Id3v2FrameHeader(FrameIdentifiers.SYLT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.SYLT, FrameFlags.None, fieldBytes.length); // Act / Assert assert.throws(() => { SynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, version); }); @@ -157,7 +157,7 @@ const assertFrame = ( ByteVector.fromString("bux", StringType.UTF16BE), // Content descriptor ByteVector.getTextDelimiter(StringType.UTF16BE), // Delimiter ); - const header = new Id3v2FrameHeader(FrameIdentifiers.SYLT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.SYLT, FrameFlags.None, fieldBytes.length); // Act const frame = SynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, version); @@ -190,7 +190,7 @@ const assertFrame = ( ByteVector.getTextDelimiter(StringType.UTF16BE), // Delimiter lyric1.render(StringType.UTF16BE) // Lyric 1 ); - const header = new Id3v2FrameHeader(FrameIdentifiers.SYLT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.SYLT, FrameFlags.None, fieldBytes.length); // Act const frame = SynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, version); @@ -225,7 +225,7 @@ const assertFrame = ( lyric1.render(StringType.Latin1), // Lyric 1 lyric2.render(StringType.Latin1) // Lyric 2 ); - const header = new Id3v2FrameHeader(FrameIdentifiers.SYLT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.SYLT, FrameFlags.None, fieldBytes.length); // Act const frame = SynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, version); @@ -259,7 +259,7 @@ const assertFrame = ( lyric1.render(encoding), // Lyric 1 lyric2.render(encoding) // Lyric 2 ); - const header = new Id3v2FrameHeader(FrameIdentifiers.SYLT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.SYLT, FrameFlags.None, fieldBytes.length); // Act const frame = SynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, 4); @@ -636,7 +636,7 @@ const assertFrame = ( ByteVector.fromString("foo", StringType.Latin1), // Content descriptor ByteVector.getTextDelimiter(StringType.Latin1), // Delimiter ); - const header = new Id3v2FrameHeader(FrameIdentifiers.SYLT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.SYLT, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(version), fieldBytes); Testers.bvEqual(output, expected); } @@ -669,7 +669,7 @@ const assertFrame = ( ByteVector.fromString("foo", StringType.Latin1), // Content descriptor ByteVector.getTextDelimiter(StringType.Latin1), // Delimiter ); - const header = new Id3v2FrameHeader(FrameIdentifiers.SYLT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.SYLT, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(version), fieldBytes); Testers.bvEqual(output, expected); } @@ -704,7 +704,7 @@ const assertFrame = ( ByteVector.getTextDelimiter(StringType.Latin1), // Delimiter lyric1.render(StringType.Latin1) // Lyric 1 ); - const header = new Id3v2FrameHeader(FrameIdentifiers.SYLT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.SYLT, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(version), fieldBytes); Testers.bvEqual(output, expected); } @@ -741,7 +741,7 @@ const assertFrame = ( lyric1.render(StringType.Latin1), // Lyric 1 lyric2.render(StringType.Latin1) // Lyric 2 ); - const header = new Id3v2FrameHeader(FrameIdentifiers.SYLT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.SYLT, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(version), fieldBytes); Testers.bvEqual(output, expected); } @@ -777,7 +777,7 @@ const assertFrame = ( lyric1.render(encoding), // Lyric 1 lyric2.render(encoding) // Lyric 2 ); - const header = new Id3v2FrameHeader(FrameIdentifiers.SYLT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.SYLT, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(4), fieldBytes); Testers.bvEqual(output, expected); } diff --git a/test-unit/id3v2/tagExtendedHeaderTests.ts b/test-unit/id3v2/tagExtendedHeaderTests.ts index 856ac1f7..4eb563e4 100644 --- a/test-unit/id3v2/tagExtendedHeaderTests.ts +++ b/test-unit/id3v2/tagExtendedHeaderTests.ts @@ -1,7 +1,7 @@ import {params, suite, test} from "@testdeck/mocha"; import {assert} from "chai"; -import Id3v2ExtendedHeader from "../../src/id3v2/id3v2ExtendedHeader"; +import TagHeaderExtended from "../../src/id3v2/tagHeaderExtended"; import {ByteVector} from "../../src/byteVector"; import {Testers} from "../utilities/testers"; import TestFile from "../utilities/testFile"; @@ -11,7 +11,7 @@ import {File} from "../../src/file"; @test public fromData_falsyData() { // Act/Assert - Testers.testTruthy((v: ByteVector) => { Id3v2ExtendedHeader.fromData(v, 2); }); + Testers.testTruthy((v: ByteVector) => { TagHeaderExtended.fromData(v, 2); }); } @test @@ -20,7 +20,7 @@ import {File} from "../../src/file"; const testData = ByteVector.fromSize(4); // Act/Assert - Testers.testByte((v: number) => { Id3v2ExtendedHeader.fromData(testData, v); }); + Testers.testByte((v: number) => { TagHeaderExtended.fromData(testData, v); }); } @params(ByteVector.empty(), "empty") @@ -28,7 +28,7 @@ import {File} from "../../src/file"; @params(ByteVector.fromSize(3), "length3") public fromData_tooShortData(data: ByteVector) { // Act/Assert - assert.throws(() => Id3v2ExtendedHeader.fromData(data, 4)); + assert.throws(() => TagHeaderExtended.fromData(data, 4)); } @test @@ -37,7 +37,7 @@ import {File} from "../../src/file"; const testData = ByteVector.concatenate(0x10, 0x10, 0x10, 0x10); // Act - const output = Id3v2ExtendedHeader.fromData(testData, 3); + const output = TagHeaderExtended.fromData(testData, 3); // Assert assert.equal(output.size, 4 + 0x10101010); @@ -49,7 +49,7 @@ import {File} from "../../src/file"; const testData = ByteVector.concatenate(0x10, 0x10, 0x10, 0x10); // Act - const output = Id3v2ExtendedHeader.fromData(testData, 2); + const output = TagHeaderExtended.fromData(testData, 2); // Assert assert.equal(output.size, 0x2040810); @@ -61,7 +61,7 @@ import {File} from "../../src/file"; const testData = ByteVector.concatenate(0x10, 0x10, 0x10, 0x10); // Act - const output = Id3v2ExtendedHeader.fromData(testData, 4); + const output = TagHeaderExtended.fromData(testData, 4); // Assert assert.equal(output.size, 0x2040810); @@ -70,7 +70,7 @@ import {File} from "../../src/file"; @test public fromFile_falsyFile() { // Act/Assert - Testers.testTruthy((v: File) => { Id3v2ExtendedHeader.fromFile(v, 0, 4); }); + Testers.testTruthy((v: File) => { TagHeaderExtended.fromFile(v, 0, 4); }); } @test @@ -79,7 +79,7 @@ import {File} from "../../src/file"; const file = TestFile.mockFile(); // Act/Assert - Testers.testSafeUint((v: number) => { Id3v2ExtendedHeader.fromFile(file, v, 4); }); + Testers.testSafeUint((v: number) => { TagHeaderExtended.fromFile(file, v, 4); }); } @test @@ -88,7 +88,7 @@ import {File} from "../../src/file"; const file = TestFile.mockFile(); // Act/Assert - Testers.testByte((v: number) => { Id3v2ExtendedHeader.fromFile(file, 0, v); }); + Testers.testByte((v: number) => { TagHeaderExtended.fromFile(file, 0, v); }); } @test @@ -97,7 +97,7 @@ import {File} from "../../src/file"; const file = TestFile.getFile(ByteVector.fromSize(3)); // Act/Assert - assert.throws(() => Id3v2ExtendedHeader.fromFile(file, 0, 4)); + assert.throws(() => TagHeaderExtended.fromFile(file, 0, 4)); } @test @@ -109,7 +109,7 @@ import {File} from "../../src/file"; )); // Act - const output = Id3v2ExtendedHeader.fromFile(file, 2, 3); + const output = TagHeaderExtended.fromFile(file, 2, 3); // Assert assert.equal(output.size, 4 + 0x10101010); @@ -124,7 +124,7 @@ import {File} from "../../src/file"; )); // Act - const output = Id3v2ExtendedHeader.fromFile(file, 2, 2); + const output = TagHeaderExtended.fromFile(file, 2, 2); // Assert assert.equal(output.size, 0x2040810); @@ -139,7 +139,7 @@ import {File} from "../../src/file"; )); // Act - const output = Id3v2ExtendedHeader.fromFile(file, 2, 4); + const output = TagHeaderExtended.fromFile(file, 2, 4); // Assert assert.equal(output.size, 0x2040810); @@ -148,7 +148,7 @@ import {File} from "../../src/file"; @test public fromEmpty() { // Act - const output = Id3v2ExtendedHeader.fromEmpty(); + const output = TagHeaderExtended.fromEmpty(); // Assert assert.equal(output.size, 0); diff --git a/test-unit/id3v2/tagFooterTests.ts b/test-unit/id3v2/tagFooterTests.ts index 4e95bf16..24241b7a 100644 --- a/test-unit/id3v2/tagFooterTests.ts +++ b/test-unit/id3v2/tagFooterTests.ts @@ -2,28 +2,28 @@ import {suite, test} from "@testdeck/mocha"; import {assert} from "chai"; import TestConstants from "../testConstants"; -import Id3v2TagFooter from "../../src/id3v2/id3v2TagFooter"; +import TagFooter from "../../src/id3v2/tagFooter"; import Id3v2Settings from "../../src/id3v2/id3v2Settings"; import {ByteVector} from "../../src/byteVector"; -import {Id3v2TagHeaderFlags} from "../../src/id3v2/id3v2TagHeader"; +import {TagFlags} from "../../src/id3v2/enums"; import {Testers} from "../utilities/testers"; -const getTestFooter = (majorVersion: number, minorVersion: number, flags: Id3v2TagHeaderFlags): Id3v2TagFooter => { +const getTestFooter = (majorVersion: number, minorVersion: number, flags: TagFlags): TagFooter => { const data = ByteVector.concatenate( - Id3v2TagFooter.FILE_IDENTIFIER, + TagFooter.FILE_IDENTIFIER, majorVersion, minorVersion, flags, TestConstants.syncedUintBytes ); - return Id3v2TagFooter.fromData(data); + return TagFooter.fromData(data); }; @suite class Id3v2_TagFooter_ConstructorTests { @test public fromData_falsyData() { // Act/Assert - Testers.testTruthy((v: ByteVector) => Id3v2TagFooter.fromData(v)); + Testers.testTruthy((v: ByteVector) => TagFooter.fromData(v)); } @test @@ -32,7 +32,7 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: Id3v2T const data = ByteVector.fromSize(1); // Act/Assert - assert.throws(() => Id3v2TagFooter.fromData(data)); + assert.throws(() => TagFooter.fromData(data)); } @test @@ -41,26 +41,26 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: Id3v2T const data = ByteVector.fromSize(10); // Act/Assert - assert.throws(() => Id3v2TagFooter.fromData(data)); + assert.throws(() => TagFooter.fromData(data)); } @test public fromData_invalidFlags_version4() { // Arrange const data = ByteVector.concatenate( - Id3v2TagFooter.FILE_IDENTIFIER, + TagFooter.FILE_IDENTIFIER, 0x04, 0x00, 0x07 ); // Act/Assert - assert.throws(() => Id3v2TagFooter.fromData(data)); + assert.throws(() => TagFooter.fromData(data)); } @test public fromData_invalidTagSizeBytes() { // Arrange const testData = ByteVector.concatenate( - Id3v2TagFooter.FILE_IDENTIFIER, + TagFooter.FILE_IDENTIFIER, 0x04, 0x00, 0x00 ); const testData1 = ByteVector.concatenate(testData, 0x80, 0x00, 0x00, 0x00); @@ -69,10 +69,10 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: Id3v2T const testData4 = ByteVector.concatenate(testData, 0x00, 0x00, 0x00, 0x80); // Act/Assert - assert.throws(() => Id3v2TagFooter.fromData(testData1)); - assert.throws(() => Id3v2TagFooter.fromData(testData2)); - assert.throws(() => Id3v2TagFooter.fromData(testData3)); - assert.throws(() => Id3v2TagFooter.fromData(testData4)); + assert.throws(() => TagFooter.fromData(testData1)); + assert.throws(() => TagFooter.fromData(testData2)); + assert.throws(() => TagFooter.fromData(testData3)); + assert.throws(() => TagFooter.fromData(testData4)); } @test @@ -82,7 +82,7 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: Id3v2T const minorVersion = 0x00; const flags = 0xE0; const testData = ByteVector.concatenate( - Id3v2TagFooter.FILE_IDENTIFIER, + TagFooter.FILE_IDENTIFIER, majorVersion, minorVersion, flags, @@ -90,7 +90,7 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: Id3v2T ); // Act - const output = Id3v2TagFooter.fromData(testData); + const output = TagFooter.fromData(testData); // Assert assert.equal(output.flags, flags); @@ -104,7 +104,7 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: Id3v2T @test public getCompleteTagSize() { // Arrange - const footer = getTestFooter(4, 0, Id3v2TagHeaderFlags.None); + const footer = getTestFooter(4, 0, TagFlags.None); // Act const output = footer.completeTagSize; @@ -116,19 +116,19 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: Id3v2T @test public setFlags_validFlags() { // Arrange - const footer = getTestFooter(4, 0, Id3v2TagHeaderFlags.None); + const footer = getTestFooter(4, 0, TagFlags.None); // Act - footer.flags = Id3v2TagHeaderFlags.FooterPresent; + footer.flags = TagFlags.FooterPresent; // Assert - assert.equal(footer.flags, Id3v2TagHeaderFlags.FooterPresent); + assert.equal(footer.flags, TagFlags.FooterPresent); } @test public getMajorVersion_zero() { // Arrange - const footer = getTestFooter(0, 0, Id3v2TagHeaderFlags.None); + const footer = getTestFooter(0, 0, TagFlags.None); // Act const output = footer.majorVersion; @@ -140,7 +140,7 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: Id3v2T @test public getMajorVersion_nonZero() { // Arrange - const footer = getTestFooter(4, 0, Id3v2TagHeaderFlags.None); + const footer = getTestFooter(4, 0, TagFlags.None); // Act const output = footer.majorVersion; @@ -152,7 +152,7 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: Id3v2T @test public setMajorVersion_invalidValues() { // Arrange - const footer = getTestFooter(4, 0, Id3v2TagHeaderFlags.None); + const footer = getTestFooter(4, 0, TagFlags.None); // Act/Assert Testers.testByte((v: number) => { footer.majorVersion = v; }); @@ -163,7 +163,7 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: Id3v2T @test public setRevisionNumber_invalidValue() { // Arrange - const footer = getTestFooter(4, 0, Id3v2TagHeaderFlags.None); + const footer = getTestFooter(4, 0, TagFlags.None); // Act/Assert Testers.testByte((v: number) => { footer.revisionNumber = v; }); @@ -172,7 +172,7 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: Id3v2T @test public setRevisionNumber_validValue() { // Arrange - const footer = getTestFooter(4, 0, Id3v2TagHeaderFlags.None); + const footer = getTestFooter(4, 0, TagFlags.None); // Act footer.revisionNumber = 2; @@ -184,7 +184,7 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: Id3v2T @test public setTagSize_invalidValues() { // Arrange - const footer = getTestFooter(4, 0, Id3v2TagHeaderFlags.None); + const footer = getTestFooter(4, 0, TagFlags.None); // Act/Assert assert.throws(() => { footer.tagSize = -1; }); @@ -195,7 +195,7 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: Id3v2T @test public publicsetTagSize_validValue() { // Arrange - const footer = getTestFooter(4, 0, Id3v2TagHeaderFlags.None); + const footer = getTestFooter(4, 0, TagFlags.None); // Act footer.tagSize = 0x1234; @@ -213,13 +213,13 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: Id3v2T const minorVersion = 0x00; const flags = 0xE0; const testData = ByteVector.concatenate( - Id3v2TagFooter.FILE_IDENTIFIER, + TagFooter.FILE_IDENTIFIER, majorVersion, minorVersion, flags, TestConstants.syncedUintBytes ); - const footer = Id3v2TagFooter.fromData(testData); + const footer = TagFooter.fromData(testData); // Act const output = footer.render(); diff --git a/test-unit/id3v2/tagHeaderTests.ts b/test-unit/id3v2/tagHeaderTests.ts index cd776adf..d72150d2 100644 --- a/test-unit/id3v2/tagHeaderTests.ts +++ b/test-unit/id3v2/tagHeaderTests.ts @@ -2,28 +2,29 @@ import {suite, test} from "@testdeck/mocha"; import {assert} from "chai"; import Id3v2Settings from "../../src/id3v2/id3v2Settings"; +import TagHeader from "../../src/id3v2/tagHeader"; import TestConstants from "../testConstants"; import {ByteVector} from "../../src/byteVector"; -import {Id3v2TagHeader, Id3v2TagHeaderFlags} from "../../src/id3v2/id3v2TagHeader"; +import {TagFlags} from "../../src/id3v2/enums"; import {Testers} from "../utilities/testers"; import {NumberUtils} from "../../src/utils"; -const getTestHeader = (majorVersion: number, minorVersion: number, flags: Id3v2TagHeaderFlags): Id3v2TagHeader => { +const getTestHeader = (majorVersion: number, minorVersion: number, flags: TagFlags): TagHeader => { const data = ByteVector.concatenate( - Id3v2TagHeader.FILE_IDENTIFIER, + TagHeader.FILE_IDENTIFIER, majorVersion, minorVersion, flags, 0x10, 0x10, 0x10, 0x10 ); - return Id3v2TagHeader.fromData(data); + return TagHeader.fromData(data); }; @suite class Id3v2_TagHeader_ConstructorTests { @test public falsyData() { // Act/Assert - Testers.testTruthy((v: ByteVector) => Id3v2TagHeader.fromData(v)); + Testers.testTruthy((v: ByteVector) => TagHeader.fromData(v)); } @test @@ -33,63 +34,63 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: Id3v2T const data1 = ByteVector.fromSize(1); // Act/Assert - assert.throws(() => Id3v2TagHeader.fromData(data0)); - assert.throws(() => Id3v2TagHeader.fromData(data1)); + assert.throws(() => TagHeader.fromData(data0)); + assert.throws(() => TagHeader.fromData(data1)); } @test public invalidStartOfData() { // Act/Assert - assert.throws(() => Id3v2TagHeader.fromData(TestConstants.testByteVector)); + assert.throws(() => TagHeader.fromData(TestConstants.testByteVector)); } @test public invalidFlagsForVersion2() { // Arrange const testData = ByteVector.concatenate( - Id3v2TagHeader.FILE_IDENTIFIER, + TagHeader.FILE_IDENTIFIER, 0x02, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00 ); // Act/Assert - assert.throws(() => Id3v2TagHeader.fromData(testData)); + assert.throws(() => TagHeader.fromData(testData)); } @test public invalidFlagsForVersion3() { // Arrange const testData = ByteVector.concatenate( - Id3v2TagHeader.FILE_IDENTIFIER, + TagHeader.FILE_IDENTIFIER, 0x03, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00 ); // Act/Assert - assert.throws(() => Id3v2TagHeader.fromData(testData)); + assert.throws(() => TagHeader.fromData(testData)); } @test public invalidFlagsForVersion4() { // Arrange const testData = ByteVector.concatenate( - Id3v2TagHeader.FILE_IDENTIFIER, + TagHeader.FILE_IDENTIFIER, 0x04, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00 ); // Act/Assert - assert.throws(() => Id3v2TagHeader.fromData(testData)); + assert.throws(() => TagHeader.fromData(testData)); } @test public invalidTagSizeBytes() { // Arrange const testData = ByteVector.concatenate( - Id3v2TagHeader.FILE_IDENTIFIER, + TagHeader.FILE_IDENTIFIER, 0x04, 0x00, 0x00 ); @@ -99,10 +100,10 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: Id3v2T const testData4 = ByteVector.concatenate(testData, 0x00, 0x00, 0x00, 0x80); // Act/Assert - assert.throws(() => Id3v2TagHeader.fromData(testData1)); - assert.throws(() => Id3v2TagHeader.fromData(testData2)); - assert.throws(() => Id3v2TagHeader.fromData(testData3)); - assert.throws(() => Id3v2TagHeader.fromData(testData4)); + assert.throws(() => TagHeader.fromData(testData1)); + assert.throws(() => TagHeader.fromData(testData2)); + assert.throws(() => TagHeader.fromData(testData3)); + assert.throws(() => TagHeader.fromData(testData4)); } @test @@ -112,7 +113,7 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: Id3v2T const minorVersion = 0x00; const flags = 0xE0; const testData = ByteVector.concatenate( - Id3v2TagHeader.FILE_IDENTIFIER, + TagHeader.FILE_IDENTIFIER, majorVersion, minorVersion, flags, @@ -120,7 +121,7 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: Id3v2T ); // Act - const output = Id3v2TagHeader.fromData(testData); + const output = TagHeader.fromData(testData); // Assert assert.equal(output.flags, flags); @@ -134,7 +135,7 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: Id3v2T @test public getFileIdentifier() { // Act - const output = Id3v2TagHeader.FILE_IDENTIFIER; + const output = TagHeader.FILE_IDENTIFIER; // Assert assert.ok(output); @@ -143,7 +144,7 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: Id3v2T @test public getCompleteTagSize_withFooter() { // Arrange - const header = getTestHeader(4, 0, Id3v2TagHeaderFlags.FooterPresent); + const header = getTestHeader(4, 0, TagFlags.FooterPresent); // Act const totalSize = header.completeTagSize; @@ -155,7 +156,7 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: Id3v2T @test public getCompleteTagSize_noFooter() { // Arrange - const header = getTestHeader(4, 0, Id3v2TagHeaderFlags.None); + const header = getTestHeader(4, 0, TagFlags.None); // Act const totalSize = header.completeTagSize; @@ -167,49 +168,49 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: Id3v2T @test public setFlags_version2InvalidFlags() { // Arrange - const header = getTestHeader(2, 0, Id3v2TagHeaderFlags.None); + const header = getTestHeader(2, 0, TagFlags.None); // Act - const set1 = () => { header.flags = Id3v2TagHeaderFlags.ExtendedHeader; }; - const set2 = () => { header.flags = Id3v2TagHeaderFlags.ExperimentalIndicator; }; - const set3 = () => { header.flags = Id3v2TagHeaderFlags.FooterPresent; }; + const set1 = () => { header.flags = TagFlags.ExtendedHeader; }; + const set2 = () => { header.flags = TagFlags.ExperimentalIndicator; }; + const set3 = () => { header.flags = TagFlags.FooterPresent; }; // Assert assert.throws(set1); assert.throws(set2); assert.throws(set3); - assert.equal(header.flags, Id3v2TagHeaderFlags.None); + assert.equal(header.flags, TagFlags.None); } @test public setFlags_version3InvalidFlags() { // Arrange - const header = getTestHeader(3, 0, Id3v2TagHeaderFlags.None); + const header = getTestHeader(3, 0, TagFlags.None); // Act - const set = () => { header.flags = Id3v2TagHeaderFlags.FooterPresent; }; + const set = () => { header.flags = TagFlags.FooterPresent; }; // Assert assert.throws(set); - assert.equal(header.flags, Id3v2TagHeaderFlags.None); + assert.equal(header.flags, TagFlags.None); } @test public setFlags_validFlags() { // Arrange - const header = getTestHeader(4, 0, Id3v2TagHeaderFlags.None); + const header = getTestHeader(4, 0, TagFlags.None); // Act - header.flags = Id3v2TagHeaderFlags.FooterPresent; + header.flags = TagFlags.FooterPresent; // Assert - assert.equal(header.flags, Id3v2TagHeaderFlags.FooterPresent); + assert.equal(header.flags, TagFlags.FooterPresent); } @test public getMajorVersion_zero() { // Arrange - const header = getTestHeader(0, 0, Id3v2TagHeaderFlags.None); + const header = getTestHeader(0, 0, TagFlags.None); // Act const output = header.majorVersion; @@ -221,7 +222,7 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: Id3v2T @test public getMajorVersion_nonZero() { // Arrange - const header = getTestHeader(4, 0, Id3v2TagHeaderFlags.None); + const header = getTestHeader(4, 0, TagFlags.None); // Act const output = header.majorVersion; @@ -233,7 +234,7 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: Id3v2T @test public getMajorVersion_forcedDefault() { // Arrange - const header = getTestHeader(4, 0, Id3v2TagHeaderFlags.None); + const header = getTestHeader(4, 0, TagFlags.None); const initialForceValue = Id3v2Settings.forceDefaultVersion; try { @@ -253,7 +254,7 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: Id3v2T @test public setMajorVersion_invalidValues() { // Arrange - const header = getTestHeader(4, 0, Id3v2TagHeaderFlags.None); + const header = getTestHeader(4, 0, TagFlags.None); // Act/Assert Testers.testByte((v: number) => { header.majorVersion = v; }); @@ -264,9 +265,9 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: Id3v2T @test public setMajorVersion_2_unsets3And4Flags() { // Arrange - const flags = Id3v2TagHeaderFlags.ExtendedHeader | - Id3v2TagHeaderFlags.ExperimentalIndicator | - Id3v2TagHeaderFlags.FooterPresent; + const flags = TagFlags.ExtendedHeader | + TagFlags.ExperimentalIndicator | + TagFlags.FooterPresent; const header = getTestHeader(4, 0, flags); // Act @@ -280,7 +281,7 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: Id3v2T @test public setMajorVersion3_unsets4Flags() { // Arrange - const flags = Id3v2TagHeaderFlags.FooterPresent; + const flags = TagFlags.FooterPresent; const header = getTestHeader(4, 0, flags); // Act @@ -294,7 +295,7 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: Id3v2T @test public setRevisionNumber_invalidValue() { // Arrange - const header = getTestHeader(4, 0, Id3v2TagHeaderFlags.None); + const header = getTestHeader(4, 0, TagFlags.None); // Act/Assert Testers.testByte((v: number) => { header.revisionNumber = v; }); @@ -303,7 +304,7 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: Id3v2T @test public setRevisionNumber_validValue() { // Arrange - const header = getTestHeader(4, 0, Id3v2TagHeaderFlags.None); + const header = getTestHeader(4, 0, TagFlags.None); // Act header.revisionNumber = 2; @@ -315,7 +316,7 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: Id3v2T @test public setTagSize_invalidValues() { // Arrange - const header = getTestHeader(4, 0, Id3v2TagHeaderFlags.None); + const header = getTestHeader(4, 0, TagFlags.None); // Act/Assert Testers.testUint((v: number) => { header.tagSize = v; }); @@ -325,7 +326,7 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: Id3v2T @test public setTagSize_validValue() { // Arrange - const header = getTestHeader(4, 0, Id3v2TagHeaderFlags.None); + const header = getTestHeader(4, 0, TagFlags.None); // Act header.tagSize = 0x1234; @@ -343,13 +344,13 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: Id3v2T const minorVersion = 0x00; const flags = 0xE0; const testData = ByteVector.concatenate( - Id3v2TagHeader.FILE_IDENTIFIER, + TagHeader.FILE_IDENTIFIER, majorVersion, minorVersion, flags, 0x10, 0x10, 0x10, 0x10 ); - const header = Id3v2TagHeader.fromData(testData); + const header = TagHeader.fromData(testData); // Act const output = header.render(); diff --git a/test-unit/id3v2/termsOfUseFrameTests.ts b/test-unit/id3v2/termsOfUseFrameTests.ts index 6f989254..acd83961 100644 --- a/test-unit/id3v2/termsOfUseFrameTests.ts +++ b/test-unit/id3v2/termsOfUseFrameTests.ts @@ -3,12 +3,13 @@ import {assert} from "chai"; import Frame from "../../src/id3v2/frames/frame"; import FrameConstructorTests from "./frameConstructorTests"; +import FrameHeader from "../../src/id3v2/frames/frameHeader"; import Id3v2Settings from "../../src/id3v2/id3v2Settings"; import PropertyTests from "../utilities/propertyTests"; import TermsOfUseFrame from "../../src/id3v2/frames/termsOfUseFrame"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "../../src/id3v2/frames/frameHeader"; +import {FrameFlags} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -23,7 +24,7 @@ const assertFrame = (frame: TermsOfUseFrame, language: string, text: string, tex } @suite class Id3v2_TermsOfUseFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: Id3v2FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { return TermsOfUseFrame.fromFieldBytes; } @@ -33,7 +34,7 @@ const assertFrame = (frame: TermsOfUseFrame, language: string, text: string, tex public fromFieldBytes_notEnoughBytes(version: number) { // Arrange const fieldBytes = ByteVector.concatenate(0x00, 0x00); - const header = new Id3v2FrameHeader(FrameIdentifiers.USER, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.USER, FrameFlags.None, fieldBytes.length); // Act / Assert assert.throws(() => { TermsOfUseFrame.fromFieldBytes(header, fieldBytes, version); }); @@ -48,7 +49,7 @@ const assertFrame = (frame: TermsOfUseFrame, language: string, text: string, tex StringType.Latin1, // Encoding ByteVector.fromString("eng", StringType.Latin1) // Language ); - const header = new Id3v2FrameHeader(FrameIdentifiers.USER, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.USER, FrameFlags.None, fieldBytes.length); // Act const frame = TermsOfUseFrame.fromFieldBytes(header, fieldBytes, version); @@ -67,7 +68,7 @@ const assertFrame = (frame: TermsOfUseFrame, language: string, text: string, tex ByteVector.fromString("eng", StringType.Latin1), // Language ByteVector.fromString("foobarbaz", StringType.Latin1) // Text ); - const header = new Id3v2FrameHeader(FrameIdentifiers.USER, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.USER, FrameFlags.None, fieldBytes.length); // Act const frame = TermsOfUseFrame.fromFieldBytes(header, fieldBytes, version); @@ -85,7 +86,7 @@ const assertFrame = (frame: TermsOfUseFrame, language: string, text: string, tex ByteVector.fromString("eng", StringType.Latin1), // Language ByteVector.fromString("foobarbaz", encoding) // Text ); - const header = new Id3v2FrameHeader(FrameIdentifiers.USER, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.USER, FrameFlags.None, fieldBytes.length); // Act const frame = TermsOfUseFrame.fromFieldBytes(header, fieldBytes, 4); @@ -288,7 +289,7 @@ const assertFrame = (frame: TermsOfUseFrame, language: string, text: string, tex StringType.Latin1, // Encoding ByteVector.fromString("foo", StringType.Latin1), // Language ); - const header = new Id3v2FrameHeader(FrameIdentifiers.USER, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.USER, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(4), fieldBytes); Testers.bvEqual(result, expected); } @@ -308,7 +309,7 @@ const assertFrame = (frame: TermsOfUseFrame, language: string, text: string, tex ByteVector.fromString("foo", StringType.Latin1), // Language ByteVector.fromString("bar", StringType.Latin1) // Text ); - const header = new Id3v2FrameHeader(FrameIdentifiers.USER, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.USER, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(version), fieldBytes); Testers.bvEqual(result, expected); } @@ -328,7 +329,7 @@ const assertFrame = (frame: TermsOfUseFrame, language: string, text: string, tex ByteVector.fromString("foo", StringType.Latin1), // Language ByteVector.fromString("bar", encoding) // Text ); - const header = new Id3v2FrameHeader(FrameIdentifiers.USER, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.USER, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(4), fieldBytes); Testers.bvEqual(result, expected); } diff --git a/test-unit/id3v2/textInformationFrameTests.ts b/test-unit/id3v2/textInformationFrameTests.ts index 9da722c6..2765716b 100644 --- a/test-unit/id3v2/textInformationFrameTests.ts +++ b/test-unit/id3v2/textInformationFrameTests.ts @@ -3,12 +3,13 @@ import {assert} from "chai"; import Frame from "../../src/id3v2/frames/frame"; import FrameConstructorTests from "./frameConstructorTests"; +import FrameHeader from "../../src/id3v2/frames/frameHeader"; import Id3v2Settings from "../../src/id3v2/id3v2Settings"; import PropertyTests from "../utilities/propertyTests"; import TextInformationFrame from "../../src/id3v2/frames/textInformationFrame"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "../../src/id3v2/frames/frameHeader"; +import {FrameFlags} from "../../src/id3v2/enums"; import {FrameIdentifier, FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -23,7 +24,7 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text } @suite class Id3v2_TextInformationFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: Id3v2FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { return TextInformationFrame.fromFieldBytes; } @@ -33,7 +34,7 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text public fromFieldBytes_empty_throws(version: number) { // Arrange const fieldBytes = ByteVector.empty(); - const header = new Id3v2FrameHeader(FrameIdentifiers.TCOP, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.TCOP, FrameFlags.None, fieldBytes.length); // Act / Assert assert.throws(() => TextInformationFrame.fromFieldBytes(header, fieldBytes, version)); @@ -45,7 +46,7 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text public fromFieldBytes_noText_returnsEmptyFrame(version: number) { // Arrange const fieldBytes = ByteVector.fromByte(StringType.UTF16BE); - const header = new Id3v2FrameHeader(FrameIdentifiers.TCOP, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.TCOP, FrameFlags.None, fieldBytes.length); // Act const frame = TextInformationFrame.fromFieldBytes(header, fieldBytes, version); @@ -63,7 +64,7 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text StringType.UTF16BE, // Encoding 0x00, 0x00, 0x00 // Text ); - const header = new Id3v2FrameHeader(FrameIdentifiers.TCOP, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.TCOP, FrameFlags.None, fieldBytes.length); // Act const frame = TextInformationFrame.fromFieldBytes(header, fieldBytes, version); @@ -80,7 +81,7 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text StringType.Latin1, // Encoding ByteVector.fromString("fux/bux", StringType.Latin1) // Text ); - const header = new Id3v2FrameHeader(FrameIdentifiers.TALB, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.TALB, FrameFlags.None, fieldBytes.length); // Act const frame = TextInformationFrame.fromFieldBytes(header, fieldBytes, version); @@ -97,7 +98,7 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text StringType.Latin1, // Encoding ByteVector.fromString("fux/bux", StringType.Latin1) // Text ); - const header = new Id3v2FrameHeader(FrameIdentifiers.TCOM, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.TCOM, FrameFlags.None, fieldBytes.length); // Act const frame = TextInformationFrame.fromFieldBytes(header, fieldBytes, version); @@ -116,7 +117,7 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text 0x00, // ... ByteVector.fromString("bar", StringType.Latin1) // ... ); - const header = new Id3v2FrameHeader(FrameIdentifiers.TCOM, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.TCOM, FrameFlags.None, fieldBytes.length); // Act const frame = TextInformationFrame.fromFieldBytes(header, fieldBytes, version); @@ -135,7 +136,7 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text ByteVector.getTextDelimiter(encoding), // ... ByteVector.fromString("bux", encoding), // ... ); - const header = new Id3v2FrameHeader(FrameIdentifiers.TCOP, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.TCOP, FrameFlags.None, fieldBytes.length); // Act const frame = TextInformationFrame.fromFieldBytes(header, fieldBytes, 4); @@ -425,7 +426,7 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text ByteVector.getTextDelimiter(encoding), // ... ByteVector.fromString("baz", encoding) // ... ); - const header = new Id3v2FrameHeader(FrameIdentifiers.TALB, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.TALB, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(4), fieldBytes); Testers.bvEqual(result, expected); } @@ -448,7 +449,7 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text encoding, // Encoding ByteVector.fromString("fux/bux", encoding) // Text ); - const header = new Id3v2FrameHeader(FrameIdentifiers.TCOP, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.TCOP, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(version), fieldBytes); Testers.bvEqual(output, expected); } @@ -471,7 +472,7 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text encoding, // Encoding ByteVector.fromString("fux", encoding) // Text ); - const header = new Id3v2FrameHeader(FrameIdentifiers.TCOP, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.TCOP, FrameFlags.None, fieldBytes.length); const expected = ByteVector.concatenate(header.render(version), fieldBytes); Testers.bvEqual(output, expected); } diff --git a/test-unit/id3v2/uniqueFileIdentifierFrameTests.ts b/test-unit/id3v2/uniqueFileIdentifierFrameTests.ts index 5696b4b2..2e8b2f3a 100644 --- a/test-unit/id3v2/uniqueFileIdentifierFrameTests.ts +++ b/test-unit/id3v2/uniqueFileIdentifierFrameTests.ts @@ -3,11 +3,12 @@ import {assert} from "chai"; import Frame from "../../src/id3v2/frames/frame"; import FrameConstructorTests from "./frameConstructorTests"; +import FrameHeader from "../../src/id3v2/frames/frameHeader"; import PropertyTests from "../utilities/propertyTests"; import UniqueFileIdentifierFrame from "../../src/id3v2/frames/uniqueFileIdentifierFrame"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "../../src/id3v2/frames/frameHeader"; +import {FrameFlags} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -25,7 +26,7 @@ const assertFrame = (frame: UniqueFileIdentifierFrame, o: string, i: ByteVector) } @suite class Id3v2_UniqueFileIdentifierFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: Id3v2FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { return UniqueFileIdentifierFrame.fromFieldBytes; } @@ -35,7 +36,7 @@ const assertFrame = (frame: UniqueFileIdentifierFrame, o: string, i: ByteVector) public fromFieldBytes_empty_throws(version: number) { // Arrange const fieldBytes = ByteVector.empty(); - const header = new Id3v2FrameHeader(FrameIdentifiers.UFID, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.UFID, FrameFlags.None, fieldBytes.length); // Act / Assert assert.throws(() => UniqueFileIdentifierFrame.fromFieldBytes(header, fieldBytes, version)); @@ -47,7 +48,7 @@ const assertFrame = (frame: UniqueFileIdentifierFrame, o: string, i: ByteVector) public fromFieldBytes_oneField_throws(version: number) { // Arrange const fieldBytes = testIdentifier; - const header = new Id3v2FrameHeader(FrameIdentifiers.UFID, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.UFID, FrameFlags.None, fieldBytes.length); // Act / Assert assert.throws(() => UniqueFileIdentifierFrame.fromFieldBytes(header, fieldBytes, version)); @@ -63,7 +64,7 @@ const assertFrame = (frame: UniqueFileIdentifierFrame, o: string, i: ByteVector) ByteVector.getTextDelimiter(StringType.Latin1), // Delimiter testIdentifier, 0x00, testIdentifier // Identifier ); - const header = new Id3v2FrameHeader(FrameIdentifiers.UFID, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.UFID, FrameFlags.None, fieldBytes.length); // Act const frame = UniqueFileIdentifierFrame.fromFieldBytes(header, fieldBytes, version); @@ -83,7 +84,7 @@ const assertFrame = (frame: UniqueFileIdentifierFrame, o: string, i: ByteVector) ByteVector.getTextDelimiter(StringType.Latin1), // Delimiter testIdentifier // Identifier ); - const header = new Id3v2FrameHeader(FrameIdentifiers.UFID, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.UFID, FrameFlags.None, fieldBytes.length); // Act @@ -275,7 +276,7 @@ const assertFrame = (frame: UniqueFileIdentifierFrame, o: string, i: ByteVector) 0x00, // Delimiter testIdentifier // Identifier ); - const header = new Id3v2FrameHeader(FrameIdentifiers.UFID, Id3v2FrameFlags.None, fieldData.length); + const header = new FrameHeader(FrameIdentifiers.UFID, FrameFlags.None, fieldData.length); const expected = ByteVector.concatenate(header.render(version), fieldData); Testers.bvEqual(result, expected); } diff --git a/test-unit/id3v2/unknownFrameTests.ts b/test-unit/id3v2/unknownFrameTests.ts index 60596f75..c359fee4 100644 --- a/test-unit/id3v2/unknownFrameTests.ts +++ b/test-unit/id3v2/unknownFrameTests.ts @@ -4,9 +4,10 @@ import {assert} from "chai"; import CommentsFrame from "../../src/id3v2/frames/commentsFrame"; import Frame from "../../src/id3v2/frames/frame"; import FrameConstructorTests from "./frameConstructorTests"; +import FrameHeader from "../../src/id3v2/frames/frameHeader"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "../../src/id3v2/frames/frameHeader"; +import {FrameFlags} from "../../src/id3v2/enums"; import {FrameIdentifier, FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -23,7 +24,7 @@ const assertFrame = (frame: UnknownFrame, fi: FrameIdentifier, d: ByteVector) => } @suite class Id3v2_UnknownFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: Id3v2FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { return UnknownFrame.fromFieldBytes; } @@ -33,7 +34,7 @@ const assertFrame = (frame: UnknownFrame, fi: FrameIdentifier, d: ByteVector) => public fromFieldBytes_validParams_returnsFrame(version: number) { // Arrange const fieldBytes = ByteVector.fromString("foo bar baz", StringType.UTF8); - const header = new Id3v2FrameHeader(FrameIdentifiers.WXXX, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.WXXX, FrameFlags.None, fieldBytes.length); // Act const frame = UnknownFrame.fromFieldBytes(header, fieldBytes, version); @@ -81,7 +82,7 @@ const assertFrame = (frame: UnknownFrame, fi: FrameIdentifier, d: ByteVector) => public clone_returnsCopy(version: number) { // Arrange const fieldBytes = ByteVector.fromString("foo bar baz", StringType.UTF8); - const header = new Id3v2FrameHeader(FrameIdentifiers.WXXX, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.WXXX, FrameFlags.None, fieldBytes.length); const frame = UnknownFrame.fromFieldBytes(header, fieldBytes, version); // Act @@ -178,7 +179,7 @@ const assertFrame = (frame: UnknownFrame, fi: FrameIdentifier, d: ByteVector) => public render_returnsByteVector(version: number) { // Arrange const fieldBytes = ByteVector.fromString("foo bar baz", StringType.UTF8); - const header = new Id3v2FrameHeader(FrameIdentifiers.WXXX, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.WXXX, FrameFlags.None, fieldBytes.length); const frame = UnknownFrame.fromFieldBytes(header, fieldBytes, version); // Act diff --git a/test-unit/id3v2/unsynchronizedLyricsFrameTests.ts b/test-unit/id3v2/unsynchronizedLyricsFrameTests.ts index aaeddd76..eb023600 100644 --- a/test-unit/id3v2/unsynchronizedLyricsFrameTests.ts +++ b/test-unit/id3v2/unsynchronizedLyricsFrameTests.ts @@ -3,12 +3,13 @@ import {assert} from "chai"; import Frame from "../../src/id3v2/frames/frame"; import FrameConstructorTests from "./frameConstructorTests"; +import FrameHeader from "../../src/id3v2/frames/frameHeader"; import Id3v2Settings from "../../src/id3v2/id3v2Settings"; import PropertyTests from "../utilities/propertyTests"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import UnsynchronizedLyricsFrame from "../../src/id3v2/frames/unsynchronizedLyricsFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "../../src/id3v2/frames/frameHeader"; +import {FrameFlags} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -24,7 +25,7 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: } @suite class Id3v2_UnsynchronizedLyricsFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: Id3v2FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { return UnsynchronizedLyricsFrame.fromFieldBytes; } @@ -34,7 +35,7 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: public fromFieldBytes_tooFewBytes_throws(version: number) { // Arrange const fieldBytes = ByteVector.fromByte(StringType.Latin1); - const header = new Id3v2FrameHeader(FrameIdentifiers.USLT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.USLT, FrameFlags.None, fieldBytes.length); // Act/Assert assert.throws(() => { UnsynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, version); }); @@ -49,7 +50,7 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: StringType.Latin1, // Encoding ByteVector.fromString("eng", StringType.Latin1), // Language ); - const header = new Id3v2FrameHeader(FrameIdentifiers.USLT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.USLT, FrameFlags.None, fieldBytes.length); // Act const frame = UnsynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, version); @@ -68,7 +69,7 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: ByteVector.fromString("eng", StringType.Latin1), // Language ByteVector.fromString("foobarbaz", StringType.Latin1) // Description -> will become lyrics ); - const header = new Id3v2FrameHeader(FrameIdentifiers.USLT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.USLT, FrameFlags.None, fieldBytes.length); // Act const frame = UnsynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, version); @@ -88,7 +89,7 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: ByteVector.getTextDelimiter(StringType.Latin1), // Separator ByteVector.fromString("foobarbaz", StringType.Latin1) // Lyrics ); - const header = new Id3v2FrameHeader(FrameIdentifiers.USLT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.USLT, FrameFlags.None, fieldBytes.length); // Act const frame = UnsynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, version); @@ -109,7 +110,7 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: ByteVector.getTextDelimiter(StringType.Latin1), // Delimiter ByteVector.fromString("bar", StringType.Latin1) // Lyrics ); - const header = new Id3v2FrameHeader(FrameIdentifiers.USLT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.USLT, FrameFlags.None, fieldBytes.length); // Act const frame = UnsynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, version); @@ -129,7 +130,7 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: ByteVector.getTextDelimiter(encoding), // Delimiter ByteVector.fromString("bar", encoding) // Lyrics ); - const header = new Id3v2FrameHeader(FrameIdentifiers.USLT, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.USLT, FrameFlags.None, fieldBytes.length); // Act const frame = UnsynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, 4); @@ -357,7 +358,7 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: ByteVector.getTextDelimiter(encoding), // Delimiter ByteVector.fromString("bar", encoding) // Lyrics ); - const header = new Id3v2FrameHeader(FrameIdentifiers.USLT, Id3v2FrameFlags.None, expectedFieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.USLT, FrameFlags.None, expectedFieldBytes.length); const expectedBytes = ByteVector.concatenate(header.render(version), expectedFieldBytes); Testers.bvEqual(output, expectedBytes); } @@ -382,7 +383,7 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: ByteVector.getTextDelimiter(outputEncoding), // Delimiter ByteVector.fromString("bar", outputEncoding) // Lyrics ); - const header = new Id3v2FrameHeader(FrameIdentifiers.USLT, Id3v2FrameFlags.None, expectedFieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.USLT, FrameFlags.None, expectedFieldBytes.length); const expectedBytes = ByteVector.concatenate(header.render(version), expectedFieldBytes); Testers.bvEqual(output, expectedBytes); } @@ -404,7 +405,7 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: ByteVector.fromString("foo", StringType.Latin1), // Description ByteVector.getTextDelimiter(StringType.Latin1), // Delimiter ); - const header = new Id3v2FrameHeader(FrameIdentifiers.USLT, Id3v2FrameFlags.None, expectedFieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.USLT, FrameFlags.None, expectedFieldBytes.length); const expectedBytes = ByteVector.concatenate(header.render(4), expectedFieldBytes); Testers.bvEqual(result, expectedBytes); } @@ -426,7 +427,7 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: ByteVector.getTextDelimiter(StringType.Latin1), // Delimiter ByteVector.fromString("foo", StringType.Latin1), // Lyrics ); - const header = new Id3v2FrameHeader(FrameIdentifiers.USLT, Id3v2FrameFlags.None, expectedFieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.USLT, FrameFlags.None, expectedFieldBytes.length); const expectedBytes = ByteVector.concatenate(header.render(4), expectedFieldBytes); Testers.bvEqual(result, expectedBytes); } diff --git a/test-unit/id3v2/urlLinkFrameTests.ts b/test-unit/id3v2/urlLinkFrameTests.ts index 9a18a100..2a0617dd 100644 --- a/test-unit/id3v2/urlLinkFrameTests.ts +++ b/test-unit/id3v2/urlLinkFrameTests.ts @@ -3,10 +3,11 @@ import {assert} from "chai"; import Frame from "../../src/id3v2/frames/frame"; import FrameConstructorTests from "./frameConstructorTests"; +import FrameHeader from "../../src/id3v2/frames/frameHeader"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import UrlLinkFrame from "../../src/id3v2/frames/urlLinkFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "../../src/id3v2/frames/frameHeader"; +import {FrameFlags} from "../../src/id3v2/enums"; import {FrameIdentifier, FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -18,7 +19,7 @@ const assertFrame = (frame: UrlLinkFrame, identifier: FrameIdentifier, text: str } @suite class Id3v2_UrlLinkFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: Id3v2FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { return UrlLinkFrame.fromFieldBytes; } @@ -28,7 +29,7 @@ const assertFrame = (frame: UrlLinkFrame, identifier: FrameIdentifier, text: str public fromFieldBytes_itsGood(version: number) { // Arrange const fieldBytes = ByteVector.fromString("foo", StringType.Latin1); - const header = new Id3v2FrameHeader(FrameIdentifiers.WCOM, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.WCOM, FrameFlags.None, fieldBytes.length); // Act const output = UrlLinkFrame.fromFieldBytes(header, fieldBytes, version); @@ -46,7 +47,7 @@ const assertFrame = (frame: UrlLinkFrame, identifier: FrameIdentifier, text: str ByteVector.fromString("foo", StringType.Latin1), 0x00, 0x00 ); - const header = new Id3v2FrameHeader(FrameIdentifiers.WCOM, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.WCOM, FrameFlags.None, fieldBytes.length); // Act const output = UrlLinkFrame.fromFieldBytes(header, fieldBytes, version); @@ -66,7 +67,7 @@ const assertFrame = (frame: UrlLinkFrame, identifier: FrameIdentifier, text: str ByteVector.fromString("bar", StringType.Latin1), 0x00, 0x00 ); - const header = new Id3v2FrameHeader(FrameIdentifiers.WCOM, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.WCOM, FrameFlags.None, fieldBytes.length); // Act const output = UrlLinkFrame.fromFieldBytes(header, fieldBytes, version); @@ -313,7 +314,7 @@ const assertFrame = (frame: UrlLinkFrame, identifier: FrameIdentifier, text: str const expectedBytes = ByteVector.concatenate( FrameIdentifiers.WCOM.render(4), ByteVector.fromUint(3), - ByteVector.fromUshort(Id3v2FrameFlags.None), + ByteVector.fromUshort(FrameFlags.None), ByteVector.fromString("foo", StringType.Latin1) ); Testers.bvEqual(result, expectedBytes); diff --git a/test-unit/id3v2/userTextInformationFrameTests.ts b/test-unit/id3v2/userTextInformationFrameTests.ts index 3065d217..4a4602d3 100644 --- a/test-unit/id3v2/userTextInformationFrameTests.ts +++ b/test-unit/id3v2/userTextInformationFrameTests.ts @@ -3,11 +3,12 @@ import {assert} from "chai"; import Frame from "../../src/id3v2/frames/frame"; import FrameConstructorTests from "./frameConstructorTests"; +import FrameHeader from "../../src/id3v2/frames/frameHeader"; import Id3v2Settings from "../../src/id3v2/id3v2Settings"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import UserTextInformationFrame from "../../src/id3v2/frames/userTextInformationFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "../../src/id3v2/frames/frameHeader"; +import {FrameFlags} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -28,7 +29,7 @@ const assertFrame = ( } @suite class Id3v2_UserInformationFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: Id3v2FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { return UserTextInformationFrame.fromFieldBytes; } @@ -38,7 +39,7 @@ const assertFrame = ( public fromFieldBytes_emptyFrame_throw(version: number) { // Arrange const fieldBytes = ByteVector.empty(); - const header = new Id3v2FrameHeader(FrameIdentifiers.TXXX, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.TXXX, FrameFlags.None, fieldBytes.length); // Act / Assert assert.throws(() => UserTextInformationFrame.fromFieldBytes(header, fieldBytes, version)); @@ -50,7 +51,7 @@ const assertFrame = ( public fromFieldBytes_encodingOnly(version: number) { // Arrange const fieldBytes = ByteVector.fromByte(StringType.UTF16LE); - const header = new Id3v2FrameHeader(FrameIdentifiers.TXXX, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.TXXX, FrameFlags.None, fieldBytes.length); // Act const frame = UserTextInformationFrame.fromFieldBytes(header, fieldBytes, version); @@ -68,7 +69,7 @@ const assertFrame = ( StringType.UTF16BE, ByteVector.fromString("foo", StringType.UTF16BE) ); - const header = new Id3v2FrameHeader(FrameIdentifiers.TXXX, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.TXXX, FrameFlags.None, fieldBytes.length); // Act const output = UserTextInformationFrame.fromFieldBytes(header, fieldBytes, version); @@ -90,7 +91,7 @@ const assertFrame = ( ByteVector.getTextDelimiter(StringType.UTF16BE), ByteVector.fromString("baz", StringType.UTF16BE), ); - const header = new Id3v2FrameHeader(FrameIdentifiers.TXXX, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.TXXX, FrameFlags.None, fieldBytes.length); // Act const output = UserTextInformationFrame.fromFieldBytes(header, fieldBytes, version); @@ -110,7 +111,7 @@ const assertFrame = ( ByteVector.getTextDelimiter(StringType.Latin1), ByteVector.fromString("bar", StringType.UTF8) ); - const header = new Id3v2FrameHeader(FrameIdentifiers.TXXX, Id3v2FrameFlags.None, fieldData.length); + const header = new FrameHeader(FrameIdentifiers.TXXX, FrameFlags.None, fieldData.length); // Act const frame = UserTextInformationFrame.fromFieldBytes(header, fieldData, version); @@ -129,7 +130,7 @@ const assertFrame = ( ByteVector.getTextDelimiter(encoding), ByteVector.fromString("bar", encoding) ); - const header = new Id3v2FrameHeader(FrameIdentifiers.TXXX, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.TXXX, FrameFlags.None, fieldBytes.length); // Act const output = UserTextInformationFrame.fromFieldBytes(header, fieldBytes, 4); @@ -329,7 +330,7 @@ const assertFrame = ( const expected = ByteVector.concatenate( FrameIdentifiers.TXXX.render(4), ByteVector.fromUint(12), - ByteVector.fromUshort(Id3v2FrameFlags.None), + ByteVector.fromUshort(FrameFlags.None), StringType.Latin1, ByteVector.fromString("foo", StringType.Latin1), ByteVector.getTextDelimiter(StringType.Latin1), @@ -367,7 +368,7 @@ const assertFrame = ( const expected = ByteVector.concatenate( FrameIdentifiers.TXXX.render(4), ByteVector.fromUint(5), - ByteVector.fromUshort(Id3v2FrameFlags.None), + ByteVector.fromUshort(FrameFlags.None), StringType.Latin1, ByteVector.getTextDelimiter(StringType.Latin1), ByteVector.fromString("foo", StringType.Latin1) @@ -389,7 +390,7 @@ const assertFrame = ( const expected = ByteVector.concatenate( FrameIdentifiers.TXXX.render(4), ByteVector.fromUint(5), - ByteVector.fromUshort(Id3v2FrameFlags.None), + ByteVector.fromUshort(FrameFlags.None), StringType.Latin1, ByteVector.fromString("foo", StringType.Latin1), ByteVector.getTextDelimiter(StringType.Latin1) @@ -412,7 +413,7 @@ const assertFrame = ( const expected = ByteVector.concatenate( FrameIdentifiers.TXXX.render(4), ByteVector.fromUint(15), - ByteVector.fromUshort(Id3v2FrameFlags.None), + ByteVector.fromUshort(FrameFlags.None), StringType.UTF16LE, ByteVector.fromString("foo", StringType.UTF16LE), ByteVector.getTextDelimiter(StringType.UTF16LE), diff --git a/test-unit/id3v2/userUrlLinkFrameTests.ts b/test-unit/id3v2/userUrlLinkFrameTests.ts index 22398d8a..83f878b5 100644 --- a/test-unit/id3v2/userUrlLinkFrameTests.ts +++ b/test-unit/id3v2/userUrlLinkFrameTests.ts @@ -3,11 +3,12 @@ import {assert} from "chai"; import Frame from "../../src/id3v2/frames/frame"; import FrameConstructorTests from "./frameConstructorTests"; +import FrameHeader from "../../src/id3v2/frames/frameHeader"; import Id3v2Settings from "../../src/id3v2/id3v2Settings"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import UserUrlLinkFrame from "../../src/id3v2/frames/userUrlLinkFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {Id3v2FrameFlags, Id3v2FrameHeader} from "../../src/id3v2/frames/frameHeader"; +import {FrameFlags} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -22,7 +23,7 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, } @suite class Id3v2_UserUrlLinkFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: Id3v2FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { return UserUrlLinkFrame.fromFieldBytes; } @@ -45,7 +46,7 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, public fromFieldBytes_tooSmall(version: number) { // Arrange const fieldBytes = ByteVector.fromSize(1); - const header = new Id3v2FrameHeader(FrameIdentifiers.WXXX, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.WXXX, FrameFlags.None, fieldBytes.length); // Act / Assert assert.throws(() => UserUrlLinkFrame.fromFieldBytes(header, fieldBytes, version)); @@ -60,7 +61,7 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, StringType.Latin1, ByteVector.fromString("foo/bar", StringType.Latin1) ); - const header = new Id3v2FrameHeader(FrameIdentifiers.WXXX, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.WXXX, FrameFlags.None, fieldBytes.length); // Act const output = UserUrlLinkFrame.fromFieldBytes(header, fieldBytes, version); @@ -78,7 +79,7 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, StringType.UTF16BE, ByteVector.fromString("foo", StringType.UTF16BE) ); - const header = new Id3v2FrameHeader(FrameIdentifiers.WXXX, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.WXXX, FrameFlags.None, fieldBytes.length); // Act const output = UserUrlLinkFrame.fromFieldBytes(header, fieldBytes, version); @@ -101,7 +102,7 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, ByteVector.fromString("baz", StringType.Latin1), // Bogus ByteVector.getTextDelimiter(StringType.Latin1), // Bogus ); - const header = new Id3v2FrameHeader(FrameIdentifiers.WXXX, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.WXXX, FrameFlags.None, fieldBytes.length); // Act const output = UserUrlLinkFrame.fromFieldBytes(header, fieldBytes, version); @@ -121,7 +122,7 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, ByteVector.getTextDelimiter(StringType.Latin1), ByteVector.fromString("bar", StringType.Latin1) ); - const header = new Id3v2FrameHeader(FrameIdentifiers.WXXX, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.WXXX, FrameFlags.None, fieldBytes.length); // Act const output = UserUrlLinkFrame.fromFieldBytes(header, fieldBytes, version); @@ -140,7 +141,7 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, ByteVector.getTextDelimiter(encoding), ByteVector.fromString("bar", StringType.Latin1) ); - const header = new Id3v2FrameHeader(FrameIdentifiers.WXXX, Id3v2FrameFlags.None, fieldBytes.length); + const header = new FrameHeader(FrameIdentifiers.WXXX, FrameFlags.None, fieldBytes.length); // Act const output = UserUrlLinkFrame.fromFieldBytes(header, fieldBytes, 4); @@ -320,7 +321,7 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, const expectedBytes = ByteVector.concatenate( FrameIdentifiers.WXXX.render(4), ByteVector.fromUint(5), - ByteVector.fromUshort(Id3v2FrameFlags.None), + ByteVector.fromUshort(FrameFlags.None), ByteVector.fromByte(StringType.Latin1), ByteVector.getTextDelimiter(StringType.Latin1), ByteVector.fromString("foo", StringType.Latin1) @@ -343,7 +344,7 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, const expectedBytes = ByteVector.concatenate( FrameIdentifiers.WXXX.render(4), ByteVector.fromUint(5), - ByteVector.fromUshort(Id3v2FrameFlags.None), + ByteVector.fromUshort(FrameFlags.None), ByteVector.fromByte(StringType.Latin1), ByteVector.fromString("foo", StringType.Latin1), ByteVector.getTextDelimiter(StringType.Latin1) @@ -366,7 +367,7 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, const expectedBytes = ByteVector.concatenate( FrameIdentifiers.WXXX.render(4), ByteVector.fromUint(8), - ByteVector.fromUshort(Id3v2FrameFlags.None), + ByteVector.fromUshort(FrameFlags.None), ByteVector.fromByte(StringType.Latin1), ByteVector.fromString("foo", StringType.Latin1), ByteVector.getTextDelimiter(StringType.Latin1), @@ -390,7 +391,7 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, const expectedBytes = ByteVector.concatenate( FrameIdentifiers.WXXX.render(4), ByteVector.fromUint(12), - ByteVector.fromUshort(Id3v2FrameFlags.None), + ByteVector.fromUshort(FrameFlags.None), ByteVector.fromByte(StringType.UTF16LE), ByteVector.fromString("foo", StringType.UTF16LE), ByteVector.getTextDelimiter(StringType.UTF16LE), diff --git a/test-unit/matroska/matroskaTagCollectionTests.ts b/test-unit/matroska/matroskaTagCollectionTests.ts index 4e4ca1a6..7c568c41 100644 --- a/test-unit/matroska/matroskaTagCollectionTests.ts +++ b/test-unit/matroska/matroskaTagCollectionTests.ts @@ -2,13 +2,15 @@ import {suite, test} from "@testdeck/mocha"; import {assert} from "chai"; import {Mock} from "typemoq"; +import MatroskaAttachment from "../../src/matroska/matroskaAttachment"; import MatroskaTag from "../../src/matroska/matroskaTag"; import MatroskaTagCollection from "../../src/matroska/matroskaTagCollection"; -import {TagTesters, Testers} from "../utilities/testers"; -import MatroskaAttachment from "../../src/matroska/matroskaAttachment"; -import {ByteVector, IPicture, PictureType, StringType, TagTypes} from "../../src"; -import {MatroskaTagTarget, MatroskaTagTargetType} from "../../src/matroska/matroskaTagTarget"; import MatroskaTagValue from "../../src/matroska/matroskaTagValue"; +import {ByteVector, StringType} from "../../src/byteVector"; +import {MatroskaTagTarget, MatroskaTagTargetType} from "../../src/matroska/matroskaTagTarget"; +import {IPicture, PictureType} from "../../src/picture"; +import {TagTypes} from "../../src/tag"; +import {TagTesters, Testers} from "../utilities/testers"; @suite class Matroska_TagCollectionTests { diff --git a/test-unit/matroska/utils.ts b/test-unit/matroska/utils.ts index 61de9f46..a09c5fcc 100644 --- a/test-unit/matroska/utils.ts +++ b/test-unit/matroska/utils.ts @@ -1,6 +1,6 @@ -import {ByteVector, StringType} from "../../src"; import EbmlElement from "../../src/ebml/ebmlElement"; import TestFile from "../utilities/testFile"; +import {ByteVector, StringType} from "../../src/byteVector"; export default class MatroskaTestUtils { public static getTestElement(value: string|boolean|number|bigint|ByteVector, id: number): EbmlElement { diff --git a/test-unit/riff/riffFileTests.ts b/test-unit/riff/riffFileTests.ts index d7dd25f1..98e499d7 100644 --- a/test-unit/riff/riffFileTests.ts +++ b/test-unit/riff/riffFileTests.ts @@ -17,7 +17,7 @@ import {default as Resources} from "./resources"; import {ByteVector, StringType} from "../../src/byteVector"; import {FileAccessMode, ReadStyle} from "../../src/file"; import {IFileAbstraction} from "../../src/fileAbstraction"; -import {Id3v2TagHeaderFlags} from "../../src/id3v2/id3v2TagHeader"; +import {TagFlags as Id3v2TagFlags} from "../../src/id3v2/enums"; import {TagTypes} from "../../src/tag"; import {Testers} from "../utilities/testers"; @@ -1319,7 +1319,7 @@ import {Testers} from "../utilities/testers"; private static getId3v2Bytes(fourcc: string): ByteVector { const id3v2Tag = Id3v2Tag.fromEmpty(); id3v2Tag.version = 4; - id3v2Tag.flags |= Id3v2TagHeaderFlags.FooterPresent; + id3v2Tag.flags |= Id3v2TagFlags.FooterPresent; id3v2Tag.amazonId = "foo"; return RiffChunk.fromData(fourcc, id3v2Tag.render()).render(); } @@ -1347,7 +1347,7 @@ import {Testers} from "../utilities/testers"; private static getSavedId3v2Bytes(fourcc: string): ByteVector { const expectedId3v2Tag = Id3v2Tag.fromEmpty(); expectedId3v2Tag.version = 4; - expectedId3v2Tag.flags |= Id3v2TagHeaderFlags.FooterPresent; + expectedId3v2Tag.flags |= Id3v2TagFlags.FooterPresent; expectedId3v2Tag.title = "foo"; expectedId3v2Tag.amazonId = "foo"; expectedId3v2Tag.composers = ["Giuseppe Ottiviani"]; diff --git a/test-unit/sandwich/endTagTests.ts b/test-unit/sandwich/endTagTests.ts index 0838a35e..960a54b9 100644 --- a/test-unit/sandwich/endTagTests.ts +++ b/test-unit/sandwich/endTagTests.ts @@ -6,10 +6,10 @@ import ApeTag from "../../src/ape/apeTag"; import EndTag from "../../src/sandwich/endTag"; import Id3v1Tag from "../../src/id3v1/id3v1Tag"; import Id3v2Tag from "../../src/id3v2/id3v2Tag"; -import {default as TestFile} from "../utilities/testFile"; +import TestFile from "../utilities/testFile"; import {ByteVector} from "../../src/byteVector"; +import {TagFlags as Id3v2TagFlags} from "../../src/id3v2/enums"; import {File, ReadStyle} from "../../src/file"; -import {Id3v2TagHeaderFlags} from "../../src/id3v2/id3v2TagHeader"; import {TagTypes} from "../../src/tag"; import {TagTesters, Testers} from "../utilities/testers"; import {NumberUtils} from "../../src/utils"; @@ -65,7 +65,7 @@ import {NumberUtils} from "../../src/utils"; id3v1Tag.track = 123; const id3v2Tag = Id3v2Tag.fromEmpty(); id3v2Tag.version = 4; - id3v2Tag.flags |= Id3v2TagHeaderFlags.FooterPresent; + id3v2Tag.flags |= Id3v2TagFlags.FooterPresent; id3v2Tag.album = "foo"; const apeTag = ApeTag.fromEmpty(); apeTag.title = "bar"; @@ -100,7 +100,7 @@ import {NumberUtils} from "../../src/utils"; id3v1Tag.track = 123; const id3v2Tag = Id3v2Tag.fromEmpty(); id3v2Tag.version = 4; - id3v2Tag.flags |= Id3v2TagHeaderFlags.FooterPresent; + id3v2Tag.flags |= Id3v2TagFlags.FooterPresent; id3v2Tag.album = "foobarbaz12345678901234567890"; id3v2Tag.albumArtists = ["foo", "bar", "baz"]; id3v2Tag.amazonId = "1234567890123456789012345678901234567890"; @@ -160,7 +160,7 @@ import {NumberUtils} from "../../src/utils"; const id3v1Tag = Id3v1Tag.fromEmpty(); const id3v2Tag = Id3v2Tag.fromEmpty(); id3v2Tag.version = 4; - id3v2Tag.flags |= Id3v2TagHeaderFlags.FooterPresent; + id3v2Tag.flags |= Id3v2TagFlags.FooterPresent; const apeTag = ApeTag.fromEmpty(); const fileBytes = ByteVector.concatenate( @@ -210,7 +210,7 @@ import {NumberUtils} from "../../src/utils"; assert.isOk(newTag); assert.strictEqual(newTag.tagTypes, TagTypes.Id3v2); assert.strictEqual(( newTag).version, 4); - assert.isTrue(NumberUtils.hasFlag(( newTag).flags, Id3v2TagHeaderFlags.FooterPresent)); + assert.isTrue(NumberUtils.hasFlag(( newTag).flags, Id3v2TagFlags.FooterPresent)); assert.strictEqual(tag.tags.length, 1); assert.strictEqual(tag.tagTypes, TagTypes.Id3v2); @@ -239,7 +239,7 @@ import {NumberUtils} from "../../src/utils"; // Arrange const id3v2Tag = Id3v2Tag.fromEmpty(); id3v2Tag.version = 4; - id3v2Tag.flags |= Id3v2TagHeaderFlags.FooterPresent; + id3v2Tag.flags |= Id3v2TagFlags.FooterPresent; id3v2Tag.album = "foobarbaz"; id3v2Tag.title = "fuxbuxquxx"; @@ -270,7 +270,7 @@ import {NumberUtils} from "../../src/utils"; // Arrange const id3v2Tag = Id3v2Tag.fromEmpty(); id3v2Tag.version = 4; - id3v2Tag.flags |= Id3v2TagHeaderFlags.FooterPresent; + id3v2Tag.flags |= Id3v2TagFlags.FooterPresent; id3v2Tag.album = "foobarbaz"; const apeTag = ApeTag.fromEmpty(); apeTag.title = "fuxbuxquxx"; @@ -315,4 +315,3 @@ import {NumberUtils} from "../../src/utils"; assert.isTrue(output.isEmpty); } } - diff --git a/test-unit/sandwich/sandwichTagTests.ts b/test-unit/sandwich/sandwichTagTests.ts index 2881d57c..386a04b0 100644 --- a/test-unit/sandwich/sandwichTagTests.ts +++ b/test-unit/sandwich/sandwichTagTests.ts @@ -5,10 +5,10 @@ import ApeTag from "../../src/ape/apeTag"; import Id3v1Tag from "../../src/id3v1/id3v1Tag"; import Id3v2Tag from "../../src/id3v2/id3v2Tag"; import SandwichTag from "../../src/sandwich/sandwichTag"; -import {default as TestFile} from "../utilities/testFile"; +import TestFile from "../utilities/testFile"; import {ByteVector} from "../../src/byteVector"; +import {TagFlags as Id3v2TagFlags} from "../../src/id3v2/enums"; import {File, ReadStyle} from "../../src/file"; -import {Id3v2TagHeaderFlags} from "../../src/id3v2/id3v2TagHeader"; import {TagTypes} from "../../src/tag"; import {TagTesters, Testers} from "../utilities/testers"; @@ -64,7 +64,7 @@ import {TagTesters, Testers} from "../utilities/testers"; // Arrange const id3v2Tag = Id3v2Tag.fromEmpty(); id3v2Tag.version = 4; - id3v2Tag.flags |= Id3v2TagHeaderFlags.FooterPresent; + id3v2Tag.flags |= Id3v2TagFlags.FooterPresent; id3v2Tag.album = "foo"; const apeTag = ApeTag.fromEmpty(); apeTag.amazonId = "bar"; diff --git a/test-unit/xiph/resources.ts b/test-unit/xiph/resources.ts index 5dac09ac..cd1047d0 100644 --- a/test-unit/xiph/resources.ts +++ b/test-unit/xiph/resources.ts @@ -1,4 +1,5 @@ -import {ByteVector, PictureType, StringType} from "../../src"; +import {ByteVector, StringType} from "../../src/byteVector"; +import {PictureType} from "../../src/picture"; export default class XiphTestResources { public static readonly pictureData = ByteVector.fromString("foobarbaz", StringType.UTF8); From f041cb4b14a7152903976cfeb98b0c83b69dbd12 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 29 Jul 2026 22:11:20 -0500 Subject: [PATCH 02/18] Introduce Id3v2Version enum --- .eslintrc.js | 1 + src/id3v2/enums.ts | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.eslintrc.js b/.eslintrc.js index d93c27bd..3b5eb7e7 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -72,6 +72,7 @@ module.exports = { "@typescript-eslint/no-namespace": "error", "@typescript-eslint/no-parameter-properties": "warn", "@typescript-eslint/no-shadow": "error", + "@typescript-eslint/no-unsafe-enum-comparison": "error", "@typescript-eslint/prefer-namespace-keyword": "error", "@typescript-eslint/restrict-template-expressions": 0, "@typescript-eslint/triple-slash-reference": [ diff --git a/src/id3v2/enums.ts b/src/id3v2/enums.ts index 8e0a6457..2f886a68 100644 --- a/src/id3v2/enums.ts +++ b/src/id3v2/enums.ts @@ -266,12 +266,12 @@ export enum Id3v2Version { /** * Indicates the ID3v2.2 version. */ - V22 = 1, + V22 = 2, /** * Indicates the ID3v2.3 version. */ - V23 = 2, + V23 = 3, /** * Indicates the ID3v2.4 version. From 04ab7e6e186a7cbbb4f61aa7f3ef27a98df56f3e Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 29 Jul 2026 22:46:16 -0500 Subject: [PATCH 03/18] FrameHeader --- src/id3v2/frames/frameHeader.ts | 51 ++++------ test-unit/id3v2/frameHeaderTests.ts | 144 +++++++--------------------- 2 files changed, 54 insertions(+), 141 deletions(-) diff --git a/src/id3v2/frames/frameHeader.ts b/src/id3v2/frames/frameHeader.ts index 62480d8d..65685495 100644 --- a/src/id3v2/frames/frameHeader.ts +++ b/src/id3v2/frames/frameHeader.ts @@ -1,6 +1,6 @@ import SyncData from "../syncData"; import {ByteVector, StringType} from "../../byteVector"; -import {FrameFlags} from "../enums"; +import {FrameFlags, Id3v2Version} from "../enums"; import {CorruptFileError, NotImplementedError} from "../../errors"; import {FrameIdentifier, FrameIdentifiers} from "../frameIdentifiers"; import {Guards, NumberUtils} from "../../utils"; @@ -54,17 +54,15 @@ export default class FrameHeader { * a frame identifier and the remaining values are zeroed. @TODO: Why?? Why needs that functionality? * @param version ID3v2 version with which the data in `data` was encoded. */ - public static fromData(data: ByteVector, version: number): FrameHeader { + public static fromData(data: ByteVector, version: Id3v2Version): FrameHeader { Guards.truthy(data, "data"); - Guards.byte(version, "version"); - Guards.betweenInclusive(version, 2, 4, "version"); let rawFrameId: string; let frameId: FrameIdentifier; let flags = 0; let frameSize = 0; switch (version) { - case 2: + case Id3v2Version.V22: if (data.length < 3) { throw new CorruptFileError("Data must contain at least a 3 byte frame identifier"); } @@ -82,7 +80,7 @@ export default class FrameHeader { frameSize = data.subarray(3, 3).toUint(); break; - case 3: + case Id3v2Version.V23: if (data.length < 4) { throw new CorruptFileError("Data must contain at least a 4 byte frame identifier"); } @@ -106,7 +104,7 @@ export default class FrameHeader { ); break; - case 4: + case Id3v2Version.V24: if (data.length < 4) { throw new CorruptFileError("Data must contain at least 4 byte frame identifier"); } @@ -245,11 +243,10 @@ export default class FrameHeader { /** * Gets the size of a header for a specified ID3v2 version. - * @param version Version of ID3v2 to get the size for. Must be a positive integer < 256 + * @param version Version of ID3v2 to get the size for */ - public static getBaseSize(version: number): number { - Guards.byte(version, "version"); - return version < 3 ? 6 : 10; + public static getBaseSize(version: Id3v2Version): number { + return version === Id3v2Version.V22 ? 6 : 10; } /** @@ -257,18 +254,17 @@ export default class FrameHeader { * determined by the flags initially read for the freame header. * @param payloadBytes Frame's payload from which the extended header bytes will be read. These * bytes must be resynchronized if the frame was marked as unsynchronized. - * @param version ID3v2 version. Must be a byte. + * @param version ID3v2 version * @returns number Number of bytes for the extended frame header fields. */ - public readExtendedHeaderFromPayloadBytes(payloadBytes: ByteVector, version: number): number { + public readExtendedHeaderFromPayloadBytes(payloadBytes: ByteVector, version: Id3v2Version): number { Guards.truthy(payloadBytes, "payloadBytes"); - Guards.byte(version, "version"); let position = 0; switch (version) { - case 2: + case Id3v2Version.V22: break; - case 3: + case Id3v2Version.V23: if (NumberUtils.hasFlag(this._flags, FrameFlags.Compression)) { this._dataLength = this.getFieldBytes(payloadBytes, position, 4).toUint(); position += 4; @@ -282,7 +278,7 @@ export default class FrameHeader { position++; } break; - case 4: + case Id3v2Version.V24: if (NumberUtils.hasFlag(this._flags, FrameFlags.GroupingIdentity)) { this._groupId = this.getFieldBytes(payloadBytes, position, 1).get(0); position++; @@ -296,8 +292,6 @@ export default class FrameHeader { position += 4; } break; - default: - throw new Error("Argument error: version must be a valid ID3v2 version."); } return position; @@ -318,19 +312,16 @@ export default class FrameHeader { * Renders the current instance, encoded in a specified ID3v2 version. * @param version Version of ID3v2 to use when encoding the current instance. */ - public render(version: number): ByteVector { - Guards.byte(version, "version"); - Guards.betweenInclusive(version, 2, 4, "version"); - + public render(version: Id3v2Version): ByteVector { // Start by rendering the frame identifier const byteVectors = [this._frameId.render(version)]; switch (version) { - case 2: + case Id3v2Version.V22: byteVectors.push(ByteVector.fromUint(this._frameSize).subarray(1, 3)); break; - case 3: + case Id3v2Version.V23: const newFlags = NumberUtils.uintOr( NumberUtils.uintAnd(NumberUtils.uintLShift(this._flags, 1), 0xE000), NumberUtils.uintAnd(NumberUtils.uintLShift(this._flags, 4), 0x00C0), @@ -341,7 +332,7 @@ export default class FrameHeader { byteVectors.push(ByteVector.fromUshort(newFlags)); break; - case 4: + case Id3v2Version.V24: byteVectors.push(SyncData.fromUint(this._frameSize)); byteVectors.push(ByteVector.fromUshort(this._flags)); break; @@ -350,12 +341,12 @@ export default class FrameHeader { return ByteVector.concatenate(... byteVectors); } - public renderExtendedHeader(version: number): ByteVector { + public renderExtendedHeader(version: Id3v2Version): ByteVector { const fieldVectors = []; switch (version) { - case 2: + case Id3v2Version.V22: break; - case 3: + case Id3v2Version.V23: if (NumberUtils.hasFlag(this._flags, FrameFlags.Compression)) { throw new NotImplementedError("Compression is not supported."); } @@ -366,7 +357,7 @@ export default class FrameHeader { fieldVectors.push(ByteVector.fromByte(this._groupId)); } break; - case 4: + case Id3v2Version.V24: if (NumberUtils.hasFlag(this._flags, FrameFlags.GroupingIdentity)) { fieldVectors.push(ByteVector.fromByte(this._groupId)); } diff --git a/test-unit/id3v2/frameHeaderTests.ts b/test-unit/id3v2/frameHeaderTests.ts index 14006791..354b5132 100644 --- a/test-unit/id3v2/frameHeaderTests.ts +++ b/test-unit/id3v2/frameHeaderTests.ts @@ -5,7 +5,7 @@ import FrameHeader from "../../src/id3v2/frames/frameHeader"; import PropertyTests from "../utilities/propertyTests"; import {ByteVector, StringType} from "../../src/byteVector"; import {Allow, Testers} from "../utilities/testers"; -import {FrameFlags} from "../../src/id3v2/enums"; +import {FrameFlags, Id3v2Version} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {NumberUtils} from "../../src/utils"; @@ -24,119 +24,47 @@ import {NumberUtils} from "../../src/utils"; assert.throws(() => FrameHeader.fromData(testBytes, 5)); } - @test - public fromData_v2_tooShort() { + @params([Id3v2Version.V22, 2], "v2") + @params([Id3v2Version.V23, 3], "v3") + @params([Id3v2Version.V24, 3], "v4") + public fromData_tooShort([version, testLength]: [Id3v2Version, number]) { // Arrange - const testBytes = ByteVector.fromSize(2); + const testBytes = ByteVector.fromSize(testLength); // Act / Assert - assert.throws(() => FrameHeader.fromData(testBytes, 2)); - } - - @test - public fromData_v2_standardIdentifier() { - // Arrange - const testBytes = ByteVector.fromString("TT1", StringType.Latin1); - - // Act - const header = FrameHeader.fromData(testBytes, 2); - - // Assert - assert.isOk(header); - assert.strictEqual(header.frameId, FrameIdentifiers['TIT1']); - assert.strictEqual(header.flags, 0); - assert.strictEqual(header.frameSize, 0); + assert.throws(() => FrameHeader.fromData(testBytes, version)); } - @test - public fromData_v2_nonstandardIdentifier() { + @params([Id3v2Version.V22, "TT1"], "v2") + @params([Id3v2Version.V23, "TIT1"], "v3") + @params([Id3v2Version.V24, "TIT1"], "v4") + public fromData_standardIdentifier([version, testIdentifier]: [Id3v2Version, string]) { // Arrange - const testBytes = ByteVector.fromString("NON", StringType.Latin1); + const testBytes = ByteVector.fromString(testIdentifier, StringType.Latin1); // Act - const header = FrameHeader.fromData(testBytes, 2); + const header = FrameHeader.fromData(testBytes, version); // Assert assert.isOk(header); - Testers.bvEqual(header.frameId.render(2), testBytes); + assert.strictEqual(header.frameId, FrameIdentifiers[testIdentifier]); assert.strictEqual(header.flags, 0); assert.strictEqual(header.frameSize, 0); } - @test - public fromData_v3_tooShort() { - // Arrange - const testBytes = ByteVector.fromSize(3); - - // Act / Assert - assert.throws(() => FrameHeader.fromData(testBytes, 3)); - } - - @test - public fromData_v3_standardIdentifier() { - // Arrange - const testBytes = ByteVector.fromString("TIT1", StringType.Latin1); - - // Act - const header = FrameHeader.fromData(testBytes, 3); - - // Assert - assert.isOk(header); - assert.strictEqual(header.frameId, FrameIdentifiers['TIT1']); - assert.strictEqual(header.flags, 0); - assert.strictEqual(header.frameSize, 0); - } - - @test - public fromData_v3_nonstandardIdentifier() { + @params([Id3v2Version.V22, "NON"], "v2") + @params([Id3v2Version.V23, "NON1"], "v3") + @params([Id3v2Version.V24, "NON1"], "v4") + public fromData_nonstandardIdentifier([version, testIdentifier]: [Id3v2Version, string]) { // Arrange - const testBytes = ByteVector.fromString("NON1", StringType.Latin1); + const testBytes = ByteVector.fromString(testIdentifier, StringType.Latin1); // Act - const header = FrameHeader.fromData(testBytes, 3); + const header = FrameHeader.fromData(testBytes, version); // Assert assert.isOk(header); - Testers.bvEqual(header.frameId.render(3), testBytes); - assert.strictEqual(header.flags, 0); - assert.strictEqual(header.frameSize, 0); - } - - @test - public fromData_v4_tooShort() { - // Arrange - const testBytes = ByteVector.fromSize(3); - - // Act / Assert - assert.throws(() => FrameHeader.fromData(testBytes, 4)); - } - - @test - public fromData_v4_standardIdentifier() { - // Arrange - const testBytes = ByteVector.fromString("TIT1", StringType.Latin1); - - // Act - const header = FrameHeader.fromData(testBytes, 4); - - // Assert - assert.isOk(header); - assert.strictEqual(header.frameId, FrameIdentifiers['TIT1']); - assert.strictEqual(header.flags, 0); - assert.strictEqual(header.frameSize, 0); - } - - @test - public fromData_v4_nonstandardIdentifier() { - // Arrange - const testBytes = ByteVector.fromString("NON1", StringType.Latin1); - - // Act - const header = FrameHeader.fromData(testBytes, 4); - - // Assert - assert.isOk(header); - Testers.bvEqual(header.frameId.render(4), testBytes); + Testers.bvEqual(header.frameId.render(version), testBytes); assert.strictEqual(header.flags, 0); assert.strictEqual(header.frameSize, 0); } @@ -244,10 +172,10 @@ import {NumberUtils} from "../../src/utils"; // #region Method Tests - @params([2, 6], "v2") - @params([3, 10], "v3") - @params([4, 10], "v4") - public getBaseSize([version, size]: [number, number]) { + @params([Id3v2Version.V22, 6], "v2") + @params([Id3v2Version.V23, 10], "v3") + @params([Id3v2Version.V24, 10], "v4") + public getBaseSize([version, size]: [Id3v2Version, number]) { // Act const result = FrameHeader.getBaseSize(version); @@ -284,7 +212,7 @@ import {NumberUtils} from "../../src/utils"; header.flags = flags; // Act - const result = header.readExtendedHeaderFromPayloadBytes(ByteVector.fromSize(10), 2); + const result = header.readExtendedHeaderFromPayloadBytes(ByteVector.fromSize(10), Id3v2Version.V22); // Assert assert.strictEqual(result, 0); @@ -340,7 +268,7 @@ import {NumberUtils} from "../../src/utils"; const extendedBytes = ByteVector.fromByteArray([0x01, 0x02, 0x03, 0x04, 0x05, 0x06]); // Act - const result = header.readExtendedHeaderFromPayloadBytes(extendedBytes, 3); + const result = header.readExtendedHeaderFromPayloadBytes(extendedBytes, Id3v2Version.V23); // Assert assert.strictEqual(result, length); @@ -395,7 +323,7 @@ import {NumberUtils} from "../../src/utils"; const extendedBytes = ByteVector.fromByteArray([0x01, 0x02, 0x03, 0x04, 0x05, 0x06]); // Act - const result = header.readExtendedHeaderFromPayloadBytes(extendedBytes, 4); + const result = header.readExtendedHeaderFromPayloadBytes(extendedBytes, Id3v2Version.V24); // Assert assert.strictEqual(result, length); @@ -405,17 +333,14 @@ import {NumberUtils} from "../../src/utils"; } @test - public readExtendedHeaderFromPayloadBytes_notEnoughBytes() { + public readExtendedHeaderFromPayloadBytes_v4_notEnoughBytes() { // Arrange - const header = new FrameHeader( - FrameIdentifiers.APIC, - FrameFlags.DataLengthIndicator - ); + const header = new FrameHeader(FrameIdentifiers.APIC, FrameFlags.DataLengthIndicator); const extendedBytes = ByteVector.fromByteArray([0x00, 0x00, 0x02]); // Act / Assert assert.throws( - () => header.readExtendedHeaderFromPayloadBytes(extendedBytes, 4), + () => header.readExtendedHeaderFromPayloadBytes(extendedBytes, Id3v2Version.V24), "ID3v2 frame extended header does not contain enough bytes for fields set by flags" ); } @@ -423,14 +348,11 @@ import {NumberUtils} from "../../src/utils"; @test public renderExtendedHeader_v4_dataLengthIndicatorIsSyncSafe() { // Arrange - const header = new FrameHeader( - FrameIdentifiers.APIC, - FrameFlags.DataLengthIndicator - ); + const header = new FrameHeader(FrameIdentifiers.APIC, FrameFlags.DataLengthIndicator); header.dataLength = 0x100; // Act - const result = header.renderExtendedHeader(4); + const result = header.renderExtendedHeader(Id3v2Version.V24); // Assert Testers.bvEqual(result, [0x00, 0x00, 0x02, 0x00]); From a1dad427578a9fc7d595f73372345b2004f78afa Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 29 Jul 2026 23:08:38 -0500 Subject: [PATCH 04/18] Frame --- src/id3v2/frames/frame.ts | 20 ++++++++------------ test-unit/id3v2/frameTests.ts | 14 +++++++------- 2 files changed, 15 insertions(+), 19 deletions(-) diff --git a/src/id3v2/frames/frame.ts b/src/id3v2/frames/frame.ts index f57aacab..8a78a0dc 100644 --- a/src/id3v2/frames/frame.ts +++ b/src/id3v2/frames/frame.ts @@ -2,9 +2,9 @@ import FrameHeader from "./frameHeader"; import Id3v2Settings from "../id3v2Settings"; import SyncData from "../syncData"; import {ByteVector, StringType} from "../../byteVector"; -import {FrameFlags} from "../enums"; +import {FrameFlags, Id3v2Version} from "../enums"; import {FrameIdentifier} from "../frameIdentifiers"; -import {Guards, NumberUtils} from "../../utils"; +import {NumberUtils} from "../../utils"; /** * Abstract class that represents an ID3v2 frame. Frames are the unit for storing information in @@ -108,9 +108,7 @@ export default abstract class Frame { * Renders the current instance, encoded in a specified ID3v2 version. * @param version Version of ID3v2 to use when encoding the current instance */ - public render(version: number): ByteVector { - Guards.byte(version, "version"); - + public render(version: Id3v2Version): ByteVector { // 1) Render the fields const fieldBytes = this.renderFields(version); if (fieldBytes.length === 0) { @@ -121,11 +119,11 @@ export default abstract class Frame { // 2) Render the extended header and process with the body // Remove flags that are not supported by older versions of ID3v2 - if (version < 4) { + if (version !== Id3v2Version.V24) { const v4Flags = FrameFlags.DataLengthIndicator | FrameFlags.Unsynchronized; this.flags &= ~(v4Flags); } - if (version < 3) { + if (version === Id3v2Version.V22) { const v3Flags = FrameFlags.Compression | FrameFlags.Encryption | FrameFlags.FileAlterPreservation @@ -165,14 +163,12 @@ export default abstract class Frame { * {@link Id3v2Settings.forceDefaultEncoding} and what is supported by * `version` */ - protected static correctEncoding(type: StringType, version: number): StringType { - Guards.byte(version, "version"); - + protected static correctEncoding(type: StringType, version: Id3v2Version): StringType { if (Id3v2Settings.forceDefaultEncoding) { type = Id3v2Settings.defaultEncoding; } - return version < 4 && type === StringType.UTF8 + return version !== Id3v2Version.V24 && type === StringType.UTF8 ? StringType.UTF16 : type; } @@ -181,7 +177,7 @@ export default abstract class Frame { * Renders the values in the current instance into field data for a specified version. * @param version ID3v2 version the field data is to be encoded in. */ - protected abstract renderFields(version: number): ByteVector; + protected abstract renderFields(version: Id3v2Version): ByteVector; // #endregion } diff --git a/test-unit/id3v2/frameTests.ts b/test-unit/id3v2/frameTests.ts index 5a0890d0..11a1b5e8 100644 --- a/test-unit/id3v2/frameTests.ts +++ b/test-unit/id3v2/frameTests.ts @@ -5,7 +5,7 @@ import Frame from "../../src/id3v2/frames/frame"; import FrameHeader from "../../src/id3v2/frames/frameHeader"; import PropertyTests from "../utilities/propertyTests"; import {ByteVector} from "../../src/byteVector"; -import {FrameFlags} from "../../src/id3v2/enums"; +import {FrameFlags, Id3v2Version} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -24,9 +24,9 @@ class TestFrame extends Frame { return undefined; } - protected parseFields(_data: ByteVector, _version: number): void { /* no-op */ } + protected parseFields(_data: ByteVector, _version: Id3v2Version): void { /* no-op */ } - protected renderFields(_version: number): ByteVector { + protected renderFields(_version: Id3v2Version): ByteVector { return TestFrame.renderFieldData; } } @@ -103,11 +103,11 @@ class TestFrame extends Frame { const frame = new TestFrame(header); // Act - const output = frame.render(4); + const output = frame.render(Id3v2Version.V24); // Assert const expected = ByteVector.concatenate( - header.render(4), + header.render(Id3v2Version.V24), ByteVector.fromUint(TestFrame.renderFieldData.length), TestFrame.renderFieldData ); @@ -122,11 +122,11 @@ class TestFrame extends Frame { frame.groupId = 0x88; // Act - const output = frame.render(4); + const output = frame.render(Id3v2Version.V24); // Assert const expected = ByteVector.concatenate( - header.render(4), + header.render(Id3v2Version.V24), 0x88, TestFrame.renderFieldData ); From 51642c6a27efc3a813bb6122deef93b67d7289fe Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Wed, 29 Jul 2026 23:10:34 -0500 Subject: [PATCH 05/18] FrameIdentifiers --- src/id3v2/frameIdentifiers.ts | 11 ++-- test-unit/id3v2/frameIdentifiersTests.ts | 70 +++++------------------- 2 files changed, 20 insertions(+), 61 deletions(-) diff --git a/src/id3v2/frameIdentifiers.ts b/src/id3v2/frameIdentifiers.ts index 5d6a3e48..e04fb540 100644 --- a/src/id3v2/frameIdentifiers.ts +++ b/src/id3v2/frameIdentifiers.ts @@ -1,5 +1,6 @@ import {ByteVector, StringType} from "../byteVector"; import {NotSupportedError} from "../errors"; +import {Id3v2Version} from "./enums"; /** * Represents the identifier of a frame, depending on the version this may be 3 or 4 @@ -75,20 +76,18 @@ export class FrameIdentifier { * @throws NotSupportedError Thrown if the frame identifier does not contain a string for the * provided ID3v2 version. */ - public render(version: number): ByteVector { + public render(version: Id3v2Version): ByteVector { let bytesForVersion; switch (version) { - case 2: + case Id3v2Version.V22: bytesForVersion = this._version2; break; - case 3: + case Id3v2Version.V23: bytesForVersion = this._version3; break; - case 4: + case Id3v2Version.V24: bytesForVersion = this._version4; break; - default: - throw new Error("Argument error: version must be a value between 2 and 4"); } if (!bytesForVersion) { diff --git a/test-unit/id3v2/frameIdentifiersTests.ts b/test-unit/id3v2/frameIdentifiersTests.ts index c9b04934..858ff81f 100644 --- a/test-unit/id3v2/frameIdentifiersTests.ts +++ b/test-unit/id3v2/frameIdentifiersTests.ts @@ -1,15 +1,16 @@ -import {suite, test} from "@testdeck/mocha"; +import {params, suite, test} from "@testdeck/mocha"; import {assert} from "chai"; import {ByteVector, StringType} from "../../src/byteVector"; import {FrameIdentifier, FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; +import {Id3v2Version} from "../../src/id3v2/enums"; @suite class FrameIdentifierTests { @test public isTextFrame_v2StartsWithT() { // Arrange - const identifier = new FrameIdentifier(undefined, "XYZZ", "TCH"); + const identifier = new FrameIdentifier("ABC", "DEF", "TCH"); // Act const output = identifier.isTextFrame; @@ -21,7 +22,7 @@ import {Testers} from "../utilities/testers"; @test public isTextFrame_v3StartsWithT() { // Arrange - const identifier = new FrameIdentifier(undefined, "TCCH", "XYZ"); + const identifier = new FrameIdentifier("ABC", "TCCH", "DEF"); // Act const output = identifier.isTextFrame; @@ -33,7 +34,7 @@ import {Testers} from "../utilities/testers"; @test public isTextFrame_v4StartsWithT() { // Arrange - const identifier = new FrameIdentifier("TCCH", "XYZZ", undefined); + const identifier = new FrameIdentifier("TCCH", "ABC", "DEF"); // Act const output = identifier.isTextFrame; @@ -45,7 +46,7 @@ import {Testers} from "../utilities/testers"; @test public isTextFrame_noVersionStartsWithT() { // Arrange - const identifier = new FrameIdentifier("XYZZ", undefined, "XYZ"); + const identifier = new FrameIdentifier("ABC", "DEF", "GHI"); // Act const output = identifier.isTextFrame; @@ -57,7 +58,7 @@ import {Testers} from "../utilities/testers"; @test public isUrlFrame_v2StartsWithW() { // Arrange - const identifier = new FrameIdentifier(undefined, undefined, "WCH"); + const identifier = new FrameIdentifier("ABC", "DEF", "WCH"); // Act const output = identifier.isUrlFrame; @@ -69,7 +70,7 @@ import {Testers} from "../utilities/testers"; @test public isUrlFrame_v3StartsWithW() { // Arrange - const identifier = new FrameIdentifier(undefined, "WCCH", undefined); + const identifier = new FrameIdentifier("ABC", "WCCH", "DEF"); // Act const output = identifier.isUrlFrame; @@ -81,7 +82,7 @@ import {Testers} from "../utilities/testers"; @test public isUrlFrame_v4StartsWithW() { // Arrange - const identifier = new FrameIdentifier("WCCH", undefined, undefined); + const identifier = new FrameIdentifier("WCCH", "ABC", "DEF"); // Act const output = identifier.isUrlFrame; @@ -90,58 +91,17 @@ import {Testers} from "../utilities/testers"; assert.isTrue(output); } - @test - public render_invalidVersion() { - // Act / Assert - assert.throws(() => { FrameIdentifiers.RVA2.render(-1); }); - assert.throws(() => { FrameIdentifiers.RVA2.render(1.23); }); - assert.throws(() => { FrameIdentifiers.RVA2.render(256); }); - assert.throws(() => { FrameIdentifiers.RVA2.render(1); }); - assert.throws(() => { FrameIdentifiers.RVA2.render(5); }); - } - - @test - public render_v2() { - // Arrange - const identifier = new FrameIdentifier("ABCD", "DEFG", "HIJ"); - - // Act - const output = identifier.render(2); - - // Assert - Testers.bvEqual(output, ByteVector.fromString("HIJ", StringType.UTF8)); - } - - @test - public render_v3() { + @params([Id3v2Version.V22, "HIJ"], "v2") + @params([Id3v2Version.V23, "DEFG"], "v3") + @params([Id3v2Version.V24, "ABCD"], "v4") + public render([version, expected]: [Id3v2Version, string]) { // Arrange const identifier = new FrameIdentifier("ABCD", "DEFG", "HIJ"); // Act - const output = identifier.render(3); + const output = identifier.render(version); // Assert - Testers.bvEqual(output, ByteVector.fromString("DEFG", StringType.UTF8)); - } - - @test - public render_v4() { - // Arrange - const identifier = new FrameIdentifier("ABCD", "DEFG", "HIJ"); - - // Act - const output = identifier.render(4); - - // Assert - Testers.bvEqual(output, ByteVector.fromString("ABCD", StringType.UTF8)); - } - - @test - public render_unsupported() { - // Arrange - const identifier = new FrameIdentifier("ABCD", undefined, undefined); - - // Act / Assert - assert.throws(() => identifier.render(2)); + Testers.bvEqual(output, ByteVector.fromString(expected, StringType.UTF8)); } } From c6ba38641a91653a4781d1e04d84963c55949803 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Thu, 30 Jul 2026 00:27:37 -0500 Subject: [PATCH 06/18] TagFooter --- src/id3v2/tagFooter.ts | 36 +++++----- test-unit/id3v2/tagFooterTests.ts | 116 +++++++++++++++--------------- 2 files changed, 79 insertions(+), 73 deletions(-) diff --git a/src/id3v2/tagFooter.ts b/src/id3v2/tagFooter.ts index 2bc2d7ec..c59e4b85 100644 --- a/src/id3v2/tagFooter.ts +++ b/src/id3v2/tagFooter.ts @@ -2,7 +2,7 @@ import Id3v2Settings from "./id3v2Settings"; import SyncData from "./syncData"; import TagHeader from "./tagHeader"; import {ByteVector, StringType} from "../byteVector"; -import {TagFlags} from "./enums"; +import {Id3v2Version, TagFlags} from "./enums"; import {CorruptFileError} from "../errors"; import {Guards, NumberUtils} from "../utils"; @@ -17,9 +17,9 @@ export default class TagFooter { public static readonly FILE_IDENTIFIER = ByteVector.fromString("3DI", StringType.Latin1).makeReadOnly(); private _flags: TagFlags = TagFlags.FooterPresent; - private _majorVersion: number = 0; - private _revisionNumber: number = 0; - private _tagSize: number = 0; + private _majorVersion: Id3v2Version; + private _revisionNumber: number; + private _tagSize: number; /** * Constructs and initializes a new instance by reading it from raw footer data. @@ -35,18 +35,24 @@ export default class TagFooter { } const footer = new TagFooter(); - footer._majorVersion = data.get(3); + + const majorVersion = data.get(3); + if (majorVersion < 2 || majorVersion > 4) { + throw new CorruptFileError(`Id3v2 footer has invalid version: ${majorVersion}`); + } + footer._majorVersion = majorVersion; + footer._revisionNumber = data.get(4); footer._flags = data.get(5); // TODO: Is there any point to supporting footers on versions less than 4? - if (footer._majorVersion === 2 && NumberUtils.hasFlag(footer._flags, 127)) { + if (footer._majorVersion === Id3v2Version.V22 && NumberUtils.hasFlag(footer._flags, 127)) { throw new CorruptFileError("Invalid flags set on version 2 tag"); } - if (footer._majorVersion === 3 && NumberUtils.hasFlag(footer._flags, 15)) { + if (footer._majorVersion === Id3v2Version.V23 && NumberUtils.hasFlag(footer._flags, 15)) { throw new CorruptFileError("Invalid flags set on version 3 tag"); } - if (footer._majorVersion === 4 && NumberUtils.hasFlag(footer._flags, 7)) { + if (footer._majorVersion === Id3v2Version.V24 && NumberUtils.hasFlag(footer._flags, 7)) { throw new CorruptFileError("Invalid flags set on version 4 tag"); } @@ -99,11 +105,11 @@ export default class TagFooter { */ public set flags(value: TagFlags) { const version3Flags = TagFlags.ExtendedHeader | TagFlags.ExperimentalIndicator; - if (NumberUtils.hasFlag(value, version3Flags) && this.majorVersion < 3) { + if (NumberUtils.hasFlag(value, version3Flags) && this.majorVersion === Id3v2Version.V22) { throw new Error("Feature only supported in version 2.3+"); } const version4Flags = TagFlags.FooterPresent; - if (NumberUtils.hasFlag(value, version4Flags) && this.majorVersion < 4) { + if (NumberUtils.hasFlag(value, version4Flags) && this.majorVersion !== Id3v2Version.V24) { throw new Error("Feature only supported in version 2.4+"); } @@ -113,11 +119,7 @@ export default class TagFooter { /** * Sets the major version of the tag described by the current instance. */ - public get majorVersion(): number { - return this._majorVersion === 0 - ? Id3v2Settings.defaultVersion - : this._majorVersion; - } + public get majorVersion(): Id3v2Version { return this._majorVersion; } /** * Sets the major version of the tag described by the current instance. * When the version is set, unsupported header flags will automatically be removed from the @@ -125,8 +127,8 @@ export default class TagFooter { * @param value ID3v2 version if tag described by the current instance. Footers are only * supported with version 4, so this value can only be 4. */ - public set majorVersion(value: number) { - if (value !== 4) { + public set majorVersion(value: Id3v2Version) { + if (value !== Id3v2Version.V24) { throw new Error("Argument out of range: Version unsupported"); } this._majorVersion = value; diff --git a/test-unit/id3v2/tagFooterTests.ts b/test-unit/id3v2/tagFooterTests.ts index 24241b7a..a71e1215 100644 --- a/test-unit/id3v2/tagFooterTests.ts +++ b/test-unit/id3v2/tagFooterTests.ts @@ -1,20 +1,20 @@ -import {suite, test} from "@testdeck/mocha"; +import {params, suite, test} from "@testdeck/mocha"; import {assert} from "chai"; import TestConstants from "../testConstants"; import TagFooter from "../../src/id3v2/tagFooter"; import Id3v2Settings from "../../src/id3v2/id3v2Settings"; import {ByteVector} from "../../src/byteVector"; -import {TagFlags} from "../../src/id3v2/enums"; +import {Id3v2Version, TagFlags} from "../../src/id3v2/enums"; import {Testers} from "../utilities/testers"; -const getTestFooter = (majorVersion: number, minorVersion: number, flags: TagFlags): TagFooter => { +const getTestFooter = (majorVersion: Id3v2Version, minorVersion: number, flags: TagFlags): TagFooter => { const data = ByteVector.concatenate( - TagFooter.FILE_IDENTIFIER, - majorVersion, - minorVersion, - flags, - TestConstants.syncedUintBytes + TagFooter.FILE_IDENTIFIER, // File identifier + majorVersion, // Major version + minorVersion, // Minor version + flags, // Flags + 0x10, 0x10, 0x10, 0x10 // Size in bytes (unsync'd) ); return TagFooter.fromData(data); }; @@ -27,7 +27,7 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: TagFla } @test - public fromData_invalidDataLength() { + public fromData_tooSmall() { // Arrange const data = ByteVector.fromSize(1); @@ -44,12 +44,31 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: TagFla assert.throws(() => TagFooter.fromData(data)); } + @params(1, "too_low") + @params(5, "too_high") + public fromData_invalidMajorVersion(version: number) { + // Arrange + const data = ByteVector.concatenate( + TagFooter.FILE_IDENTIFIER, // File identifier + version, // Major version (out of range) + 0x00, // Minor version + 0x00, // Flags + 0x10, 0x10, 0x10, 0x10 // Size in bytes (sync'd) + ); + + // Act/Assert + assert.throws(() => TagFooter.fromData(data)); + } + @test public fromData_invalidFlags_version4() { // Arrange const data = ByteVector.concatenate( - TagFooter.FILE_IDENTIFIER, - 0x04, 0x00, 0x07 + TagFooter.FILE_IDENTIFIER, // File identifier + 0x04, // Major version + 0x00, // Minor version + 0x07, // Flags (invalid for v4) + 0x10, 0x10, 0x10, 0x10 // Size in bytes (sync'd) ); // Act/Assert @@ -60,8 +79,10 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: TagFla public fromData_invalidTagSizeBytes() { // Arrange const testData = ByteVector.concatenate( - TagFooter.FILE_IDENTIFIER, - 0x04, 0x00, 0x00 + TagFooter.FILE_IDENTIFIER, // File identifier + 0x04, // Major version + 0x00, // Minor version + 0x00 // Flags ); const testData1 = ByteVector.concatenate(testData, 0x80, 0x00, 0x00, 0x00); const testData2 = ByteVector.concatenate(testData, 0x00, 0x80, 0x00, 0x00); @@ -78,25 +99,24 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: TagFla @test public fromData_validParams() { // Arrange - const majorVersion = 0x04; const minorVersion = 0x00; const flags = 0xE0; const testData = ByteVector.concatenate( - TagFooter.FILE_IDENTIFIER, - majorVersion, - minorVersion, - flags, - TestConstants.syncedUintBytes + TagFooter.FILE_IDENTIFIER, // File identifier + Id3v2Version.V24, // Major version + 0x01, // Minor version + TagFlags.ExperimentalIndicator, // Flags + 0x10, 0x10, 0x10, 0x10 // Size in bytes ); // Act const output = TagFooter.fromData(testData); // Assert - assert.equal(output.flags, flags); - assert.equal(output.majorVersion, majorVersion); - assert.equal(output.revisionNumber, minorVersion); - assert.equal(output.tagSize, TestConstants.syncedUint); + assert.equal(output.flags, TagFlags.ExperimentalIndicator); + assert.equal(output.majorVersion, Id3v2Version.V24); + assert.equal(output.revisionNumber, 1); + assert.equal(output.tagSize, 0x2040810); } } @@ -104,7 +124,7 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: TagFla @test public getCompleteTagSize() { // Arrange - const footer = getTestFooter(4, 0, TagFlags.None); + const footer = getTestFooter(Id3v2Version.V24, 0, TagFlags.None); // Act const output = footer.completeTagSize; @@ -116,7 +136,7 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: TagFla @test public setFlags_validFlags() { // Arrange - const footer = getTestFooter(4, 0, TagFlags.None); + const footer = getTestFooter(Id3v2Version.V24, 0, TagFlags.None); // Act footer.flags = TagFlags.FooterPresent; @@ -126,44 +146,31 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: TagFla } @test - public getMajorVersion_zero() { + public getMajorVersion() { // Arrange - const footer = getTestFooter(0, 0, TagFlags.None); + const footer = getTestFooter(Id3v2Version.V24, 0, TagFlags.None); // Act const output = footer.majorVersion; // Assert - assert.equal(output, Id3v2Settings.defaultVersion); + assert.equal(output, Id3v2Version.V24); } - @test - public getMajorVersion_nonZero() { - // Arrange - const footer = getTestFooter(4, 0, TagFlags.None); - - // Act - const output = footer.majorVersion; - - // Assert - assert.equal(output, 4); - } - - @test - public setMajorVersion_invalidValues() { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + public setMajorVersion_invalidValues(version: Id3v2Version) { // Arrange - const footer = getTestFooter(4, 0, TagFlags.None); + const footer = getTestFooter(Id3v2Version.V24, 0, TagFlags.None); // Act/Assert - Testers.testByte((v: number) => { footer.majorVersion = v; }); - assert.throws(() => { footer.majorVersion = 1; }); - assert.throws(() => { footer.majorVersion = 5; }); + assert.throws(() => { footer.majorVersion = version; }); } @test public setRevisionNumber_invalidValue() { // Arrange - const footer = getTestFooter(4, 0, TagFlags.None); + const footer = getTestFooter(Id3v2Version.V24, 0, TagFlags.None); // Act/Assert Testers.testByte((v: number) => { footer.revisionNumber = v; }); @@ -172,7 +179,7 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: TagFla @test public setRevisionNumber_validValue() { // Arrange - const footer = getTestFooter(4, 0, TagFlags.None); + const footer = getTestFooter(Id3v2Version.V24, 0, TagFlags.None); // Act footer.revisionNumber = 2; @@ -184,7 +191,7 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: TagFla @test public setTagSize_invalidValues() { // Arrange - const footer = getTestFooter(4, 0, TagFlags.None); + const footer = getTestFooter(Id3v2Version.V24, 0, TagFlags.None); // Act/Assert assert.throws(() => { footer.tagSize = -1; }); @@ -195,7 +202,7 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: TagFla @test public publicsetTagSize_validValue() { // Arrange - const footer = getTestFooter(4, 0, TagFlags.None); + const footer = getTestFooter(Id3v2Version.V24, 0, TagFlags.None); // Act footer.tagSize = 0x1234; @@ -209,14 +216,11 @@ const getTestFooter = (majorVersion: number, minorVersion: number, flags: TagFla @test public render() { // Arrange - const majorVersion = 0x04; - const minorVersion = 0x00; - const flags = 0xE0; const testData = ByteVector.concatenate( TagFooter.FILE_IDENTIFIER, - majorVersion, - minorVersion, - flags, + Id3v2Version.V24, + 0x00, + 0xE0, TestConstants.syncedUintBytes ); const footer = TagFooter.fromData(testData); From 65fa3a60cd1cdbe70000ec62e5fae9c6c89ca8f9 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Thu, 30 Jul 2026 01:11:10 -0500 Subject: [PATCH 07/18] TagHeader --- src/id3v2/tagHeader.ts | 46 +++--- test-unit/id3v2/tagHeaderTests.ts | 239 +++++++++++++----------------- 2 files changed, 129 insertions(+), 156 deletions(-) diff --git a/src/id3v2/tagHeader.ts b/src/id3v2/tagHeader.ts index a39e8af3..b244e594 100644 --- a/src/id3v2/tagHeader.ts +++ b/src/id3v2/tagHeader.ts @@ -1,7 +1,7 @@ import Id3v2Settings from "./id3v2Settings"; import SyncData from "./syncData"; import {ByteVector, StringType} from "../byteVector"; -import {TagFlags} from "./enums"; +import {Id3v2Version, TagFlags} from "./enums"; import {CorruptFileError} from "../errors"; import {Guards, NumberUtils} from "../utils"; @@ -15,10 +15,10 @@ export default class TagHeader { */ public static readonly FILE_IDENTIFIER = ByteVector.fromString("ID3", StringType.Latin1).makeReadOnly(); - private _flags: TagFlags = TagFlags.None; - private _majorVersion: number = 0; - private _revisionNumber: number = 0; - private _tagSize: number = 0; + private _flags: TagFlags; + private _majorVersion: Id3v2Version; + private _revisionNumber: number; + private _tagSize: number; // #region Constructors @@ -30,7 +30,7 @@ export default class TagHeader { * @param tagSize Size of the tag in bytes as it currently exists on the disk. See {@link tagSize}. * @internal */ - public constructor(majorVersion: number, revisionVersion: number, flags: TagFlags, tagSize: number) { + public constructor(majorVersion: Id3v2Version, revisionVersion: number, flags: TagFlags, tagSize: number) { this._majorVersion = majorVersion; this.flags = flags; @@ -51,22 +51,28 @@ export default class TagHeader { throw new CorruptFileError("Provided data does not start with the file identifier"); } - const majorVersion = data.get(3); + const majorVersionNumber = data.get(3); + if (majorVersionNumber > 4 || majorVersionNumber < 2) { + throw new CorruptFileError(`ID3v2 tag header has an invalid version: ${majorVersionNumber}`); + } + const majorVersion = majorVersionNumber; + const revisionNumber = data.get(4); const flags = data.get(5); // Make sure flags provided are legal - if (majorVersion === 2 && NumberUtils.hasFlag(flags, 63)) { + if (majorVersion === Id3v2Version.V22 && NumberUtils.hasFlag(flags, 63)) { throw new CorruptFileError("Invalid flags set on version 2 tag"); } - if (majorVersion === 3 && NumberUtils.hasFlag(flags, 15)) { + if (majorVersion === Id3v2Version.V23 && NumberUtils.hasFlag(flags, 15)) { throw new CorruptFileError("Invalid flags set on version 3 tag"); } - if (majorVersion === 4 && NumberUtils.hasFlag(flags, 7)) { + if (majorVersion === Id3v2Version.V24 && NumberUtils.hasFlag(flags, 7)) { throw new CorruptFileError("Invalid flags set on version 4 tag"); } // Make sure the bytes for the size of the tag are legal + // @TODO: Create a helper that checks and returns valid value or throws for (let i = 6; i < 10; i++) { if (data.get(i) >= 128) { throw new CorruptFileError("One of the bytes in the tag size was greater than the allowed 128"); @@ -103,11 +109,11 @@ export default class TagHeader { public set flags(value: TagFlags) { // @TODO: Does it make sense to check for flags for major version <4? const version3Flags = TagFlags.ExtendedHeader | TagFlags.ExperimentalIndicator; - if (NumberUtils.hasFlag(value, version3Flags) && this.majorVersion < 3) { + if (NumberUtils.hasFlag(value, version3Flags) && this._majorVersion === Id3v2Version.V22) { throw new Error("Feature only supported in version 2.3+"); } const version4Flags = TagFlags.FooterPresent; - if (NumberUtils.hasFlag(value, version4Flags) && this.majorVersion < 4) { + if (NumberUtils.hasFlag(value, version4Flags) && this._majorVersion !== Id3v2Version.V24) { throw new Error("Feature only supported in version 2.4+"); } @@ -117,8 +123,8 @@ export default class TagHeader { /** * Gets the major version of the tag described by the current instance. */ - public get majorVersion(): number { - return this._majorVersion === 0 || Id3v2Settings.forceDefaultVersion + public get majorVersion(): Id3v2Version { + return this._majorVersion === undefined || Id3v2Settings.forceDefaultVersion ? Id3v2Settings.defaultVersion : this._majorVersion; } @@ -126,17 +132,13 @@ export default class TagHeader { * Sets the major version of the tag described by the current instance. * When the version is set, unsupported header flags will automatically be removed from the * tag. - * @param value ID3v2 version of tag. Must be a positive 8-bit integer betweenInclusive 2 and 4. + * @param value ID3v2 version of tag */ - public set majorVersion(value: number) { - Guards.byte(value, "value"); - Guards.betweenInclusive(value, 2, 4, "value"); - - // @TODO: do we need to support setting to versions <4? - if (value < 3) { + public set majorVersion(value: Id3v2Version) { + if (value === Id3v2Version.V22) { this._flags &= ~(TagFlags.ExtendedHeader | TagFlags.ExperimentalIndicator); } - if (value < 4) { + if (value !== Id3v2Version.V24) { this._flags &= ~TagFlags.FooterPresent; } diff --git a/test-unit/id3v2/tagHeaderTests.ts b/test-unit/id3v2/tagHeaderTests.ts index d72150d2..d47974c1 100644 --- a/test-unit/id3v2/tagHeaderTests.ts +++ b/test-unit/id3v2/tagHeaderTests.ts @@ -1,34 +1,33 @@ -import {suite, test} from "@testdeck/mocha"; +import {params, suite, test} from "@testdeck/mocha"; import {assert} from "chai"; import Id3v2Settings from "../../src/id3v2/id3v2Settings"; import TagHeader from "../../src/id3v2/tagHeader"; -import TestConstants from "../testConstants"; import {ByteVector} from "../../src/byteVector"; -import {TagFlags} from "../../src/id3v2/enums"; +import {Id3v2Version, TagFlags} from "../../src/id3v2/enums"; import {Testers} from "../utilities/testers"; import {NumberUtils} from "../../src/utils"; -const getTestHeader = (majorVersion: number, minorVersion: number, flags: TagFlags): TagHeader => { +const getTestHeader = (majorVersion: Id3v2Version, minorVersion: number, flags: TagFlags): TagHeader => { const data = ByteVector.concatenate( - TagHeader.FILE_IDENTIFIER, - majorVersion, - minorVersion, - flags, - 0x10, 0x10, 0x10, 0x10 + TagHeader.FILE_IDENTIFIER, // File identifier + majorVersion, // Major version + minorVersion, // Minor version + flags, // Flags + 0x10, 0x10, 0x10, 0x10 // Size in bytes (unsync'd) ); return TagHeader.fromData(data); }; @suite class Id3v2_TagHeader_ConstructorTests { @test - public falsyData() { + public fromData_falsyData() { // Act/Assert Testers.testTruthy((v: ByteVector) => TagHeader.fromData(v)); } @test - public tooShortData() { + public fromData_tooSmall() { // Arrange const data0 = ByteVector.empty(); const data1 = ByteVector.fromSize(1); @@ -39,60 +38,57 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: TagFla } @test - public invalidStartOfData() { - // Act/Assert - assert.throws(() => TagHeader.fromData(TestConstants.testByteVector)); - } - - @test - public invalidFlagsForVersion2() { + public fromData_missingIdentifier() { // Arrange - const testData = ByteVector.concatenate( - TagHeader.FILE_IDENTIFIER, - 0x02, 0x00, - 0xFF, - 0x00, 0x00, 0x00, 0x00 - ); + const data = ByteVector.fromSize(10); // Act/Assert - assert.throws(() => TagHeader.fromData(testData)); + assert.throws(() => TagHeader.fromData(data)); } - @test - public invalidFlagsForVersion3() { + @params(1, "too_low") + @params(5, "too_high") + public fromData_invalidMajorVersion(version: number) { // Arrange - const testData = ByteVector.concatenate( - TagHeader.FILE_IDENTIFIER, - 0x03, 0x00, - 0xFF, - 0x00, 0x00, 0x00, 0x00 + const data = ByteVector.concatenate( + TagHeader.FILE_IDENTIFIER, // File identifier + version, // Major version (out of range) + 0x00, // Minor version + 0x00, // Flags + 0x10, 0x10, 0x10, 0x10 // Size in bytes (sync'd) ); // Act/Assert - assert.throws(() => TagHeader.fromData(testData)); + assert.throws(() => TagHeader.fromData(data)); } - @test - public invalidFlagsForVersion4() { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromData_invalidFlags(version: Id3v2Version) { // Arrange const testData = ByteVector.concatenate( - TagHeader.FILE_IDENTIFIER, - 0x04, 0x00, - 0xFF, - 0x00, 0x00, 0x00, 0x00 + TagHeader.FILE_IDENTIFIER, // File identifier + version, // Major version + 0x00, // Minor version + 0xFF, // Flags (invalid) + 0x10, 0x10, 0x10, 0x10 // Size in bytes (sync'd) ); // Act/Assert assert.throws(() => TagHeader.fromData(testData)); } - @test - public invalidTagSizeBytes() { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromData_invalidTagSizeBytes(version: Id3v2Version) { // Arrange const testData = ByteVector.concatenate( - TagHeader.FILE_IDENTIFIER, - 0x04, 0x00, - 0x00 + TagHeader.FILE_IDENTIFIER, // File identifier + version, // Major version + 0x00, // Minor version + 0x00 // Flags ); const testData1 = ByteVector.concatenate(testData, 0x80, 0x00, 0x00, 0x00); const testData2 = ByteVector.concatenate(testData, 0x00, 0x80, 0x00, 0x00); @@ -106,27 +102,26 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: TagFla assert.throws(() => TagHeader.fromData(testData4)); } - @test - public validData() { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromData_validData(version: Id3v2Version) { // Arrange - const majorVersion = 0x04; - const minorVersion = 0x00; - const flags = 0xE0; const testData = ByteVector.concatenate( - TagHeader.FILE_IDENTIFIER, - majorVersion, - minorVersion, - flags, - 0x10, 0x10, 0x10, 0x10 + TagHeader.FILE_IDENTIFIER, // File identifier + version, // Major version + 0x01, // Minor version + TagFlags.None, // Flags + 0x10, 0x10, 0x10, 0x10 // Size in bytes (sync'd) ); // Act const output = TagHeader.fromData(testData); // Assert - assert.equal(output.flags, flags); - assert.equal(output.majorVersion, majorVersion); - assert.equal(output.revisionNumber, minorVersion); + assert.equal(output.flags, TagFlags.None); + assert.equal(output.majorVersion, version); + assert.equal(output.revisionNumber, 0x01); assert.equal(output.tagSize, 0x2040810); } } @@ -142,9 +137,9 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: TagFla } @test - public getCompleteTagSize_withFooter() { + public getCompleteTagSize_v4_withFooter() { // Arrange - const header = getTestHeader(4, 0, TagFlags.FooterPresent); + const header = getTestHeader(Id3v2Version.V24, 0, TagFlags.FooterPresent); // Act const totalSize = header.completeTagSize; @@ -154,9 +149,9 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: TagFla } @test - public getCompleteTagSize_noFooter() { + public getCompleteTagSize_v4_noFooter() { // Arrange - const header = getTestHeader(4, 0, TagFlags.None); + const header = getTestHeader(Id3v2Version.V24, 0, TagFlags.None); // Act const totalSize = header.completeTagSize; @@ -165,40 +160,30 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: TagFla assert.equal(totalSize, header.tagSize + Id3v2Settings.headerSize); } - @test - public setFlags_version2InvalidFlags() { + @params(TagFlags.ExtendedHeader, "ExtendedHeader") + @params(TagFlags.ExperimentalIndicator, "ExperimentalIndicator") + @params(TagFlags.FooterPresent, "FooterPresent") + public setFlags_v2_invalidFlags(flags: TagFlags) { // Arrange - const header = getTestHeader(2, 0, TagFlags.None); - - // Act - const set1 = () => { header.flags = TagFlags.ExtendedHeader; }; - const set2 = () => { header.flags = TagFlags.ExperimentalIndicator; }; - const set3 = () => { header.flags = TagFlags.FooterPresent; }; + const header = getTestHeader(Id3v2Version.V22, 0, TagFlags.None); - // Assert - assert.throws(set1); - assert.throws(set2); - assert.throws(set3); - assert.equal(header.flags, TagFlags.None); + // Act / Assert + assert.throws(() => { header.flags = flags }); } @test - public setFlags_version3InvalidFlags() { + public setFlags_v3_invalidFlags() { // Arrange const header = getTestHeader(3, 0, TagFlags.None); - // Act - const set = () => { header.flags = TagFlags.FooterPresent; }; - - // Assert - assert.throws(set); - assert.equal(header.flags, TagFlags.None); + // Act / Assert + assert.throws(() => { header.flags = TagFlags.FooterPresent }); } @test public setFlags_validFlags() { // Arrange - const header = getTestHeader(4, 0, TagFlags.None); + const header = getTestHeader(Id3v2Version.V24, 0, TagFlags.None); // Act header.flags = TagFlags.FooterPresent; @@ -207,34 +192,26 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: TagFla assert.equal(header.flags, TagFlags.FooterPresent); } - @test - public getMajorVersion_zero() { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public getMajorVersion(version: Id3v2Version) { // Arrange - const header = getTestHeader(0, 0, TagFlags.None); + const header = getTestHeader(version, 0, TagFlags.None); // Act const output = header.majorVersion; // Assert - assert.equal(output, Id3v2Settings.defaultVersion); + assert.equal(output, version); } - @test - public getMajorVersion_nonZero() { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public getMajorVersion_forcedDefault(version: Id3v2Version) { // Arrange - const header = getTestHeader(4, 0, TagFlags.None); - - // Act - const output = header.majorVersion; - - // Assert - assert.equal(output, 4); - } - - @test - public getMajorVersion_forcedDefault() { - // Arrange - const header = getTestHeader(4, 0, TagFlags.None); + const header = getTestHeader(version, 0, TagFlags.None); const initialForceValue = Id3v2Settings.forceDefaultVersion; try { @@ -252,23 +229,12 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: TagFla } @test - public setMajorVersion_invalidValues() { - // Arrange - const header = getTestHeader(4, 0, TagFlags.None); - - // Act/Assert - Testers.testByte((v: number) => { header.majorVersion = v; }); - assert.throws(() => { header.majorVersion = 1; }); - assert.throws(() => { header.majorVersion = 5; }); - } - - @test - public setMajorVersion_2_unsets3And4Flags() { + public setMajorVersion_v2_unsets3And4Flags() { // Arrange const flags = TagFlags.ExtendedHeader | TagFlags.ExperimentalIndicator | TagFlags.FooterPresent; - const header = getTestHeader(4, 0, flags); + const header = getTestHeader(Id3v2Version.V24, 0, flags); // Act header.majorVersion = 2; @@ -279,10 +245,10 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: TagFla } @test - public setMajorVersion3_unsets4Flags() { + public setMajorVersion_v3_unsets4Flags() { // Arrange const flags = TagFlags.FooterPresent; - const header = getTestHeader(4, 0, flags); + const header = getTestHeader(Id3v2Version.V24, 0, flags); // Act header.majorVersion = 3; @@ -292,19 +258,23 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: TagFla assert.isFalse(NumberUtils.hasFlag(header.flags, flags)); } - @test - public setRevisionNumber_invalidValue() { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public setRevisionNumber_invalidValue(version: Id3v2Version) { // Arrange - const header = getTestHeader(4, 0, TagFlags.None); + const header = getTestHeader(version, 0, TagFlags.None); // Act/Assert Testers.testByte((v: number) => { header.revisionNumber = v; }); } - @test - public setRevisionNumber_validValue() { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public setRevisionNumber_validValue(version: Id3v2Version) { // Arrange - const header = getTestHeader(4, 0, TagFlags.None); + const header = getTestHeader(version, 0, TagFlags.None); // Act header.revisionNumber = 2; @@ -313,20 +283,24 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: TagFla assert.equal(header.revisionNumber, 2); } - @test - public setTagSize_invalidValues() { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public setTagSize_invalidValues(version: Id3v2Version) { // Arrange - const header = getTestHeader(4, 0, TagFlags.None); + const header = getTestHeader(version, 0, TagFlags.None); // Act/Assert Testers.testUint((v: number) => { header.tagSize = v; }); assert.throws(() => { header.tagSize = 0xF0000000; }); } - @test - public setTagSize_validValue() { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public setTagSize_validValue(version: Id3v2Version) { // Arrange - const header = getTestHeader(4, 0, TagFlags.None); + const header = getTestHeader(version, 0, TagFlags.None); // Act header.tagSize = 0x1234; @@ -340,14 +314,11 @@ const getTestHeader = (majorVersion: number, minorVersion: number, flags: TagFla @test public render() { // Arrange - const majorVersion = 0x04; - const minorVersion = 0x00; - const flags = 0xE0; const testData = ByteVector.concatenate( TagHeader.FILE_IDENTIFIER, - majorVersion, - minorVersion, - flags, + Id3v2Version.V24, + 0x00, + 0xE0, 0x10, 0x10, 0x10, 0x10 ); const header = TagHeader.fromData(testData); From eddfd0bb83c0c4b537b55c101c4bcc52fcf3a6fd Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Thu, 30 Jul 2026 23:49:03 -0500 Subject: [PATCH 08/18] TagHeaderExtended --- src/id3v2/tagHeaderExtended.ts | 19 ++- test-unit/id3v2/tagExtendedHeaderTests.ts | 156 ---------------------- test-unit/id3v2/tagHeaderExtendedTests.ts | 89 ++++++++++++ 3 files changed, 98 insertions(+), 166 deletions(-) delete mode 100644 test-unit/id3v2/tagExtendedHeaderTests.ts create mode 100644 test-unit/id3v2/tagHeaderExtendedTests.ts diff --git a/src/id3v2/tagHeaderExtended.ts b/src/id3v2/tagHeaderExtended.ts index 80212e25..dc61232c 100644 --- a/src/id3v2/tagHeaderExtended.ts +++ b/src/id3v2/tagHeaderExtended.ts @@ -3,6 +3,7 @@ import {ByteVector} from "../byteVector"; import {CorruptFileError} from "../errors"; import {Guards} from "../utils"; import {File} from "../file"; +import {Id3v2Version} from "./enums"; /** * This class is a filler until support for reading and writing the ID3v2 extended header is @@ -16,11 +17,10 @@ export default class TagHeaderExtended { /** * Constructs and initializes a new instance by reading the raw contents. * @param data Raw extended header structure - * @param version ID3v2 version. Must be an unsigned 8-bit integer. + * @param version ID3v2 version */ - public static fromData(data: ByteVector, version: number): TagHeaderExtended { + public static fromData(data: ByteVector, version: Id3v2Version): TagHeaderExtended { Guards.truthy(data, "data"); - Guards.byte(version, "version"); if (data.length < 4) { throw new CorruptFileError("Provided data is smaller than extended header size field"); } @@ -28,10 +28,10 @@ export default class TagHeaderExtended { const header = new TagHeaderExtended(); // Read extended header size - const declaredSize = version === 3 + const declaredSize = version === Id3v2Version.V23 ? data.subarray(0, 4).toUint() : SyncData.toUint(data.subarray(0, 4)); - header._size = (version === 3 ? 4 : 0) + declaredSize; + header._size = (version === Id3v2Version.V23 ? 4 : 0) + declaredSize; return header; } @@ -40,12 +40,11 @@ export default class TagHeaderExtended { * Constructs and initializes a new instance by reading from file. * @param file File containing the extended header * @param position Offset into the file where the extended header begins. - * @param version ID3v2 version. Must be an unsigned 8-bit integer. + * @param version ID3v2 version */ - public static fromFile(file: File, position: number, version: number): TagHeaderExtended { + public static fromFile(file: File, position: number, version: Id3v2Version): TagHeaderExtended { Guards.truthy(file, "file"); Guards.safeUint(position, "position"); - Guards.byte(version, "version"); const header = new TagHeaderExtended(); @@ -59,10 +58,10 @@ export default class TagHeaderExtended { ); } - const declaredSize = version === 3 + const declaredSize = version === Id3v2Version.V23 ? sizeData.toUint() : SyncData.toUint(sizeData); - header._size = (version === 3 ? 4 : 0) + declaredSize; + header._size = (version === Id3v2Version.V23 ? 4 : 0) + declaredSize; return header; } diff --git a/test-unit/id3v2/tagExtendedHeaderTests.ts b/test-unit/id3v2/tagExtendedHeaderTests.ts deleted file mode 100644 index 4eb563e4..00000000 --- a/test-unit/id3v2/tagExtendedHeaderTests.ts +++ /dev/null @@ -1,156 +0,0 @@ -import {params, suite, test} from "@testdeck/mocha"; -import {assert} from "chai"; - -import TagHeaderExtended from "../../src/id3v2/tagHeaderExtended"; -import {ByteVector} from "../../src/byteVector"; -import {Testers} from "../utilities/testers"; -import TestFile from "../utilities/testFile"; -import {File} from "../../src/file"; - -@suite class Id3v2_TagExtendedHeaderTests { - @test - public fromData_falsyData() { - // Act/Assert - Testers.testTruthy((v: ByteVector) => { TagHeaderExtended.fromData(v, 2); }); - } - - @test - public fromData_invalidVersion() { - // Arrange - const testData = ByteVector.fromSize(4); - - // Act/Assert - Testers.testByte((v: number) => { TagHeaderExtended.fromData(testData, v); }); - } - - @params(ByteVector.empty(), "empty") - @params(ByteVector.fromSize(1), "length1") - @params(ByteVector.fromSize(3), "length3") - public fromData_tooShortData(data: ByteVector) { - // Act/Assert - assert.throws(() => TagHeaderExtended.fromData(data, 4)); - } - - @test - public fromData_version3() { - // Arrange - const testData = ByteVector.concatenate(0x10, 0x10, 0x10, 0x10); - - // Act - const output = TagHeaderExtended.fromData(testData, 3); - - // Assert - assert.equal(output.size, 4 + 0x10101010); - } - - @test - public fromData_version2() { - // Arrange - const testData = ByteVector.concatenate(0x10, 0x10, 0x10, 0x10); - - // Act - const output = TagHeaderExtended.fromData(testData, 2); - - // Assert - assert.equal(output.size, 0x2040810); - } - - @test - public fromData_version4() { - // Arrange - const testData = ByteVector.concatenate(0x10, 0x10, 0x10, 0x10); - - // Act - const output = TagHeaderExtended.fromData(testData, 4); - - // Assert - assert.equal(output.size, 0x2040810); - } - - @test - public fromFile_falsyFile() { - // Act/Assert - Testers.testTruthy((v: File) => { TagHeaderExtended.fromFile(v, 0, 4); }); - } - - @test - public fromFile_invalidPosition() { - // Arrange - const file = TestFile.mockFile(); - - // Act/Assert - Testers.testSafeUint((v: number) => { TagHeaderExtended.fromFile(file, v, 4); }); - } - - @test - public fromFile_invalidVersion() { - // Arrange - const file = TestFile.mockFile(); - - // Act/Assert - Testers.testByte((v: number) => { TagHeaderExtended.fromFile(file, 0, v); }); - } - - @test - public fromFile_tooShortData() { - // Arrange - const file = TestFile.getFile(ByteVector.fromSize(3)); - - // Act/Assert - assert.throws(() => TagHeaderExtended.fromFile(file, 0, 4)); - } - - @test - public fromFile_version3() { - // Arrange - const file = TestFile.getFile(ByteVector.concatenate( - 0x00, 0x00, - 0x10, 0x10, 0x10, 0x10 - )); - - // Act - const output = TagHeaderExtended.fromFile(file, 2, 3); - - // Assert - assert.equal(output.size, 4 + 0x10101010); - } - - @test - public fromFile_version2() { - // Arrange - const file = TestFile.getFile(ByteVector.concatenate( - 0x00, 0x00, - 0x10, 0x10, 0x10, 0x10 - )); - - // Act - const output = TagHeaderExtended.fromFile(file, 2, 2); - - // Assert - assert.equal(output.size, 0x2040810); - } - - @test - public fromFile_version4() { - // Arrange - const file = TestFile.getFile(ByteVector.concatenate( - 0x00, 0x00, - 0x10, 0x10, 0x10, 0x10 - )); - - // Act - const output = TagHeaderExtended.fromFile(file, 2, 4); - - // Assert - assert.equal(output.size, 0x2040810); - } - - @test - public fromEmpty() { - // Act - const output = TagHeaderExtended.fromEmpty(); - - // Assert - assert.equal(output.size, 0); - } -} diff --git a/test-unit/id3v2/tagHeaderExtendedTests.ts b/test-unit/id3v2/tagHeaderExtendedTests.ts new file mode 100644 index 00000000..7e97ba5f --- /dev/null +++ b/test-unit/id3v2/tagHeaderExtendedTests.ts @@ -0,0 +1,89 @@ +import {params, suite, test} from "@testdeck/mocha"; +import {assert} from "chai"; + +import TagHeaderExtended from "../../src/id3v2/tagHeaderExtended"; +import {ByteVector} from "../../src/byteVector"; +import {Testers} from "../utilities/testers"; +import TestFile from "../utilities/testFile"; +import {File} from "../../src/file"; +import {Id3v2Version} from "../../src/id3v2/enums"; + +@suite class Id3v2_TagExtendedHeaderTests { + @test + public fromData_falsyData() { + // Act/Assert + Testers.testTruthy((v: ByteVector) => { TagHeaderExtended.fromData(v, Id3v2Version.V22); }); + } + + @params(ByteVector.empty(), "empty") + @params(ByteVector.fromSize(1), "length1") + @params(ByteVector.fromSize(3), "length3") + public fromData_tooShortData(data: ByteVector) { + // Act/Assert + assert.throws(() => TagHeaderExtended.fromData(data, Id3v2Version.V24)); + } + + @params([Id3v2Version.V22, 0x2040810], "v2") + @params([Id3v2Version.V23, 4 + 0x10101010], "v3") + @params([Id3v2Version.V24, 0x2040810], "v4") + public fromData([version, expectedSize]: [Id3v2Version, number]) { + // Arrange + const testData = ByteVector.concatenate(0x10, 0x10, 0x10, 0x10); + + // Act + const output = TagHeaderExtended.fromData(testData, version); + + // Assert + assert.equal(output.size, expectedSize); + } + + @test + public fromFile_falsyFile() { + // Act/Assert + Testers.testTruthy((v: File) => { TagHeaderExtended.fromFile(v, 0, Id3v2Version.V24); }); + } + + @test + public fromFile_invalidPosition() { + // Arrange + const file = TestFile.mockFile(); + + // Act/Assert + Testers.testSafeUint((v: number) => { TagHeaderExtended.fromFile(file, v, Id3v2Version.V24); }); + } + + @test + public fromFile_tooShortData() { + // Arrange + const file = TestFile.getFile(ByteVector.fromSize(3)); + + // Act/Assert + assert.throws(() => TagHeaderExtended.fromFile(file, 0, Id3v2Version.V24)); + } + + @params([Id3v2Version.V22, 0x2040810], "v2") + @params([Id3v2Version.V23, 4 + 0x10101010], "v3") + @params([Id3v2Version.V24, 0x2040810], "v4") + public fromFile([version, expectedSize]: [Id3v2Version, number]) { + // Arrange + const file = TestFile.getFile(ByteVector.concatenate( + 0x00, 0x00, + 0x10, 0x10, 0x10, 0x10 + )); + + // Act + const output = TagHeaderExtended.fromFile(file, 2, version); + + // Assert + assert.equal(output.size, expectedSize); + } + + @test + public fromEmpty() { + // Act + const output = TagHeaderExtended.fromEmpty(); + + // Assert + assert.equal(output.size, 0); + } +} From 05290698768953dad62a368ee8c57edc60f19490 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Fri, 31 Jul 2026 00:28:24 -0500 Subject: [PATCH 09/18] Id3v2Tag --- src/id3v2/id3v2Tag.ts | 35 ++++++---- src/id3v2/utilTypes.ts | 5 -- test-unit/id3v2/id3v2TagTests.ts | 106 ++++++++++++------------------- 3 files changed, 60 insertions(+), 86 deletions(-) delete mode 100644 src/id3v2/utilTypes.ts diff --git a/src/id3v2/id3v2Tag.ts b/src/id3v2/id3v2Tag.ts index 953103c8..7ea052c4 100644 --- a/src/id3v2/id3v2Tag.ts +++ b/src/id3v2/id3v2Tag.ts @@ -13,7 +13,7 @@ import UnsynchronizedLyricsFrame from "./frames/unsynchronizedLyricsFrame"; import UrlLinkFrame from "./frames/urlLinkFrame"; import UserTextInformationFrame from "./frames/userTextInformationFrame"; import {ByteVector, StringType} from "../byteVector"; -import {FrameFlags, TagFlags} from "./enums"; +import {FrameFlags, Id3v2Version, TagFlags} from "./enums"; import {CorruptFileError, NotImplementedError, NotSupportedError} from "../errors"; import {File, ReadStyle} from "../file"; import {Id3v2FrameFactory} from "./frames/frameFactory"; @@ -182,19 +182,21 @@ export default class Id3v2Tag extends Tag { /** * Gets the ID3v2 version for the current instance. */ - public get version(): number { - return this._header.majorVersion; - } + public get version(): Id3v2Version { return this._header.majorVersion; } /** * Sets the ID3v2 version for the current instance. - * @param value ID3v2 version for the current instance. Must be 2, 3, or 4. + * @param value ID3v2 version for the current instance */ - public set version(value: number) { + public set version(value: Id3v2Version) { const originalVersion = this._header.majorVersion; this._header.majorVersion = value; // Migrate any incompatible frames that have direct migrations - if (value === 4 && (originalVersion === 2 || originalVersion === 3)) { + const v23ToV4 = (originalVersion === Id3v2Version.V22 || originalVersion== Id3v2Version.V23) && + value === Id3v2Version.V24; + const v4ToV23 = originalVersion === Id3v2Version.V24 && + (value === Id3v2Version.V22 || value === Id3v2Version.V23); + if (v23ToV4) { // * TYER, etc -> TDRC const tyerFrames = TextInformationFrame.filterFrames(this._frameList, FrameIdentifiers.TYER); const tdatFrames = TextInformationFrame.filterFrames(this._frameList, FrameIdentifiers.TDAT); @@ -216,7 +218,7 @@ export default class Id3v2Tag extends Tag { this.setTextFrame(FrameIdentifiers.TDRC, tdrcText); } - } else if (originalVersion === 4 && (value === 2 || value === 3)) { + } else if (v4ToV23) { // * TDRC -> TYER, etc const tdrcFrames = TextInformationFrame.filterFrames(this._frameList, FrameIdentifiers.TDRC); if (tdrcFrames.length > 0) { @@ -553,7 +555,7 @@ export default class Id3v2Tag extends Tag { } // Case 3: We have neither type of frame, create the frame for the version of tag on disk - if (this.version > 3) { + if (this.version === Id3v2Version.V24) { this.setNumberFrame(FrameIdentifiers.TDRC, value, 0); } else { this.setNumberFrame(FrameIdentifiers.TYER, value, 0); @@ -1119,9 +1121,9 @@ export default class Id3v2Tag extends Tag { // the extended header, frames and padding, but does not include the tag's header or footer const hasFooter = (this._header.flags & TagFlags.FooterPresent) !== 0; const unsyncAtFrameLevel = (this._header.flags & TagFlags.Unsynchronization) !== 0 - && this.version >= 4; + && this.version === Id3v2Version.V24; const unsyncAtTagLevel = (this._header.flags & TagFlags.Unsynchronization) !== 0 - && this.version < 4; + && this.version !== Id3v2Version.V24; this._header.majorVersion = hasFooter ? 4 : this.version; @@ -1216,7 +1218,7 @@ export default class Id3v2Tag extends Tag { private parseFromData(data: ByteVector, style: ReadStyle): void { // Determine if the entire tag needs to be resynchronized. // @TODO: How important is it to check if the version is < 4? - const fullTagUnsync = this.version < 4 && + const fullTagUnsync = this.version !== Id3v2Version.V24 && NumberUtils.hasFlag(this._header.flags, TagFlags.Unsynchronization); // Resynchronize the entire tag if required @@ -1230,7 +1232,7 @@ export default class Id3v2Tag extends Tag { private parseFromFile(file: File, offset: number, style: ReadStyle): void { // Determine if the entire tag needs to be resynchronized. // @TODO: How important is it to check if the version is < 4? - const fullTagUnsync = this.version < 4 && + const fullTagUnsync = this.version !== Id3v2Version.V24 && NumberUtils.hasFlag(this._header.flags, TagFlags.Unsynchronization); // 1) Resynchronize the entire tag if required @@ -1487,7 +1489,12 @@ export default class Id3v2Tag extends Tag { * @param minPlaces Minimum number of digits to use to display the `numerator`, if * the numerator has less than this number of digits, it will be filled with leading zeroes. */ - private setNumberFrame(ident: FrameIdentifier, numerator: number, denominator: number, minPlaces: number = 1): void { + private setNumberFrame( + ident: FrameIdentifier, + numerator: number, + denominator: number, + minPlaces: number = 1 + ): void { Guards.truthy(ident, "ident"); Guards.uint(numerator, "value"); Guards.uint(denominator, "count"); diff --git a/src/id3v2/utilTypes.ts b/src/id3v2/utilTypes.ts deleted file mode 100644 index 3f2ff2d6..00000000 --- a/src/id3v2/utilTypes.ts +++ /dev/null @@ -1,5 +0,0 @@ - - - - - diff --git a/test-unit/id3v2/id3v2TagTests.ts b/test-unit/id3v2/id3v2TagTests.ts index 60ab14eb..cce6e94d 100644 --- a/test-unit/id3v2/id3v2TagTests.ts +++ b/test-unit/id3v2/id3v2TagTests.ts @@ -20,14 +20,14 @@ import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import UnsynchronizedLyricsFrame from "../../src/id3v2/frames/unsynchronizedLyricsFrame"; import UserTextInformationFrame from "../../src/id3v2/frames/userTextInformationFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {TagFlags} from "../../src/id3v2/enums"; +import {Id3v2Version, TagFlags} from "../../src/id3v2/enums"; import {File, ReadStyle} from "../../src/file"; import {FrameIdentifier, FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {IPicture} from "../../src/picture"; import {TagTypes} from "../../src/tag"; import {Testers} from "../utilities/testers"; -const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): ByteVector => { +const getTestTagHeader = (version: Id3v2Version, flags: TagFlags, tagSize: number): ByteVector => { return ByteVector.concatenate( ByteVector.fromString("ID3", StringType.Latin1), version, 0x00, @@ -55,7 +55,7 @@ const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): By @test public fromData_emptyTag() { // Arrange - const data = getTestTagHeader(4, TagFlags.None, 0); + const data = getTestTagHeader(Id3v2Version.V24, TagFlags.None, 0); // Act const output = Id3v2Tag.fromData(data); @@ -69,7 +69,7 @@ const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): By public fromData_dataTooShortForTagLength() { // Arrange const data = ByteVector.concatenate( - getTestTagHeader(4, TagFlags.None, 5), + getTestTagHeader(Id3v2Version.V24, TagFlags.None, 5), 0x00, 0x00 ); @@ -81,12 +81,12 @@ const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): By public fromData_v4Tag() { // Arrange const frameBytes = ByteVector.concatenate( - PlayCountFrame.fromFields().render(4), - UniqueFileIdentifierFrame.fromFields("foo", ByteVector.fromUint(123)).render(4), - UnknownFrame.fromFields(FrameIdentifiers.RVRB, ByteVector.empty()).render(4), // Empty frame - ByteVector.fromSize(5) // Padding + PlayCountFrame.fromFields().render(Id3v2Version.V24), + UniqueFileIdentifierFrame.fromFields("foo", ByteVector.fromUint(123)).render(Id3v2Version.V24), + UnknownFrame.fromFields(FrameIdentifiers.RVRB, ByteVector.empty()).render(Id3v2Version.V24), // Empty frame + ByteVector.fromSize(5) // Padding ); - const tagHeader = getTestTagHeader(4, TagFlags.None, frameBytes.length); + const tagHeader = getTestTagHeader(Id3v2Version.V24, TagFlags.None, frameBytes.length); const data = ByteVector.concatenate(tagHeader, frameBytes); // Act @@ -117,9 +117,9 @@ const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): By @test public fromData_extendedHeader() { // Arrange - const frame1 = PlayCountFrame.fromFields().render(4); + const frame1 = PlayCountFrame.fromFields().render(Id3v2Version.V24); const data = ByteVector.concatenate( - getTestTagHeader(4, TagFlags.ExtendedHeader, frame1.length + 10), + getTestTagHeader(Id3v2Version.V24, TagFlags.ExtendedHeader, frame1.length + 10), SyncData.fromUint(10), 0x01, 0x00, @@ -142,9 +142,9 @@ const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): By @test public fromData_needsResync() { // Arrange - const frame1 = PlayCountFrame.fromFields(BigInt(123)).render(4); + const frame1 = PlayCountFrame.fromFields(BigInt(123)).render(Id3v2Version.V23); const data = ByteVector.concatenate( - getTestTagHeader(3, TagFlags.Unsynchronization, frame1.length), + getTestTagHeader(Id3v2Version.V23, TagFlags.Unsynchronization, frame1.length), frame1 ); SyncData.unsyncByteVector(data); @@ -189,7 +189,7 @@ const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): By @test public fromFileStart_emptyTag() { // Arrange - const data = getTestTagHeader(4, TagFlags.None, 0); + const data = getTestTagHeader(Id3v2Version.V24, TagFlags.None, 0); const file = TestFile.getFile(data); // Act @@ -204,12 +204,12 @@ const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): By @params(2, "with_offset") public fromFileStart_v4Tag(offset: number) { const frameBytes = ByteVector.concatenate( - PlayCountFrame.fromFields(BigInt(123)).render(4), - UniqueFileIdentifierFrame.fromFields("foo", ByteVector.fromUint(123)).render(4), - UnknownFrame.fromFields(FrameIdentifiers.RVRB).render(4), // Empty frame + PlayCountFrame.fromFields(BigInt(123)).render(Id3v2Version.V24), + UniqueFileIdentifierFrame.fromFields("foo", ByteVector.fromUint(123)).render(Id3v2Version.V24), + UnknownFrame.fromFields(FrameIdentifiers.RVRB).render(Id3v2Version.V24), // Empty frame ByteVector.fromSize(5) // Padding ); - const headerBytes = getTestTagHeader(4, TagFlags.None, frameBytes.length); + const headerBytes = getTestTagHeader(Id3v2Version.V24, TagFlags.None, frameBytes.length); const data = ByteVector.concatenate(ByteVector.fromSize(offset), headerBytes, frameBytes); const file = TestFile.getFile(data); @@ -280,34 +280,6 @@ const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): By assert.strictEqual(compilationFrames.length, 0); } - @test - public version_invalidValue() { - // Arrange - const tag = Id3v2Tag.fromEmpty(); - const set = (v: number) => { tag.version = v; }; - - // Act / Assert - PropertyTests.propertyThrows(set, -1); - PropertyTests.propertyThrows(set, 1.23); - PropertyTests.propertyThrows(set, 0); - PropertyTests.propertyThrows(set, 5); - PropertyTests.propertyThrows(set, 1); - } - - @test - public version_validValue() { - // Arrange - const tag = Id3v2Tag.fromEmpty(); - const set = (v: number) => { tag.version = v; }; - const get = () => tag.version; - - // Act / Assert - Id3v2Settings.forceDefaultVersion = false; - PropertyTests.propertyRoundTrip(set, get, 2); - PropertyTests.propertyRoundTrip(set, get, 3); - PropertyTests.propertyRoundTrip(set, get, 4); - } - @test public title() { this.testTextFrameProperty( @@ -708,7 +680,7 @@ const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): By public year_v4noExistingFrame() { // Arrange const tag = Id3v2Tag.fromEmpty(); - tag.version = 4; + tag.version = Id3v2Version.V24; // Act / Assert assert.strictEqual(tag.year, 0); @@ -728,7 +700,7 @@ const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): By public year_v3noExistingFrame() { // Arrange const tag = Id3v2Tag.fromEmpty(); - tag.version = 3; + tag.version = Id3v2Version.V23; // Act / Assert assert.strictEqual(tag.year, 0); @@ -1632,7 +1604,7 @@ const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): By public render_v4_noFooter() { // Arrange const tag = Id3v2Tag.fromEmpty(); - tag.version = 4; + tag.version = Id3v2Version.V24; const frame1 = TextInformationFrame.fromFields(FrameIdentifiers.TCOM); const frame2 = TextInformationFrame.fromFields(FrameIdentifiers.TCON); @@ -1643,11 +1615,11 @@ const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): By // Assert const frameBytes = ByteVector.concatenate( - frame1.render(4), - frame2.render(4), + frame1.render(Id3v2Version.V24), + frame2.render(Id3v2Version.V24), ByteVector.fromSize(1024, 0x00) ); - const header = new TagHeader(4, 0, TagFlags.None, frameBytes.length); + const header = new TagHeader(Id3v2Version.V24, 0, TagFlags.None, frameBytes.length); const expected = ByteVector.concatenate(header.render(), frameBytes); Testers.bvEqual(output, expected); @@ -1657,7 +1629,7 @@ const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): By public render_v4_hasFooter() { // Arrange const tag = Id3v2Tag.fromEmpty(); - tag.version = 4; + tag.version = Id3v2Version.V24; tag.flags = TagFlags.FooterPresent; const frame1 = TextInformationFrame.fromFields(FrameIdentifiers.TCOM); @@ -1669,10 +1641,10 @@ const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): By // Assert const frameBytes = ByteVector.concatenate( - frame1.render(4), - frame2.render(4) + frame1.render(Id3v2Version.V24), + frame2.render(Id3v2Version.V24) ); - const header = new TagHeader(4, 0, TagFlags.FooterPresent, frameBytes.length); + const header = new TagHeader(Id3v2Version.V24, 0, TagFlags.FooterPresent, frameBytes.length); const expected = ByteVector.concatenate( header.render(), frameBytes, @@ -1689,7 +1661,7 @@ const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): By const frame2 = TextInformationFrame.fromFields(FrameIdentifiers.TCON); const tag = Id3v2Tag.fromEmpty(); - tag.version = 4; + tag.version = Id3v2Version.V24; tag.flags = TagFlags.Unsynchronization; tag.frames.push(frame1, frame2); @@ -1698,11 +1670,11 @@ const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): By // Assert const frameBytes = ByteVector.concatenate( - frame1.render(4), - frame2.render(4), + frame1.render(Id3v2Version.V24), + frame2.render(Id3v2Version.V24), ByteVector.fromSize(1024) ); - const header = new TagHeader(4, 0, TagFlags.Unsynchronization, frameBytes.length); + const header = new TagHeader(Id3v2Version.V24, 0, TagFlags.Unsynchronization, frameBytes.length); const expected = ByteVector.concatenate(header.render(), frameBytes); Testers.bvEqual(output, expected); @@ -1715,7 +1687,7 @@ const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): By const frame2 = PrivateFrame.fromFields("fuxbuxqux", ByteVector.fromByteArray([0xAA, 0x12, 0x34, 0xAA])); const tag = Id3v2Tag.fromEmpty(); - tag.version = 3; + tag.version = Id3v2Version.V23; tag.flags = TagFlags.Unsynchronization; tag.frames.push(frame1, frame2); @@ -1724,11 +1696,11 @@ const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): By // Assert const frameData = SyncData.unsyncByteVector(ByteVector.concatenate( - frame1.render(3), - frame2.render(3), + frame1.render(Id3v2Version.V23), + frame2.render(Id3v2Version.V23), ByteVector.fromSize(1024) )); - const header = new TagHeader(3, 0, TagFlags.Unsynchronization, frameData.length); + const header = new TagHeader(Id3v2Version.V23, 0, TagFlags.Unsynchronization, frameData.length); const expected = ByteVector.concatenate(header.render(), frameData); Testers.bvEqual(output, expected); @@ -1738,7 +1710,7 @@ const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): By public render_v4_unsupportedFrameForVersion_disallowedViaSettings() { // Arrange const tag = Id3v2Tag.fromEmpty(); - tag.version = 4; + tag.version = Id3v2Version.V24; const originalSetting = Id3v2Settings.strictFrameForVersion; Id3v2Settings.strictFrameForVersion = true; @@ -1759,7 +1731,7 @@ const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): By public render_v4_unsupportedFrameForVersion_allowedViaSettings() { // Arrange const tag = Id3v2Tag.fromEmpty(); - tag.version = 4; + tag.version = Id3v2Version.V24; const originalSetting = Id3v2Settings.strictFrameForVersion; Id3v2Settings.strictFrameForVersion = false; @@ -1773,7 +1745,7 @@ const getTestTagHeader = (version: number, flags: TagFlags, tagSize: number): By const rehydratedTag = Id3v2Tag.fromData(bytes); // Assert - assert.strictEqual(rehydratedTag.version, 4); + assert.strictEqual(rehydratedTag.version, Id3v2Version.V24); assert.strictEqual(rehydratedTag.frames.length, 0); } finally { Id3v2Settings.strictFrameForVersion = originalSetting; From 96cd758aeb87ce8b5b03ffcc1c5cd25033ef5070 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Fri, 31 Jul 2026 00:41:00 -0500 Subject: [PATCH 10/18] AttachmentFrame --- src/id3v2/frames/attachmentFrame.ts | 18 ++--- test-unit/id3v2/attachmentsFrameTests.ts | 92 ++++++++++++------------ 2 files changed, 55 insertions(+), 55 deletions(-) diff --git a/src/id3v2/frames/attachmentFrame.ts b/src/id3v2/frames/attachmentFrame.ts index 09d7c7a5..bc57688d 100644 --- a/src/id3v2/frames/attachmentFrame.ts +++ b/src/id3v2/frames/attachmentFrame.ts @@ -2,6 +2,7 @@ import Frame from "./frame"; import FrameHeader from "./frameHeader"; import Id3v2Settings from "../id3v2Settings"; import {ByteVector, StringType} from "../../byteVector"; +import {Id3v2Version} from "../enums"; import {CorruptFileError} from "../../errors"; import {IFileAbstraction} from "../../fileAbstraction"; import {FrameIdentifiers} from "../frameIdentifiers"; @@ -17,9 +18,9 @@ export default class AttachmentFrame extends Frame implements IPicture { private _encoding: StringType = Id3v2Settings.defaultEncoding; private _filename: string; private _mimeType: string; - private _rawData: ByteVector; - private _rawPicture: IPicture; - private _rawVersion: number; + private _rawData: ByteVector|undefined; + private _rawPicture: IPicture|undefined; + private _rawVersion: Id3v2Version|undefined; private _type: PictureType; // #region Constructors @@ -34,10 +35,9 @@ export default class AttachmentFrame extends Frame implements IPicture { * @param fieldBytes Bytes that contain the fields of the frame * @param version ID3v2 version the frame was originally encoded with */ - public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: number): AttachmentFrame { + public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: Id3v2Version): AttachmentFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); - Guards.byte(version, "version"); if (fieldBytes.length < 5) { throw new CorruptFileError("A picture frame must contain at least 5 bytes"); @@ -82,7 +82,7 @@ export default class AttachmentFrame extends Frame implements IPicture { header: FrameHeader, frameStart: number, size: number, - version: number + version: Id3v2Version ): AttachmentFrame { Guards.truthy(file, "file"); Guards.truthy(header, "header"); @@ -272,7 +272,7 @@ export default class AttachmentFrame extends Frame implements IPicture { // #endregion /** @inheritDoc */ - protected renderFields(version: number): ByteVector { + protected renderFields(version: Id3v2Version): ByteVector { this.parseFromRaw(); const encoding = AttachmentFrame.correctEncoding(this.textEncoding, version); @@ -281,7 +281,7 @@ export default class AttachmentFrame extends Frame implements IPicture { if (this.frameId === FrameIdentifiers.APIC) { // Render an ID3v2 attached picture let extensionData; - if (version === 2) { + if (version === Id3v2Version.V22) { let ext = Picture.getExtensionFromMimeType(this.mimeType); ext = ext && ext.length >= 3 ? ext.substring(ext.length - 3).toUpperCase() : "XXX"; extensionData = ByteVector.fromString(ext, StringType.Latin1); @@ -340,7 +340,7 @@ export default class AttachmentFrame extends Frame implements IPicture { // @TODO: Maybe make two different classes? if (this.frameId === FrameIdentifiers.APIC) { // Retrieve an ID3v2 attached picture - if (this._rawVersion > 2) { + if (this._rawVersion !== Id3v2Version.V22) { // Text encoding $xx // MIME type $00 // Picture type $xx diff --git a/test-unit/id3v2/attachmentsFrameTests.ts b/test-unit/id3v2/attachmentsFrameTests.ts index 74cbc456..606f3b77 100644 --- a/test-unit/id3v2/attachmentsFrameTests.ts +++ b/test-unit/id3v2/attachmentsFrameTests.ts @@ -10,7 +10,7 @@ import Id3v2Settings from "../../src/id3v2/id3v2Settings"; import PropertyTests from "../utilities/propertyTests"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {FrameFlags} from "../../src/id3v2/enums"; +import {FrameFlags, Id3v2Version} from "../../src/id3v2/enums"; import {FrameIdentifier, FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {IPicture, Picture, PictureType} from "../../src/picture"; import {Testers} from "../utilities/testers"; @@ -65,7 +65,7 @@ const verifyFrame = ( } @suite class Id3v2_AttachmentFrame_ConstructorTests extends FrameConstructorTests { - get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { + get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: Id3v2Version) => Frame { return AttachmentFrame.fromFieldBytes; } @@ -134,9 +134,9 @@ const verifyFrame = ( // the first byte of the picture is 0, which we want to make sure isn't mistaken for the end // of the mimetype. - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_apicV34_latin1Encoding(version: number) { + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_apicV34_latin1Encoding(version: Id3v2Version) { // Arrange const testData = ByteVector.fromString("fuxbuxqux", StringType.Latin1); const fieldBytes = ByteVector.concatenate( @@ -166,9 +166,9 @@ const verifyFrame = ( ); } - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_apicV34_nonLatinEncoding(version: number) { + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_apicV34_nonLatinEncoding(version: Id3v2Version) { // Arrange const testData = ByteVector.fromString("fuxbuxqux", StringType.Latin1); const fieldBytes = ByteVector.concatenate( @@ -229,10 +229,10 @@ const verifyFrame = ( ); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_geob_latinEncoding(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_geob_latinEncoding(version: Id3v2Version) { // Arrange const testData = ByteVector.fromString("fuxbuxqux", StringType.Latin1); const fieldBytes = ByteVector.concatenate( @@ -263,10 +263,10 @@ const verifyFrame = ( ); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_geob_nonLatinEncoding(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_geob_nonLatinEncoding(version: Id3v2Version) { // Arrange const testData = ByteVector.fromString("fuxbuxqux", StringType.Latin1); const fieldBytes = ByteVector.concatenate( @@ -451,7 +451,7 @@ const verifyFrame = ( testData // Picture bytes ); const header = new FrameHeader(FrameIdentifiers.APIC, FrameFlags.None, fieldBytes.length); - const frame = AttachmentFrame.fromFieldBytes(header, fieldBytes, 4); + const frame = AttachmentFrame.fromFieldBytes(header, fieldBytes, Id3v2Version.V24); // Act const output = frame.clone(); @@ -590,7 +590,7 @@ const verifyFrame = ( const frame = getCustomTestFrame(data, "foo", "bar", "this/is_not/a_mimetype", PictureType.FrontCover); // Act - const output = frame.render(2); + const output = frame.render(Id3v2Version.V22); // Assert const fieldBytes = ByteVector.concatenate( @@ -602,7 +602,7 @@ const verifyFrame = ( data // Picture bytes ); const header = new FrameHeader(FrameIdentifiers.APIC, FrameFlags.None, fieldBytes.length); - const expected = ByteVector.concatenate(header.render(2), fieldBytes); + const expected = ByteVector.concatenate(header.render(Id3v2Version.V22), fieldBytes); Testers.bvEqual(output, expected); } @@ -613,7 +613,7 @@ const verifyFrame = ( const frame = getCustomTestFrame(data, "foo", "bar", "image/gif", PictureType.FrontCover); // Act - const output = frame.render(2); + const output = frame.render(Id3v2Version.V22); // Assert const fieldBytes = ByteVector.concatenate( @@ -625,7 +625,7 @@ const verifyFrame = ( data // Picture bytes ); const header = new FrameHeader(FrameIdentifiers.APIC, FrameFlags.None, fieldBytes.length); - const expected = ByteVector.concatenate(header.render(2), fieldBytes); + const expected = ByteVector.concatenate(header.render(Id3v2Version.V22), fieldBytes); Testers.bvEqual(output, expected); } @@ -636,7 +636,7 @@ const verifyFrame = ( const frame = getCustomTestFrame(data, "foo", "bar", "image/gif", PictureType.FrontCover); // Act - const output = frame.render(3); + const output = frame.render(Id3v2Version.V23); // Assert const fieldBytes = ByteVector.concatenate( @@ -649,7 +649,7 @@ const verifyFrame = ( data // Picture bytes ); const header = new FrameHeader(FrameIdentifiers.APIC, FrameFlags.None, fieldBytes.length); - const expected = ByteVector.concatenate(header.render(3), fieldBytes); + const expected = ByteVector.concatenate(header.render(Id3v2Version.V23), fieldBytes); Testers.bvEqual(output, expected); } @@ -660,7 +660,7 @@ const verifyFrame = ( const frame = getCustomTestFrame(data, "foo", "bar", "image/gif", PictureType.FrontCover); // Act - const output = frame.render(4); + const output = frame.render(Id3v2Version.V24); // Assert const fieldBytes = ByteVector.concatenate( @@ -673,13 +673,13 @@ const verifyFrame = ( data // Picture bytes ); const header = new FrameHeader(FrameIdentifiers.APIC, FrameFlags.None, fieldBytes.length); - const expected = ByteVector.concatenate(header.render(4), fieldBytes); + const expected = ByteVector.concatenate(header.render(Id3v2Version.V24), fieldBytes); Testers.bvEqual(output, expected); } - @params(2, "v2") - @params(3, "v3") - public render_geobWithoutMimeType_v23(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + public render_geobWithoutMimeType_v23(version: Id3v2Version) { // Arrange const data = ByteVector.fromString("fuxbuxqux", StringType.UTF8); const frame = getCustomTestFrame(data, undefined, undefined, undefined, PictureType.NotAPicture); @@ -707,7 +707,7 @@ const verifyFrame = ( const frame = getCustomTestFrame(data, undefined, undefined, undefined, PictureType.NotAPicture); // Act - const output = frame.render(4); + const output = frame.render(Id3v2Version.V24); // Assert const fieldBytes = ByteVector.concatenate(Id3v2Settings.defaultEncoding, @@ -717,13 +717,13 @@ const verifyFrame = ( data // Attachment bytes ); const header = new FrameHeader(FrameIdentifiers.GEOB, FrameFlags.None, fieldBytes.length); - const expected = ByteVector.concatenate(header.render(4), fieldBytes); + const expected = ByteVector.concatenate(header.render(Id3v2Version.V24), fieldBytes); Testers.bvEqual(output, expected); } - @params(2, "v2") - @params(3, "v3") - public render_geobWithMimeType_v23(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + public render_geobWithMimeType_v23(version: Id3v2Version) { // Arrange const data = ByteVector.fromString("fuxbuxqux", StringType.UTF8); const frame = getCustomTestFrame(data, undefined, undefined, "image/gif", PictureType.NotAPicture); @@ -752,7 +752,7 @@ const verifyFrame = ( const frame = getCustomTestFrame(data, undefined, undefined, "image/gif", PictureType.NotAPicture); // Act - const output = frame.render(4); + const output = frame.render(Id3v2Version.V24); // Assert const fieldBytes = ByteVector.concatenate( @@ -764,13 +764,13 @@ const verifyFrame = ( data // Attachment bytes ); const header = new FrameHeader(FrameIdentifiers.GEOB, FrameFlags.None, fieldBytes.length); - const expected = ByteVector.concatenate(header.render(4), fieldBytes); + const expected = ByteVector.concatenate(header.render(Id3v2Version.V24), fieldBytes); Testers.bvEqual(output, expected); } - @params(2, "v2") - @params(3, "v3") - public render_geobWithMimeTypeAndFileName_v23(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + public render_geobWithMimeTypeAndFileName_v23(version: Id3v2Version) { // Arrange const data = ByteVector.fromString("fuxbuxqux", StringType.UTF8); const frame = getCustomTestFrame(data, undefined, "file.gif", "image/gif", PictureType.NotAPicture); @@ -800,7 +800,7 @@ const verifyFrame = ( const frame = getCustomTestFrame(data, undefined, "file.gif", "image/gif", PictureType.NotAPicture); // Act - const output = frame.render(4); + const output = frame.render(Id3v2Version.V24); // Assert const fieldBytes = ByteVector.concatenate( @@ -813,13 +813,13 @@ const verifyFrame = ( data // Attachment bytes ) const header = new FrameHeader(FrameIdentifiers.GEOB, FrameFlags.None, fieldBytes.length); - const expected = ByteVector.concatenate(header.render(4), fieldBytes); + const expected = ByteVector.concatenate(header.render(Id3v2Version.V24), fieldBytes); Testers.bvEqual(output, expected); } - @params(2, "v2") - @params(3, "v3") - public render_geobWithMimeTypeAndFileNameAndDescription_v23(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + public render_geobWithMimeTypeAndFileNameAndDescription_v23(version: Id3v2Version) { // Arrange const data = ByteVector.fromString("fuxbuxqux", StringType.UTF8); const frame = getCustomTestFrame(data, "foobarbaz", "file.gif", "image/gif", PictureType.NotAPicture); @@ -843,14 +843,14 @@ const verifyFrame = ( Testers.bvEqual(output, expected); } - @params(4, "v4") + @test public render_geobWithMimeTypeAndFileNameAndDescription_v4() { // Arrange const data = ByteVector.fromString("fuxbuxqux", StringType.UTF8); const frame = getCustomTestFrame(data, "foobarbaz", "file.gif", "image/gif", PictureType.NotAPicture); // Act - const output = frame.render(4); + const output = frame.render(Id3v2Version.V24); // Assert const fieldBytes = ByteVector.concatenate( @@ -864,7 +864,7 @@ const verifyFrame = ( data // Attachment bytes ); const header = new FrameHeader(FrameIdentifiers.GEOB, FrameFlags.None, fieldBytes.length); - const expected = ByteVector.concatenate(header.render(4), fieldBytes); + const expected = ByteVector.concatenate(header.render(Id3v2Version.V24), fieldBytes); Testers.bvEqual(output, expected); } } From 558107cd23ca2a50de25677018ccd7f95a6a0785 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Sun, 2 Aug 2026 14:50:57 -0400 Subject: [PATCH 11/18] CommentsFrame --- src/id3v2/frames/commentsFrame.ts | 8 +-- test-unit/id3v2/commentsFrameTests.ts | 72 +++++++++++++-------------- 2 files changed, 40 insertions(+), 40 deletions(-) diff --git a/src/id3v2/frames/commentsFrame.ts b/src/id3v2/frames/commentsFrame.ts index 514b733d..4f7cff05 100644 --- a/src/id3v2/frames/commentsFrame.ts +++ b/src/id3v2/frames/commentsFrame.ts @@ -2,6 +2,7 @@ import Frame from "./frame"; import FrameHeader from "./frameHeader"; import Id3v2Settings from "../id3v2Settings"; import {ByteVector, StringType} from "../../byteVector"; +import {Id3v2Version} from "../enums"; import {CorruptFileError} from "../../errors"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; @@ -26,12 +27,11 @@ export default class CommentsFrame extends Frame { * Constructs and initializes a new instance by parsing the fields from the field bytes. * @param header Header of the frame * @param fieldBytes Bytes that contain the fields of the frame - * @param version ID3v2 version the frame was originally encoded with + * @param _version ID3v2 version the frame was originally encoded with */ - public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: number): CommentsFrame { + public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, _version: Id3v2Version): CommentsFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); - Guards.byte(version, "version"); if (fieldBytes.length < 4) { throw new CorruptFileError("Comment frame must contain at least 4 bytes."); @@ -168,7 +168,7 @@ export default class CommentsFrame extends Frame { return this.text; } - protected renderFields(version: number): ByteVector { + protected renderFields(version: Id3v2Version): ByteVector { const encoding = Frame.correctEncoding(this.textEncoding, version); return ByteVector.concatenate( encoding, diff --git a/test-unit/id3v2/commentsFrameTests.ts b/test-unit/id3v2/commentsFrameTests.ts index 801d27cb..788e7705 100644 --- a/test-unit/id3v2/commentsFrameTests.ts +++ b/test-unit/id3v2/commentsFrameTests.ts @@ -9,7 +9,7 @@ import Id3v2Settings from "../../src/id3v2/id3v2Settings"; import PropertyTests from "../utilities/propertyTests"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {FrameFlags} from "../../src/id3v2/enums"; +import {FrameFlags, Id3v2Version} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -31,14 +31,14 @@ const verifyFrame = ( } @suite class Id3v2_CommentsFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: FrameHeader, fb: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, fb: ByteVector, v: Id3v2Version) => Frame { return CommentsFrame.fromFieldBytes; } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_tooFewBytes_throws(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_tooFewBytes_throws(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.fromByte(StringType.Latin1); const header = new FrameHeader(FrameIdentifiers.COMM, FrameFlags.None, fieldBytes.length); @@ -47,10 +47,10 @@ const verifyFrame = ( assert.throws(() => { CommentsFrame.fromFieldBytes(header, fieldBytes, version); }); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_requiredBytesOnly(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_requiredBytesOnly(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.Latin1, // Encoding @@ -66,10 +66,10 @@ const verifyFrame = ( verifyFrame(frame, "", "eng", StringType.Latin1, ""); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_descriptionOnly(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_descriptionOnly(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.Latin1, // Encoding @@ -86,10 +86,10 @@ const verifyFrame = ( verifyFrame(frame, "", "eng", StringType.Latin1, "fux"); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_commentsOnly(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_commentsOnly(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.Latin1, // Encoding @@ -107,10 +107,10 @@ const verifyFrame = ( verifyFrame(frame, "", "eng", StringType.Latin1, "fux"); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_descriptionAndComments(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_descriptionAndComments(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.Latin1, // Encoding @@ -142,7 +142,7 @@ const verifyFrame = ( const header = new FrameHeader(FrameIdentifiers.COMM, FrameFlags.None, fieldBytes.length); // Act - const frame = CommentsFrame.fromFieldBytes(header, fieldBytes, 4); + const frame = CommentsFrame.fromFieldBytes(header, fieldBytes, Id3v2Version.V24); // Assert verifyFrame(frame, "fux", "eng", encoding, "bux"); @@ -334,12 +334,12 @@ const verifyFrame = ( verifyFrame(output, frame.description, frame.language, frame.textEncoding, frame.text); } - @params([2, StringType.Latin1], "v2_single_byte") - @params([2, StringType.UTF16BE], "v2_multibyte") - @params([3, StringType.Latin1], "v3_single_byte") - @params([3, StringType.UTF16BE], "v3_multibyte") - @params([4, StringType.Latin1], "v4_single_byte") - @params([4, StringType.UTF16BE], "v4_multibyte") + @params([Id3v2Version.V22, StringType.Latin1], "v2_single_byte") + @params([Id3v2Version.V22, StringType.UTF16BE], "v2_multibyte") + @params([Id3v2Version.V23, StringType.Latin1], "v3_single_byte") + @params([Id3v2Version.V23, StringType.UTF16BE], "v3_multibyte") + @params([Id3v2Version.V24, StringType.Latin1], "v4_single_byte") + @params([Id3v2Version.V24, StringType.UTF16BE], "v4_multibyte") public render([version, encoding]: [number, StringType]) { // Arrange const frame = CommentsFrame.fromFields("bar", "foo", "eng", encoding); @@ -362,9 +362,9 @@ const verifyFrame = ( Testers.bvEqual(output, expectedBytes); } - @params([2, StringType.UTF16], "v2") - @params([3, StringType.UTF16], "v3") - @params([4, StringType.UTF8], "v4") + @params([Id3v2Version.V22, StringType.UTF16], "v2") + @params([Id3v2Version.V23, StringType.UTF16], "v3") + @params([Id3v2Version.V24, StringType.UTF8], "v4") public render_utf8([version, outputEncoding]: [number, StringType]) { // Arrange const frame = CommentsFrame.fromFields("bar", "foo", "eng", StringType.UTF8); @@ -393,7 +393,7 @@ const verifyFrame = ( const frame = CommentsFrame.fromFields("foo", "", "eng", StringType.Latin1); // Act - const result = frame.render(4); + const result = frame.render(Id3v2Version.V24); // Assert assert.isOk(result); @@ -405,7 +405,7 @@ const verifyFrame = ( ByteVector.getTextDelimiter(StringType.Latin1), // Delimiter ); const header = new FrameHeader(FrameIdentifiers.COMM, FrameFlags.None, expectedFieldBytes.length); - const expectedBytes = ByteVector.concatenate(header.render(4), expectedFieldBytes); + const expectedBytes = ByteVector.concatenate(header.render(Id3v2Version.V24), expectedFieldBytes); Testers.bvEqual(result, expectedBytes); } @@ -415,7 +415,7 @@ const verifyFrame = ( const frame = CommentsFrame.fromFields("", "foo", "eng", StringType.Latin1); // Act - const result = frame.render(4); + const result = frame.render(Id3v2Version.V24); // Assert assert.isOk(result); @@ -427,7 +427,7 @@ const verifyFrame = ( ByteVector.fromString("foo", StringType.Latin1), // Comment text ); const header = new FrameHeader(FrameIdentifiers.COMM, FrameFlags.None, expectedFieldBytes.length); - const expectedBytes = ByteVector.concatenate(header.render(4), expectedFieldBytes); + const expectedBytes = ByteVector.concatenate(header.render(Id3v2Version.V24), expectedFieldBytes); Testers.bvEqual(result, expectedBytes); } } From 8ad80072571643967b58d7f268756c50b39e1864 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Sun, 2 Aug 2026 15:12:26 -0400 Subject: [PATCH 12/18] EventTimeCodeFrame --- src/id3v2/frames/eventTimeCodeFrame.ts | 7 ++-- test-unit/id3v2/eventTimeCodeFrameTests.ts | 48 +++++++++++----------- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/id3v2/frames/eventTimeCodeFrame.ts b/src/id3v2/frames/eventTimeCodeFrame.ts index 9fd987f0..cf5ba2b8 100644 --- a/src/id3v2/frames/eventTimeCodeFrame.ts +++ b/src/id3v2/frames/eventTimeCodeFrame.ts @@ -1,7 +1,7 @@ import Frame from "./frame"; import FrameHeader from "./frameHeader"; import {ByteVector} from "../../byteVector"; -import {EventType, FrameFlags, TimestampFormat} from "../enums"; +import {EventType, FrameFlags, Id3v2Version, TimestampFormat} from "../enums"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; import {CorruptFileError} from "../../errors"; @@ -93,16 +93,15 @@ export class EventTimeCodeFrame extends Frame { * Constructs and initializes a new instance by parsing the fields from the field bytes. * @param header Header of the frame * @param fieldBytes Bytes that contain the fields of the frame - * @param version ID3v2 version the frame was originally encoded with + * @param _version */ public static fromFieldBytes( header: FrameHeader, fieldBytes: ByteVector, - version: number + _version: Id3v2Version ): EventTimeCodeFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); - Guards.byte(version, "version"); if (fieldBytes.length < 1) { throw new CorruptFileError("Event time code frame must contain at least 1 byte."); diff --git a/test-unit/id3v2/eventTimeCodeFrameTests.ts b/test-unit/id3v2/eventTimeCodeFrameTests.ts index a3dfe4f4..f225fd16 100644 --- a/test-unit/id3v2/eventTimeCodeFrameTests.ts +++ b/test-unit/id3v2/eventTimeCodeFrameTests.ts @@ -7,7 +7,7 @@ import FrameHeader from "../../src/id3v2/frames/frameHeader"; import PropertyTests from "../utilities/propertyTests"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector} from "../../src/byteVector"; -import {EventType, FrameFlags, TimestampFormat} from "../../src/id3v2/enums"; +import {EventType, FrameFlags, Id3v2Version, TimestampFormat} from "../../src/id3v2/enums"; import {EventTimeCode, EventTimeCodeFrame} from "../../src/id3v2/frames/eventTimeCodeFrame"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -99,14 +99,14 @@ const assertFrame = (frame: EventTimeCodeFrame, e: EventTimeCode[], t: Timestamp } @suite class Id3v2_EventTimeCodeFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: Id3v2Version) => Frame { return EventTimeCodeFrame.fromFieldBytes; } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_notEnoughBytes(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_notEnoughBytes(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.empty(); const header = new FrameHeader(FrameIdentifiers.ETCO, FrameFlags.None, fieldBytes.length); @@ -115,10 +115,10 @@ const assertFrame = (frame: EventTimeCodeFrame, e: EventTimeCode[], t: Timestamp assert.throws(() => { EventTimeCodeFrame.fromFieldBytes(header, fieldBytes, version); }); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_noEvents(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_noEvents(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.fromByte(TimestampFormat.AbsoluteMilliseconds); const header = new FrameHeader(FrameIdentifiers.ETCO, FrameFlags.None, fieldBytes.length); @@ -130,9 +130,9 @@ const assertFrame = (frame: EventTimeCodeFrame, e: EventTimeCode[], t: Timestamp assertFrame(frame, [], TimestampFormat.AbsoluteMilliseconds); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") public fromFieldBytes_withEvents(version: number) { // Arrange const event1 = new EventTimeCode(EventType.Profanity, 123); @@ -151,9 +151,9 @@ const assertFrame = (frame: EventTimeCodeFrame, e: EventTimeCode[], t: Timestamp assertFrame(frame, [event1, event2], TimestampFormat.AbsoluteMilliseconds); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") public fromFieldBytes_incompleteEvent(version: number) { // Arrange const event1 = new EventTimeCode(EventType.Profanity, 123); @@ -323,10 +323,10 @@ const assertFrame = (frame: EventTimeCodeFrame, e: EventTimeCode[], t: Timestamp assert.deepEqual(result, [frame1, frame2]); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public render_withoutEvents(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public render_withoutEvents(version: Id3v2Version) { // Arrange const frame = EventTimeCodeFrame.fromFields(); frame.timestampFormat = TimestampFormat.AbsoluteMpegFrames; @@ -348,10 +348,10 @@ const assertFrame = (frame: EventTimeCodeFrame, e: EventTimeCode[], t: Timestamp Testers.bvEqual(output, expected); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public render_withEvents(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public render_withEvents(version: Id3v2Version) { // Arrange const event1 = new EventTimeCode(EventType.Profanity, 123); const event2 = new EventTimeCode(EventType.KeyChange, 456); From ae55bafb511b84de4522660160c55f6f38c7a717 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Sat, 8 Aug 2026 13:30:14 -0500 Subject: [PATCH 13/18] GenreFrame --- src/id3v2/frames/genreFrame.ts | 12 +- test-unit/id3v2/genreFrameTests.ts | 264 +++++++++++++++-------------- 2 files changed, 142 insertions(+), 134 deletions(-) diff --git a/src/id3v2/frames/genreFrame.ts b/src/id3v2/frames/genreFrame.ts index e9431310..3aaa7e69 100644 --- a/src/id3v2/frames/genreFrame.ts +++ b/src/id3v2/frames/genreFrame.ts @@ -3,6 +3,7 @@ import FrameHeader from "./frameHeader"; import Genres from "../../genres"; import Id3v2Settings from "../id3v2Settings"; import {ByteVector, StringType} from "../../byteVector"; +import {Id3v2Version} from "../enums"; import {CorruptFileError} from "../../errors"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards, StringUtils} from "../../utils"; @@ -31,10 +32,9 @@ export default class GenreFrame extends Frame { * @param fieldBytes Bytes that contain the fields of the frame * @param version ID3v2 version the frame was originally encoded with */ - public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: number): GenreFrame { + public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: Id3v2Version): GenreFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); - Guards.byte(version, "version"); if (fieldBytes.length < 1) { throw new CorruptFileError("Genre frame must contain at least 1 byte."); @@ -48,7 +48,7 @@ export default class GenreFrame extends Frame { frame._encoding = fieldBytes.get(0); const fieldList = []; - if (version > 3) { + if (version === Id3v2Version.V24) { // TCON on ID3v2.4 is encoded as a separate field for each genre. Fields can either be // the old numeric ID3v1 genres (no parenthesis) or free text. RX/CR can also be used. const genres = fieldBytes.subarray(1).toStrings(frame._encoding); @@ -182,14 +182,14 @@ export default class GenreFrame extends Frame { // #region Protected Methods /** @inheritDoc */ - protected renderFields(version: number): ByteVector { + protected renderFields(version: Id3v2Version): ByteVector { const encoding = GenreFrame.correctEncoding(this.textEncoding, version); const v = ByteVector.empty(); let text = this._textFields; v.addByte(encoding); - if (version > 3) { + if (version === Id3v2Version.V24) { // For ID3v2.4, we should encode any genres that can be numeric as numeric by // themselves. This then gets encoded the same as any other ID3v2.4 text frame (ie, // with delimiters in between values) @@ -221,7 +221,7 @@ export default class GenreFrame extends Frame { } } else { // ID3v2.2 and ID3v2.3 TCON frames are going to be written with numeric genres first - // (if enabled) and multiple text-based genres separated by ;. + // (if enabled) and multiple text-based genres separated by `;`. // NOTE: This doesn't follow the actual conventions for ID3v2.2/3 but nobody does this // correctly. This implementation will at least work with MinimServer // https://forum.minimserver.com/showthread.php?tid=2575 diff --git a/test-unit/id3v2/genreFrameTests.ts b/test-unit/id3v2/genreFrameTests.ts index 025ea860..3e8429eb 100644 --- a/test-unit/id3v2/genreFrameTests.ts +++ b/test-unit/id3v2/genreFrameTests.ts @@ -8,7 +8,7 @@ import GenreFrame from "../../src/id3v2/frames/genreFrame"; import Id3v2Settings from "../../src/id3v2/id3v2Settings"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {FrameFlags} from "../../src/id3v2/enums"; +import {FrameFlags, Id3v2Version} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -83,15 +83,15 @@ class Id3v2_GenreFrameTests extends FrameConstructorTests { // region Parse Tests - @params(2, "v2") - @params(3, "v3") - public parse_v23_emptyFrame(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + public parse_v23_emptyFrame(version: Id3v2Version) { this.testFrameParse(version, ByteVector.concatenate(StringType.UTF16BE), []); } - @params(2, "v2") - @params(3, "v3") - public parse_v23_StartsWithDelimiter(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + public parse_v23_StartsWithDelimiter(version: Id3v2Version) { const payload = ByteVector.concatenate( StringType.UTF16BE, ByteVector.getTextDelimiter(StringType.UTF16BE), @@ -101,86 +101,88 @@ class Id3v2_GenreFrameTests extends FrameConstructorTests { this.testFrameParse(version, payload, []); } - @params([2, "Classical", ["Classical"]], "string_v2") - @params([3, "Classical", ["Classical"]], "string_v3") - @params([2, "(foo)", ["(foo)"]], "invalidParentheses_v2") - @params([3, "(foo)", ["(foo)"]], "invalidParentheses_v3") - public parse_v23_singleTerm_general([version, input, output]: [number, string, string[]]) { + @params([Id3v2Version.V22, "Classical", ["Classical"]], "string_v2") + @params([Id3v2Version.V23, "Classical", ["Classical"]], "string_v3") + @params([Id3v2Version.V22, "(foo)", ["(foo)"]], "invalidParentheses_v2") + @params([Id3v2Version.V23, "(foo)", ["(foo)"]], "invalidParentheses_v3") + public parse_v23_singleTerm_general([version, input, output]: [Id3v2Version, string, string[]]) { this.testFrameParse(version, input, output); } - @params([2, "(32)", ["Classical"]], "v2") - @params([3, "(32)", ["Classical"]], "v3") - @params([2, "(32)foo", ["Classical foo"]], "Refinement_v2") - @params([3, "(32)foo", ["Classical foo"]], "Refinement_v3") - @params([2, "(32)f((oo", ["Classical f(oo"]], "Refinement_Escaped_v2") - @params([3, "(32)f((oo", ["Classical f(oo"]], "Refinement_Escaped_v3") - @params([2, "(32)f(oo", ["Classical f(oo"]], "Refinement_Unescaped_v2") - @params([3, "(32)f(oo", ["Classical f(oo"]], "Refinement_Unescaped_v3") - public parse_v23_singleTerm_oneStandardNumber([version, input, output]: [number, string, string[]]) { + @params([Id3v2Version.V22, "(32)", ["Classical"]], "v2") + @params([Id3v2Version.V23, "(32)", ["Classical"]], "v3") + @params([Id3v2Version.V22, "(32)foo", ["Classical foo"]], "Refinement_v2") + @params([Id3v2Version.V23, "(32)foo", ["Classical foo"]], "Refinement_v3") + @params([Id3v2Version.V22, "(32)f((oo", ["Classical f(oo"]], "Refinement_Escaped_v2") + @params([Id3v2Version.V23, "(32)f((oo", ["Classical f(oo"]], "Refinement_Escaped_v3") + @params([Id3v2Version.V22, "(32)f(oo", ["Classical f(oo"]], "Refinement_Unescaped_v2") + @params([Id3v2Version.V23, "(32)f(oo", ["Classical f(oo"]], "Refinement_Unescaped_v3") + public parse_v23_singleTerm_oneStandardNumber([version, input, output]: [Id3v2Version, string, string[]]) { this.testFrameParse(version, input, output); } - @params([2, "(32)(33)", ["Classical", "Instrumental"]], "v2") - @params([3, "(32)(33)", ["Classical", "Instrumental"]], "v2") - @params([2, "(32)foo(33)", ["Classical foo", "Instrumental"]], "1stRefinement_v2") - @params([3, "(32)foo(33)", ["Classical foo", "Instrumental"]], "1stRefinement_v3") - @params([2, "(32)f((oo(33)", ["Classical f(oo", "Instrumental"]], "1stRefinement_Escaped_v2") - @params([3, "(32)f((oo(33)", ["Classical f(oo", "Instrumental"]], "1stRefinement_Escaped_v3") - @params([2, "(32)f(oo(33)", ["Classical f(oo(33)"]], "1stRefinement_Unescaped_v2") - @params([3, "(32)f(oo(33)", ["Classical f(oo(33)"]], "1stRefinement_Unescaped_v3") - @params([2, "(32)(33)bar", ["Classical", "Instrumental bar"]], "2ndRefinement_v2") - @params([3, "(32)(33)bar", ["Classical", "Instrumental bar"]], "2ndRefinement_v3") - @params([2, "(32)(33)b((ar", ["Classical", "Instrumental b(ar"]], "2ndRefinement_Escaped_v2") - @params([3, "(32)(33)b((ar", ["Classical", "Instrumental b(ar"]], "2ndRefinement_Escaped_v3") - @params([2, "(32)(33)b(ar", ["Classical", "Instrumental b(ar"]], "2ndRefinement_Unescaped_v2") - @params([3, "(32)(33)b(ar", ["Classical", "Instrumental b(ar"]], "2ndRefinement_Unescaped_v3") - @params([2, "(32)foo(33)bar", ["Classical foo", "Instrumental bar"]], "BothRefinement_v2") - @params([3, "(32)foo(33)bar", ["Classical foo", "Instrumental bar"]], "BothRefinement_v3") - @params([2, "(32)f((oo(33)b((ar", ["Classical f(oo", "Instrumental b(ar"]], "BothRefinement_Escaped_v2") - @params([3, "(32)f((oo(33)b((ar", ["Classical f(oo", "Instrumental b(ar"]], "BothRefinement_Escaped_v3") - @params([2, "(32)f(oo(33)b(ar", ["Classical f(oo(33)b(ar"]], "BothRefinement_Unescaped_v2") - @params([3, "(32)f(oo(33)b(ar", ["Classical f(oo(33)b(ar"]], "BothRefinement_Unescaped_v3") - public parse_v23_singleTerm_multipleStandardNumber([version, input, output]: [number, string, string[]]) { + /* eslint-disable max-len */ + @params([Id3v2Version.V22, "(32)(33)", ["Classical", "Instrumental"]], "v2") + @params([Id3v2Version.V23, "(32)(33)", ["Classical", "Instrumental"]], "v2") + @params([Id3v2Version.V22, "(32)foo(33)", ["Classical foo", "Instrumental"]], "1stRefinement_v2") + @params([Id3v2Version.V23, "(32)foo(33)", ["Classical foo", "Instrumental"]], "1stRefinement_v3") + @params([Id3v2Version.V22, "(32)f((oo(33)", ["Classical f(oo", "Instrumental"]], "1stRefinement_Escaped_v2") + @params([Id3v2Version.V23, "(32)f((oo(33)", ["Classical f(oo", "Instrumental"]], "1stRefinement_Escaped_v3") + @params([Id3v2Version.V22, "(32)f(oo(33)", ["Classical f(oo(33)"]], "1stRefinement_Unescaped_v2") + @params([Id3v2Version.V23, "(32)f(oo(33)", ["Classical f(oo(33)"]], "1stRefinement_Unescaped_v3") + @params([Id3v2Version.V22, "(32)(33)bar", ["Classical", "Instrumental bar"]], "2ndRefinement_v2") + @params([Id3v2Version.V23, "(32)(33)bar", ["Classical", "Instrumental bar"]], "2ndRefinement_v3") + @params([Id3v2Version.V22, "(32)(33)b((ar", ["Classical", "Instrumental b(ar"]], "2ndRefinement_Escaped_v2") + @params([Id3v2Version.V23, "(32)(33)b((ar", ["Classical", "Instrumental b(ar"]], "2ndRefinement_Escaped_v3") + @params([Id3v2Version.V22, "(32)(33)b(ar", ["Classical", "Instrumental b(ar"]], "2ndRefinement_Unescaped_v2") + @params([Id3v2Version.V23, "(32)(33)b(ar", ["Classical", "Instrumental b(ar"]], "2ndRefinement_Unescaped_v3") + @params([Id3v2Version.V22, "(32)foo(33)bar", ["Classical foo", "Instrumental bar"]], "BothRefinement_v2") + @params([Id3v2Version.V23, "(32)foo(33)bar", ["Classical foo", "Instrumental bar"]], "BothRefinement_v3") + @params([Id3v2Version.V22, "(32)f((oo(33)b((ar", ["Classical f(oo", "Instrumental b(ar"]], "BothRefinement_Escaped_v2") + @params([Id3v2Version.V23, "(32)f((oo(33)b((ar", ["Classical f(oo", "Instrumental b(ar"]], "BothRefinement_Escaped_v3") + @params([Id3v2Version.V22, "(32)f(oo(33)b(ar", ["Classical f(oo(33)b(ar"]], "BothRefinement_Unescaped_v2") + @params([Id3v2Version.V23, "(32)f(oo(33)b(ar", ["Classical f(oo(33)b(ar"]], "BothRefinement_Unescaped_v3") + /* eslint-enable max-len */ + public parse_v23_singleTerm_multipleStandardNumber([version, input, output]: [Id3v2Version, string, string[]]) { this.testFrameParse(version, input, output); } - @params([2, "(CR)", ["Cover"]], "Single_v2") - @params([3, "(CR)", ["Cover"]], "Single_v3") - @params([2, "(RX)", ["Remix"]], "Single_v2") - @params([3, "(RX)", ["Remix"]], "Single_v3") - @params([2, "(CR)(RX)", ["Cover", "Remix"]], "Multiple_v2") - @params([3, "(CR)(RX)", ["Cover", "Remix"]], "Multiple_v3") - @params([2, "(CR)f((oo(RX)b((ar", ["Cover f(oo", "Remix b(ar"]], "Multiple_EscapedRefinement_v2") - @params([3, "(CR)f((oo(RX)b((ar", ["Cover f(oo", "Remix b(ar"]], "Multiple_EscapedRefinement_v3") - @params([2, "(CR)f(oo(RX)b(ar", ["Cover f(oo(RX)b(ar"]], "Multiple_UnescapedRefinement_v2") - @params([3, "(CR)f(oo(RX)b(ar", ["Cover f(oo(RX)b(ar"]], "Multiple_UnescapedRefinement_v3") - public parse_v23_singleTerm_remixCover([version, input, output]: [number, string, string[]]) { + @params([Id3v2Version.V22, "(CR)", ["Cover"]], "Single_v2") + @params([Id3v2Version.V23, "(CR)", ["Cover"]], "Single_v3") + @params([Id3v2Version.V22, "(RX)", ["Remix"]], "Single_v2") + @params([Id3v2Version.V23, "(RX)", ["Remix"]], "Single_v3") + @params([Id3v2Version.V22, "(CR)(RX)", ["Cover", "Remix"]], "Multiple_v2") + @params([Id3v2Version.V23, "(CR)(RX)", ["Cover", "Remix"]], "Multiple_v3") + @params([Id3v2Version.V22, "(CR)f((oo(RX)b((ar", ["Cover f(oo", "Remix b(ar"]], "Multiple_EscapedRefinement_v2") + @params([Id3v2Version.V23, "(CR)f((oo(RX)b((ar", ["Cover f(oo", "Remix b(ar"]], "Multiple_EscapedRefinement_v3") + @params([Id3v2Version.V22, "(CR)f(oo(RX)b(ar", ["Cover f(oo(RX)b(ar"]], "Multiple_UnescapedRefinement_v2") + @params([Id3v2Version.V23, "(CR)f(oo(RX)b(ar", ["Cover f(oo(RX)b(ar"]], "Multiple_UnescapedRefinement_v3") + public parse_v23_singleTerm_remixCover([version, input, output]: [Id3v2Version, string, string[]]) { this.testFrameParse(version, input, output); } - @params([2, false, "32", ["32"]], "disabled_v2") - @params([3, false, "32", ["32"]], "disabled_v3") - @params([2, true, "32", ["Classical"]], "enabled_v2") - @params([3, true, "32", ["Classical"]], "enabled_v3") - @params([2, false, "32foo", ["32foo"]], "singleWithString_disabled_v2") - @params([3, false, "32foo", ["32foo"]], "singleWithString_disabled_v3") - @params([2, true, "32foo", ["32foo"]], "singleWithString_enabled_v2") - @params([3, true, "32foo", ["32foo"]], "singleWithString_enabled_v3") - @params([2, false, "32foo33bar", ["32foo33bar"]], "multipleWithString_disabled_v2") - @params([3, false, "32foo33bar", ["32foo33bar"]], "multipleWithString_disabled_v3") - @params([2, true, "32foo33bar", ["32foo33bar"]], "multipleWithString_enabled_v2") - @params([3, true, "32foo33bar", ["32foo33bar"]], "multipleWithString_enabled_v3") + @params([Id3v2Version.V22, false, "32", ["32"]], "disabled_v2") + @params([Id3v2Version.V23, false, "32", ["32"]], "disabled_v3") + @params([Id3v2Version.V22, true, "32", ["Classical"]], "enabled_v2") + @params([Id3v2Version.V23, true, "32", ["Classical"]], "enabled_v3") + @params([Id3v2Version.V22, false, "32foo", ["32foo"]], "singleWithString_disabled_v2") + @params([Id3v2Version.V23, false, "32foo", ["32foo"]], "singleWithString_disabled_v3") + @params([Id3v2Version.V22, true, "32foo", ["32foo"]], "singleWithString_enabled_v2") + @params([Id3v2Version.V23, true, "32foo", ["32foo"]], "singleWithString_enabled_v3") + @params([Id3v2Version.V22, false, "32foo33bar", ["32foo33bar"]], "multipleWithString_disabled_v2") + @params([Id3v2Version.V23, false, "32foo33bar", ["32foo33bar"]], "multipleWithString_disabled_v3") + @params([Id3v2Version.V22, true, "32foo33bar", ["32foo33bar"]], "multipleWithString_enabled_v2") + @params([Id3v2Version.V23, true, "32foo33bar", ["32foo33bar"]], "multipleWithString_enabled_v3") public parse_v23_singleTerm_nonstandardNumber( - [version, numericGenres, input, output]: [number, boolean, string, string[]] + [version, numericGenres, input, output]: [Id3v2Version, boolean, string, string[]] ) { const partialSettings: PartialSettings = {useNonStandardV2V3NumericGenres: numericGenres}; this.testFrameParse_v23WithSettings(version, partialSettings, input, output); } - @params(2, "v2") - @params(3, "v3") - public parse_v23_multipleTerms_nonStandardSeparatorEnabled(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + public parse_v23_multipleTerms_nonStandardSeparatorEnabled(version: Id3v2Version) { const partialSettings: PartialSettings = {useNonStandardV2V3GenreSeparators: true}; this.testFrameParse_v23WithSettings( version, @@ -190,9 +192,9 @@ class Id3v2_GenreFrameTests extends FrameConstructorTests { ); } - @params(2, "v2") - @params(3, "v3") - public parse_v23_multipleTerms_nonStandardSeparatorDisabled(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + public parse_v23_multipleTerms_nonStandardSeparatorDisabled(version: Id3v2Version) { const partialSettings: PartialSettings = {useNonStandardV2V3GenreSeparators: false}; this.testFrameParse_v23WithSettings( version, @@ -202,9 +204,9 @@ class Id3v2_GenreFrameTests extends FrameConstructorTests { ); } - @params(2, "v2") - @params(3, "v3") - public parse_v23_multipleTerm_trailingNulls(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + public parse_v23_multipleTerm_trailingNulls(version: Id3v2Version) { const payload = ByteVector.concatenate( StringType.UTF16BE, ByteVector.fromString("(32)", StringType.UTF16BE), @@ -220,16 +222,16 @@ class Id3v2_GenreFrameTests extends FrameConstructorTests { this.testFrameParse_v4(["32", "(32)", "some genre"], ["Classical", "(32)", "some genre"]); } - @params([["CR"], ["Cover"]], "cover") - @params([["RX"], ["Remix"]], "remix") - @params([["CR foo"], ["CR foo"]], "cover_refined") - @params([["RX foo"], ["RX foo"]], "remix_refined") - @params([["(CR)"], ["(CR)"]], "cover_parenthesis") - @params([["(RX)"], ["(RX)"]], "remox_parenthesis") + @params([["CR"], ["Cover"]], "cover") + @params([["RX"], ["Remix"]], "remix") + @params([["CR foo"], ["CR foo"]], "cover_refined") + @params([["RX foo"], ["RX foo"]], "remix_refined") + @params([["(CR)"], ["(CR)"]], "cover_parenthesis") + @params([["(RX)"], ["(RX)"]], "remox_parenthesis") @params([["CR f((oo"], ["CR f((oo"]], "cover_escaped") @params([["RX f((oo"], ["RX f((oo"]], "remix_escaped") - @params([["CR f(oo"], ["CR f(oo"]], "cover_unescaped") - @params([["RX f(oo"], ["RX f(oo"]], "remix_unescaped") + @params([["CR f(oo"], ["CR f(oo"]], "cover_unescaped") + @params([["RX f(oo"], ["RX f(oo"]], "remix_unescaped") public parse_v4_coverRemix([input, output]: [string[], string[]]) { this.testFrameParse_v4(input, output); } @@ -252,72 +254,78 @@ class Id3v2_GenreFrameTests extends FrameConstructorTests { // region Render tests - @params([2, ["foobarbaz"], "foobarbaz"], "v2") - @params([3, ["foobarbaz"], "foobarbaz"], "v3") - @params([2, ["f()()"], "f(()(()"], "singleParentheses_v2") - @params([3, ["f()()"], "f(()(()"], "singleParentheses_v3") - @params([2, ["foo","bar","baz"], "foo;bar;baz"], "multiple_v2") - @params([3, ["foo","bar","baz"], "foo;bar;baz"], "multiple_v3") - public render_v23_general([version, input, output]: [number, string[], string]) { + @params([Id3v2Version.V22, ["foobarbaz"], "foobarbaz"], "v2") + @params([Id3v2Version.V23, ["foobarbaz"], "foobarbaz"], "v3") + @params([Id3v2Version.V22, ["f()()"], "f(()(()"], "singleParentheses_v2") + @params([Id3v2Version.V23, ["f()()"], "f(()(()"], "singleParentheses_v3") + @params([Id3v2Version.V22, ["foo","bar","baz"], "foo;bar;baz"], "multiple_v2") + @params([Id3v2Version.V23, ["foo","bar","baz"], "foo;bar;baz"], "multiple_v3") + public render_v23_general([version, input, output]: [Id3v2Version, string[], string]) { this.testFrameRender(version, input, output); } - @params([2, ["Classical"], "(32)"], "single_v2") - @params([3, ["Classical"], "(32)"], "single_v3") - @params([2, ["Cover"], "(CR)"], "singleCover_v2") - @params([3, ["Cover"], "(CR)"], "singleCover_v3") - @params([2, ["Remix"], "(RX)"], "singleRemix_v2") - @params([3, ["Remix"], "(RX)"], "singleRemix_v3") - @params([2, ["Classical", "Instrumental"], "(32)(33)"], "multiple_v2") - @params([3, ["Classical", "Instrumental"], "(32)(33)"], "multiple_v3") - @params([2, ["Classical foo", "Instrumental bar"], "Classical foo;Instrumental bar"], "multipleWithRefinement_v2") - @params([3, ["Classical foo", "Instrumental bar"], "Classical foo;Instrumental bar"], "multipleWithRefinement_v3") + /* eslint-disable max-len */ + @params([Id3v2Version.V22, ["Classical"], "(32)"], "single_v2") + @params([Id3v2Version.V23, ["Classical"], "(32)"], "single_v3") + @params([Id3v2Version.V22, ["Cover"], "(CR)"], "singleCover_v2") + @params([Id3v2Version.V23, ["Cover"], "(CR)"], "singleCover_v3") + @params([Id3v2Version.V22, ["Remix"], "(RX)"], "singleRemix_v2") + @params([Id3v2Version.V23, ["Remix"], "(RX)"], "singleRemix_v3") + @params([Id3v2Version.V22, ["Classical", "Instrumental"], "(32)(33)"], "multiple_v2") + @params([Id3v2Version.V23, ["Classical", "Instrumental"], "(32)(33)"], "multiple_v3") + @params([Id3v2Version.V22, ["Classical foo", "Instrumental bar"], "Classical foo;Instrumental bar"], "multipleWithRefinement_v2") + @params([Id3v2Version.V23, ["Classical foo", "Instrumental bar"], "Classical foo;Instrumental bar"], "multipleWithRefinement_v3") + /* eslint-enable */ public render_v23_numericString_useNumericGenresEnabled( - [version, input, output]: [number, string[], string] + [version, input, output]: [Id3v2Version, string[], string] ) { const settings: PartialSettings = { useNumericGenres: true }; this.testFrameRender_v23WithSettings(version, settings, input, output); } - @params([2, ["Classical"], "Classical"], "single_v2") - @params([3, ["Classical"], "Classical"], "single_v3") - @params([2, ["Cover"], "Cover"], "singleCover_v2") - @params([3, ["Cover"], "Cover"], "singleCover_v3") - @params([2, ["Remix"], "Remix"], "singleRemix_v2") - @params([3, ["Remix"], "Remix"], "singleRemix_v3") - @params([2, ["Classical", "Instrumental"], "Classical;Instrumental"], "multiple_v2") - @params([3, ["Classical", "Instrumental"], "Classical;Instrumental"], "multiple_v3") - @params([2, ["Classical foo", "Instrumental bar"], "Classical foo;Instrumental bar"], "multipleWithRefinement_v2") - @params([3, ["Classical foo", "Instrumental bar"], "Classical foo;Instrumental bar"], "multipleWithRefinement_v3") + /* eslint-disable max-len */ + @params([Id3v2Version.V22, ["Classical"], "Classical"], "single_v2") + @params([Id3v2Version.V23, ["Classical"], "Classical"], "single_v3") + @params([Id3v2Version.V22, ["Cover"], "Cover"], "singleCover_v2") + @params([Id3v2Version.V23, ["Cover"], "Cover"], "singleCover_v3") + @params([Id3v2Version.V22, ["Remix"], "Remix"], "singleRemix_v2") + @params([Id3v2Version.V23, ["Remix"], "Remix"], "singleRemix_v3") + @params([Id3v2Version.V22, ["Classical", "Instrumental"], "Classical;Instrumental"], "multiple_v2") + @params([Id3v2Version.V23, ["Classical", "Instrumental"], "Classical;Instrumental"], "multiple_v3") + @params([Id3v2Version.V22, ["Classical foo", "Instrumental bar"], "Classical foo;Instrumental bar"], "multipleWithRefinement_v2") + @params([Id3v2Version.V23, ["Classical foo", "Instrumental bar"], "Classical foo;Instrumental bar"], "multipleWithRefinement_v3") + /* eslint-enable */ public render_v23_singleTerm_numericString_useNumericGenresDisabled( - [version, input, output]: [number, string[], string] + [version, input, output]: [Id3v2Version, string[], string] ) { const settings: PartialSettings = { useNumericGenres: false }; this.testFrameRender_v23WithSettings(version, settings, input, output); } - @params([["foobarbaz"], ["foobarbaz"]], "single") - @params([["foo", "bar", "baz"], ["foo", "bar", "baz"]], "multiple") + @params([["foobarbaz"], ["foobarbaz"]], "single") + @params([["foo", "bar", "baz"], ["foo", "bar", "baz"]], "multiple") @params([["foo", undefined, "", "bar"], ["foo", undefined, "", "bar"]], "multipleWithFalsy") public render_v4_general([input, output]: [string[], string[]]) { this.testFrameRender_v4(input, output); } - @params([["Classical"], ["32"]], "single") - @params([["Cover"], ["CR"]], "cover") - @params([["Remix"], ["RX"]], "remix") - @params([["Classical", "Instrumental", "foo"], ["32", "33", "foo"]], "multiple") + @params([["Classical"], ["32"]], "single") + @params([["Cover"], ["CR"]], "cover") + @params([["Remix"], ["RX"]], "remix") + @params([["Classical", "Instrumental", "foo"], ["32", "33", "foo"]], "multiple") @params([["Classical foo", "Instrumental foo"], ["Classical foo", "Instrumental foo"], "multipleWithRefinement"]) public render_v4_numericString_useNumericGenresEnabled([input, output]: [string[], string[]]) { const settings: PartialSettings = { useNumericGenres: true }; this.testFrameRender_v4WithSettings(settings, input, output); } - @params([["Classical"], ["Classical"]], "single") - @params([["Cover"], ["CR"]], "cover") // @TODO: Quadruple check this is correct if numeric genres are disabled - @params([["Remix"], ["RX"]], "remix") - @params([["Classical", "Instrumental", "foo"], ["Classical", "Instrumental", "foo"]], "multiple") + /* eslint-disable max-len */ + @params([["Classical"], ["Classical"]], "single") + @params([["Cover"], ["CR"]], "cover") // @TODO: Quadruple check this is correct if numeric genres are disabled + @params([["Remix"], ["RX"]], "remix") + @params([["Classical", "Instrumental", "foo"], ["Classical", "Instrumental", "foo"]], "multiple") @params([["Classical foo", "Instrumental foo"], ["Classical foo", "Instrumental foo"], "multipleWithRefinement"]) + /* eslint-enable */ public render_v4_numericString_useNumericGenresDisabled([input, output]: [string[], string[]]) { const settings: PartialSettings = { useNumericGenres: false }; this.testFrameRender_v4WithSettings(settings, input, output); @@ -449,7 +457,7 @@ class Id3v2_GenreFrameTests extends FrameConstructorTests { return parts; } - private testFrameParse(tagVersion: number, payload: string|ByteVector, expected: string[]) { + private testFrameParse(tagVersion: Id3v2Version, payload: string|ByteVector, expected: string[]) { // Arrange const fieldBytes = payload instanceof ByteVector ? payload @@ -464,7 +472,7 @@ class Id3v2_GenreFrameTests extends FrameConstructorTests { } private testFrameParse_v23WithSettings( - version: number, + version: Id3v2Version, settings: PartialSettings, payload: string, expected: string[] @@ -479,10 +487,10 @@ class Id3v2_GenreFrameTests extends FrameConstructorTests { ... this.getDelimitedStrings(fields) ); - this.testFrameParse(4, payload, expected); + this.testFrameParse(Id3v2Version.V24, payload, expected); } - private testFrameRender(tagVersion: number, fields: string[], expected: string) { + private testFrameRender(tagVersion: Id3v2Version, fields: string[], expected: string) { // Arrange const frame = GenreFrame.fromFields(fields, StringType.UTF16BE); @@ -501,7 +509,7 @@ class Id3v2_GenreFrameTests extends FrameConstructorTests { } private testFrameRender_v23WithSettings( - version: number, + version: Id3v2Version, settings: PartialSettings, fields: string[], expected: string ) { @@ -514,7 +522,7 @@ class Id3v2_GenreFrameTests extends FrameConstructorTests { const frame = GenreFrame.fromFields(fields, StringType.UTF16BE); // Act - const result = frame.render(4); + const result = frame.render(Id3v2Version.V24); // Assert const expectedBody = ByteVector.concatenate( From 048dbdcf6d31006311b95c92d442f25fee3590c8 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Sat, 8 Aug 2026 13:57:26 -0500 Subject: [PATCH 14/18] MusicCdIdentifierFrame, PlayCountFrame, PopularimeterFrame --- src/id3v2/frames/musicCdIdentifierFrame.ts | 6 +- src/id3v2/frames/playCountFrame.ts | 6 +- src/id3v2/frames/popularimeterFrame.ts | 6 +- test-unit/id3v2/frameConstructorTests.ts | 10 --- .../id3v2/musicCdIdentifierFrameTests.ts | 26 +++--- test-unit/id3v2/playCountFrameTests.ts | 68 +++++++-------- test-unit/id3v2/popularimeterFrameTests.ts | 86 +++++++++---------- 7 files changed, 99 insertions(+), 109 deletions(-) diff --git a/src/id3v2/frames/musicCdIdentifierFrame.ts b/src/id3v2/frames/musicCdIdentifierFrame.ts index 3b55fa54..01fe6517 100644 --- a/src/id3v2/frames/musicCdIdentifierFrame.ts +++ b/src/id3v2/frames/musicCdIdentifierFrame.ts @@ -3,6 +3,7 @@ import FrameHeader from "./frameHeader"; import {ByteVector} from "../../byteVector"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; +import {Id3v2Version} from "../enums"; /** * Class extends {@link Frame}, implementing support for ID3v2 Music CD Identifier (MCDI) frames. @@ -21,16 +22,15 @@ export default class MusicCdIdentifierFrame extends Frame { * Constructs and initialized a new instance by storing the bytes of the frame. * @param header Header of the frame * @param fieldBytes Bytes that contain the body of the frame - * @param version ID3v2 version the frame was originally encoded with + * @param _version ID3v2 version the frame was originally encoded with */ public static fromFieldBytes( header: FrameHeader, fieldBytes: ByteVector, - version: number + _version: Id3v2Version ): MusicCdIdentifierFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); - Guards.byte(version, "version"); const frame = new MusicCdIdentifierFrame(header); frame._data = fieldBytes.toByteVector(); diff --git a/src/id3v2/frames/playCountFrame.ts b/src/id3v2/frames/playCountFrame.ts index e910f30b..e2c63004 100644 --- a/src/id3v2/frames/playCountFrame.ts +++ b/src/id3v2/frames/playCountFrame.ts @@ -4,6 +4,7 @@ import {ByteVector} from "../../byteVector"; import {CorruptFileError, NotSupportedError} from "../../errors"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; +import {Id3v2Version} from "../enums"; /** * This class extends {@link Frame} implementing support for ID3v2 play count (PCNT) frames. @@ -22,12 +23,11 @@ export default class PlayCountFrame extends Frame { * Constructs and initialized a new instance by parsing values from the field data. * @param header Header of the frame * @param fieldBytes Bytes that contain the body of the frame - * @param version ID3v2 version the frame was originally encoded with + * @param _version ID3v2 version the frame was originally encoded with */ - public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: number): PlayCountFrame { + public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, _version: Id3v2Version): PlayCountFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); - Guards.byte(version, "version"); if (fieldBytes.length < 4) { throw new CorruptFileError("Play count frame must contain at least 4 bytes."); diff --git a/src/id3v2/frames/popularimeterFrame.ts b/src/id3v2/frames/popularimeterFrame.ts index 3ca31fd9..3c090d32 100644 --- a/src/id3v2/frames/popularimeterFrame.ts +++ b/src/id3v2/frames/popularimeterFrame.ts @@ -4,6 +4,7 @@ import {ByteVector, StringType} from "../../byteVector"; import {CorruptFileError, NotSupportedError} from "../../errors"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; +import {Id3v2Version} from "../enums"; /** * This class extends {@link Frame} implementing support for ID3v2 popularimeter (POPM) frames. @@ -23,16 +24,15 @@ export default class PopularimeterFrame extends Frame { * Constructs and initialized a new instance by parsing values from the field data. * @param header Header of the frame * @param fieldBytes Bytes that contain the body of the frame - * @param version ID3v2 version the frame was originally encoded with + * @param _version ID3v2 version the frame was originally encoded with */ public static fromFieldBytes( header: FrameHeader, fieldBytes: ByteVector, - version: number + _version: Id3v2Version ): PopularimeterFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); - Guards.byte(version, "version"); // Email to user $00 // Rating $xx diff --git a/test-unit/id3v2/frameConstructorTests.ts b/test-unit/id3v2/frameConstructorTests.ts index d23534df..26eeac97 100644 --- a/test-unit/id3v2/frameConstructorTests.ts +++ b/test-unit/id3v2/frameConstructorTests.ts @@ -27,14 +27,4 @@ export default abstract class FrameConstructorTests { // Act/Assert Testers.testTruthy((v: ByteVector) => { this.fromFieldBytes(header, v, 4); }); } - - @test - public fromFieldBytes_invalidVersion_throws() { - // Arrange - const data = ByteVector.empty(); - const header = new FrameHeader(FrameIdentifiers.WCOM); - - // Act/Assert - Testers.testByte((v: number) => { this.fromFieldBytes(header, data, v); }); - } } diff --git a/test-unit/id3v2/musicCdIdentifierFrameTests.ts b/test-unit/id3v2/musicCdIdentifierFrameTests.ts index 61e5848a..fbba63f7 100644 --- a/test-unit/id3v2/musicCdIdentifierFrameTests.ts +++ b/test-unit/id3v2/musicCdIdentifierFrameTests.ts @@ -8,19 +8,19 @@ import MusicCdIdentifierFrame from "../../src/id3v2/frames/musicCdIdentifierFram import PropertyTests from "../utilities/propertyTests"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {FrameFlags} from "../../src/id3v2/enums"; +import {FrameFlags, Id3v2Version} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @suite class Id3v2_MusicCdIdentifierFrameTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: Id3v2Version) => Frame { return MusicCdIdentifierFrame.fromFieldBytes; } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_validParams(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_validParams(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.fromString("foo bar baz", StringType.UTF8); const header = new FrameHeader(FrameIdentifiers.MCDI, FrameFlags.None, fieldBytes.length); @@ -63,10 +63,10 @@ import {Testers} from "../utilities/testers"; PropertyTests.propertyRoundTrip((v) => { frame.data = v; }, () => frame.data, value); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public clone_returnsCopy(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public clone_returnsCopy(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.fromString("foo bar baz", StringType.UTF8); const header = new FrameHeader(FrameIdentifiers.MCDI, FrameFlags.None, fieldBytes.length); @@ -160,9 +160,9 @@ import {Testers} from "../utilities/testers"; assert.deepEqual(result, [frame1, frame2]); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") public render_returnsByteVector(version: number) { // Arrange const fieldBytes = ByteVector.fromString("foo bar baz", StringType.UTF8); diff --git a/test-unit/id3v2/playCountFrameTests.ts b/test-unit/id3v2/playCountFrameTests.ts index d8c6c707..30e3abb6 100644 --- a/test-unit/id3v2/playCountFrameTests.ts +++ b/test-unit/id3v2/playCountFrameTests.ts @@ -8,7 +8,7 @@ import PlayCountFrame from "../../src/id3v2/frames/playCountFrame"; import PropertyTests from "../utilities/propertyTests"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector} from "../../src/byteVector"; -import {FrameFlags} from "../../src/id3v2/enums"; +import {FrameFlags, Id3v2Version} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -21,14 +21,14 @@ const assertFrame = (frame: PlayCountFrame, p: bigint) => { } @suite class Id3v2_PlayCountFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: Id3v2Version) => Frame { return PlayCountFrame.fromFieldBytes; } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_tooBig(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_tooBig(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.fromByteArray([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09]); const header = new FrameHeader(FrameIdentifiers.PCNT, FrameFlags.None, fieldBytes.length); @@ -37,10 +37,10 @@ const assertFrame = (frame: PlayCountFrame, p: bigint) => { assert.throws(() => PlayCountFrame.fromFieldBytes(header, fieldBytes, version)); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_tooSmall(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_tooSmall(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.fromByteArray([0x01, 0x02, 0x03]); const header = new FrameHeader(FrameIdentifiers.PCNT, FrameFlags.None, fieldBytes.length); @@ -49,10 +49,10 @@ const assertFrame = (frame: PlayCountFrame, p: bigint) => { assert.throws(() => PlayCountFrame.fromFieldBytes(header, fieldBytes, version)); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_fourBytePlayCount(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_fourBytePlayCount(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.fromUint(1234); const header = new FrameHeader(FrameIdentifiers.PCNT, FrameFlags.None, fieldBytes.length); @@ -64,10 +64,10 @@ const assertFrame = (frame: PlayCountFrame, p: bigint) => { assertFrame(frame, BigInt(1234)); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_sixBytePlayCount(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_sixBytePlayCount(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.fromByteArray([0x01, 0x02, 0x03, 0x04, 0x05, 0x06]); const header = new FrameHeader(FrameIdentifiers.PCNT, FrameFlags.None, fieldBytes.length); @@ -79,10 +79,10 @@ const assertFrame = (frame: PlayCountFrame, p: bigint) => { assertFrame(frame, BigInt("1108152157446")); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_eightBytePlayCount(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_eightBytePlayCount(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.fromByteArray([0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08]); const header = new FrameHeader(FrameIdentifiers.PCNT, FrameFlags.None, fieldBytes.length); @@ -222,10 +222,10 @@ const assertFrame = (frame: PlayCountFrame, p: bigint) => { assert.deepEqual(result, [frame1, frame2]); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public render_fourBytePlayCount(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public render_fourBytePlayCount(version: Id3v2Version) { // Arrange const frame = PlayCountFrame.fromFields(BigInt(1234)); @@ -241,10 +241,10 @@ const assertFrame = (frame: PlayCountFrame, p: bigint) => { Testers.bvEqual(output, expected); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public render_sixBytePlayCount(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public render_sixBytePlayCount(version: Id3v2Version) { // Arrange const frame = PlayCountFrame.fromFields(BigInt("1108152157446")); @@ -260,10 +260,10 @@ const assertFrame = (frame: PlayCountFrame, p: bigint) => { Testers.bvEqual(output, expected); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public render_eightBytePlayCount(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public render_eightBytePlayCount(version: Id3v2Version) { // Arrange const frame = PlayCountFrame.fromFields(BigInt("72623859790382856")); diff --git a/test-unit/id3v2/popularimeterFrameTests.ts b/test-unit/id3v2/popularimeterFrameTests.ts index cef25544..e60267ae 100644 --- a/test-unit/id3v2/popularimeterFrameTests.ts +++ b/test-unit/id3v2/popularimeterFrameTests.ts @@ -8,7 +8,7 @@ import PopularimeterFrame from "../../src/id3v2/frames/popularimeterFrame"; import PropertyTests from "../utilities/propertyTests"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {FrameFlags} from "../../src/id3v2/enums"; +import {FrameFlags, Id3v2Version} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -23,14 +23,14 @@ const assertFrame = (frame: PopularimeterFrame, u: string, p: bigint, r: number) } @suite class Id3v2_PopularimeterFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: Id3v2Version) => Frame { return PopularimeterFrame.fromFieldBytes; } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_noDelimiter(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_noDelimiter(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.fromByteArray([0x01, 0x02, 0x03]); const header = new FrameHeader(FrameIdentifiers.POPM, FrameFlags.None, fieldBytes.length); @@ -39,10 +39,10 @@ const assertFrame = (frame: PopularimeterFrame, u: string, p: bigint, r: number) assert.throws(() => { PopularimeterFrame.fromFieldBytes(header, fieldBytes, version); }); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_noRating(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_noRating(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( ByteVector.fromString("foo@example.com", StringType.Latin1), 0x00 // Owner + delimiter @@ -53,10 +53,10 @@ const assertFrame = (frame: PopularimeterFrame, u: string, p: bigint, r: number) assert.throws(() => { PopularimeterFrame.fromFieldBytes(header, fieldBytes, version); }); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_playCountTooLong(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_playCountTooLong(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( ByteVector.fromString("foo@example.com", StringType.Latin1), 0x00, // Owner + Delimiter @@ -84,16 +84,16 @@ const assertFrame = (frame: PopularimeterFrame, u: string, p: bigint, r: number) const header = new FrameHeader(FrameIdentifiers.POPM, FrameFlags.None, fieldBytes.length); // Act - const frame = PopularimeterFrame.fromFieldBytes(header, fieldBytes, 4); + const frame = PopularimeterFrame.fromFieldBytes(header, fieldBytes, Id3v2Version.V24); // Assert assertFrame(frame, "foo@example.com", undefined, 0xAB); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_fourBytePlayCount(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_fourBytePlayCount(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( ByteVector.fromString("foo@example.com", StringType.Latin1), 0x00, // Owner + Delimiter @@ -109,10 +109,10 @@ const assertFrame = (frame: PopularimeterFrame, u: string, p: bigint, r: number) assertFrame(frame, "foo@example.com", BigInt(1234), 0xAB); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_sixBytePlayCount(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_sixBytePlayCount(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( ByteVector.fromString("foo@example.com", StringType.Latin1), 0x00, // Owner + Delimiter @@ -128,10 +128,10 @@ const assertFrame = (frame: PopularimeterFrame, u: string, p: bigint, r: number) assertFrame(frame, "foo@example.com", BigInt("1108152157446"), 0xAB); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_eightBytePlayCount(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_eightBytePlayCount(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( ByteVector.fromString("foo@example.com", StringType.Latin1), 0x00, // Owner + Delimiter @@ -321,10 +321,10 @@ const assertFrame = (frame: PopularimeterFrame, u: string, p: bigint, r: number) assert.deepEqual(result, [frame1, frame2]); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public render_noPlayCount(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public render_noPlayCount(version: Id3v2Version) { // Arrange const frame = PopularimeterFrame.fromFields("foo@example.com", 0xAB); @@ -343,10 +343,10 @@ const assertFrame = (frame: PopularimeterFrame, u: string, p: bigint, r: number) Testers.bvEqual(output, expected); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public render_fourBytePlayCount(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public render_fourBytePlayCount(version: Id3v2Version) { // Arrange const frame = PopularimeterFrame.fromFields("foo@example.com", 0xAB, BigInt(1234)); @@ -366,10 +366,10 @@ const assertFrame = (frame: PopularimeterFrame, u: string, p: bigint, r: number) Testers.bvEqual(output, expected); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public render_sixBytePlayCount(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public render_sixBytePlayCount(version: Id3v2Version) { // Arrange const frame = PopularimeterFrame.fromFields("foo@example.com", 0xAB, BigInt("1108152157446")); @@ -389,10 +389,10 @@ const assertFrame = (frame: PopularimeterFrame, u: string, p: bigint, r: number) Testers.bvEqual(output, expected); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public render_eightBytePlayCount(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public render_eightBytePlayCount(version: Id3v2Version) { // Arrange const frame = PopularimeterFrame.fromFields("foo@example.com", 0xAB, BigInt("72623859790382856")); From 307269a488293a21cb25cdb5e38fdd0856de3b9a Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Sat, 8 Aug 2026 14:49:42 -0500 Subject: [PATCH 15/18] PrivateFrame, RelativeVolumeFrame, SynchronizedLyricsFrame, TermsOfUseFrame, TextInformationFrame, UniqueFileIdentifier, UnknownFrame, UnsynchronizedLyricsFrame, UrlLinkFrame, UserTextInformationFrame, UserUrlLinkFrame --- src/id3v2/frames/privateFrame.ts | 10 +- src/id3v2/frames/relativeVolumeFrame.ts | 11 ++- src/id3v2/frames/synchronizedLyricsFrame.ts | 9 +- src/id3v2/frames/termsOfUseFrame.ts | 8 +- src/id3v2/frames/textInformationFrame.ts | 18 ++-- src/id3v2/frames/uniqueFileIdentifierFrame.ts | 6 +- src/id3v2/frames/unknownFrame.ts | 6 +- src/id3v2/frames/unsynchronizedLyricsFrame.ts | 8 +- src/id3v2/frames/urlLinkFrame.ts | 8 +- src/id3v2/frames/userTextInformationFrame.ts | 8 +- src/id3v2/frames/userUrlLinkFrame.ts | 12 ++- test-unit/id3v2/privateFrameTests.ts | 50 +++++----- test-unit/id3v2/relativeVolumeFrameTests.ts | 74 +++++++------- .../id3v2/synchronizedLyricsFrameTests.ts | 98 +++++++++---------- test-unit/id3v2/termsOfUseFrameTests.ts | 46 ++++----- test-unit/id3v2/textInformationFrameTests.ts | 88 ++++++++--------- .../id3v2/uniqueFileIdentifierFrameTests.ts | 44 ++++----- test-unit/id3v2/unknownFrameTests.ts | 28 +++--- .../id3v2/unsynchronizedLyricsFrameTests.ts | 76 +++++++------- test-unit/id3v2/urlLinkFrameTests.ts | 36 +++---- .../id3v2/userTextInformationFrameTests.ts | 64 ++++++------ test-unit/id3v2/userUrlLinkFrameTests.ts | 64 ++++++------ 22 files changed, 391 insertions(+), 381 deletions(-) diff --git a/src/id3v2/frames/privateFrame.ts b/src/id3v2/frames/privateFrame.ts index 01614979..d9b489b8 100644 --- a/src/id3v2/frames/privateFrame.ts +++ b/src/id3v2/frames/privateFrame.ts @@ -1,6 +1,7 @@ import Frame from "./frame"; import FrameHeader from "./frameHeader"; import {ByteVector, StringType} from "../../byteVector"; +import {Id3v2Version} from "../enums"; import {CorruptFileError, NotImplementedError} from "../../errors"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; @@ -25,12 +26,11 @@ export default class PrivateFrame extends Frame { * provided fields bytes. * @param header Header of the frame * @param fieldBytes Bytes that contain the fields of the frame - * @param version ID3v2 version the frame was originally encoded with + * @param _version ID3v2 version the frame was originally encoded with */ - public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: number): PrivateFrame { + public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, _version: Id3v2Version): PrivateFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); - Guards.byte(version, "version"); if (fieldBytes.length < 1) { throw new CorruptFileError("A private frame must contain at least 1 byte"); @@ -95,8 +95,8 @@ export default class PrivateFrame extends Frame { } /** @inheritDoc */ - protected renderFields(version: number): ByteVector { - if (version < 3) { + protected renderFields(version: Id3v2Version): ByteVector { + if (version === Id3v2Version.V22) { throw new NotImplementedError(); // @TODO: I don't think this should throw ... maybe return nothing? } diff --git a/src/id3v2/frames/relativeVolumeFrame.ts b/src/id3v2/frames/relativeVolumeFrame.ts index 2a841188..9752c34d 100644 --- a/src/id3v2/frames/relativeVolumeFrame.ts +++ b/src/id3v2/frames/relativeVolumeFrame.ts @@ -1,7 +1,7 @@ import Frame from "./frame"; import FrameHeader from "./frameHeader"; import {ByteVector, StringType} from "../../byteVector"; -import {ChannelType} from "../enums"; +import {ChannelType, Id3v2Version} from "../enums"; import {CorruptFileError} from "../../errors"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards, NumberUtils} from "../../utils"; @@ -169,12 +169,15 @@ export class RelativeVolumeFrame extends Frame { * Constructs and initialized a new instance by parsing values from the field data. * @param header Header of the frame * @param fieldBytes Bytes that contain the body of the frame - * @param version ID3v2 version the frame was originally encoded with + * @param _version ID3v2 version the frame was originally encoded with */ - public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: number): RelativeVolumeFrame { + public static fromFieldBytes( + header: FrameHeader, + fieldBytes: ByteVector, + _version: Id3v2Version + ): RelativeVolumeFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); - Guards.byte(version, "version"); // Identification $00 // ---- Repeated for each channel -------------- diff --git a/src/id3v2/frames/synchronizedLyricsFrame.ts b/src/id3v2/frames/synchronizedLyricsFrame.ts index ba53d0b6..0f465f59 100644 --- a/src/id3v2/frames/synchronizedLyricsFrame.ts +++ b/src/id3v2/frames/synchronizedLyricsFrame.ts @@ -2,7 +2,7 @@ import Frame from "./frame"; import FrameHeader from "./frameHeader"; import Id3v2Settings from "../id3v2Settings"; import {ByteVector, StringType} from "../../byteVector"; -import {SynchronizedTextType, TimestampFormat} from "../enums"; +import {Id3v2Version, SynchronizedTextType, TimestampFormat} from "../enums"; import {CorruptFileError} from "../../errors"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; @@ -91,16 +91,15 @@ export class SynchronizedLyricsFrame extends Frame { * Constructs and initialized a new instance by parsing values from the field data. * @param header Header of the frame * @param fieldBytes Bytes that contain the body of the frame - * @param version ID3v2 version the frame was originally encoded with + * @param _version ID3v2 version the frame was originally encoded with */ public static fromFieldBytes( header: FrameHeader, fieldBytes: ByteVector, - version: number + _version: Id3v2Version ): SynchronizedLyricsFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); - Guards.byte(version, "version"); if (fieldBytes.length < 6) { throw new CorruptFileError("Synchronized lyrics frame must contain at least 6 bytes."); @@ -299,7 +298,7 @@ export class SynchronizedLyricsFrame extends Frame { // #endregion /** @inheritDoc */ - protected renderFields(version: number): ByteVector { + protected renderFields(version: Id3v2Version): ByteVector { const encoding = SynchronizedLyricsFrame.correctEncoding(this.textEncoding, version); const renderedText = this.text .filter(t => !!t) diff --git a/src/id3v2/frames/termsOfUseFrame.ts b/src/id3v2/frames/termsOfUseFrame.ts index 31e05fa1..df47c034 100644 --- a/src/id3v2/frames/termsOfUseFrame.ts +++ b/src/id3v2/frames/termsOfUseFrame.ts @@ -5,6 +5,7 @@ import {ByteVector, StringType} from "../../byteVector"; import {CorruptFileError} from "../../errors"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; +import {Id3v2Version} from "../enums"; export default class TermsOfUseFrame extends Frame { private _language: string; @@ -21,12 +22,11 @@ export default class TermsOfUseFrame extends Frame { * Constructs and initializes a new instance by parsing the fields from the field bytes. * @param header Header of the frame * @param fieldBytes Bytes that contain the fields of the frame - * @param version ID3v2 version the frame was originally encoded with + * @param _version ID3v2 version the frame was originally encoded with */ - public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: number): TermsOfUseFrame { + public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, _version: Id3v2Version): TermsOfUseFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); - Guards.byte(version, "version"); if (fieldBytes.length < 4) { throw new CorruptFileError("Terms of use frame must contain at least 4 bytes."); @@ -125,7 +125,7 @@ export default class TermsOfUseFrame extends Frame { // #region Protected Methods /** @inheritDoc */ - protected renderFields(version: number): ByteVector { + protected renderFields(version: Id3v2Version): ByteVector { const encoding = Frame.correctEncoding(this.textEncoding, version); return ByteVector.concatenate( diff --git a/src/id3v2/frames/textInformationFrame.ts b/src/id3v2/frames/textInformationFrame.ts index 13f92bf4..c9348a2b 100644 --- a/src/id3v2/frames/textInformationFrame.ts +++ b/src/id3v2/frames/textInformationFrame.ts @@ -5,6 +5,7 @@ import {ByteVector, StringType} from "../../byteVector"; import {CorruptFileError} from "../../errors"; import {FrameIdentifier, FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; +import {Id3v2Version} from "../enums"; /** * This class provides support for ID3v2 text information frames (section 4.2) covering `T000` to @@ -158,10 +159,13 @@ export default class TextInformationFrame extends Frame { * @param fieldBytes Bytes that contain the fields of the frame * @param version ID3v2 version the frame was originally encoded with */ - public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: number): TextInformationFrame { + public static fromFieldBytes( + header: FrameHeader, + fieldBytes: ByteVector, + version: Id3v2Version + ): TextInformationFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); - Guards.byte(version, "version"); if (fieldBytes.length < 1) { throw new CorruptFileError("Text identifier frame must contain at least 1 byte."); @@ -177,7 +181,7 @@ export default class TextInformationFrame extends Frame { // Split the text if required const textBytes = fieldBytes.subarray(1); - if (version >= 4) { + if (version === Id3v2Version.V24) { // @TODO: Should we filter out empty? We currently do it when rendering... frame._textFields = textBytes.toStrings(frame._encoding) .filter(t => !!t); @@ -275,10 +279,10 @@ export default class TextInformationFrame extends Frame { * 8-bit integer. * @returns Rendered version of the current instance. */ - public render(version: number): ByteVector { + public render(version: Id3v2Version): ByteVector { Guards.byte(version, "version"); - if (version !== 3 || this.frameId !== FrameIdentifiers.TDRC) { + if (version !== Id3v2Version.V23 || this.frameId !== FrameIdentifiers.TDRC) { return super.render(version); } @@ -320,7 +324,7 @@ export default class TextInformationFrame extends Frame { // #region Protected Methods /** @inheritDoc */ - protected renderFields(version: number): ByteVector { + protected renderFields(version: Id3v2Version): ByteVector { const truthyFields = this._textFields.filter(tf => !!tf); if (truthyFields.length === 0) { return ByteVector.empty(); @@ -329,7 +333,7 @@ export default class TextInformationFrame extends Frame { const encoding = TextInformationFrame.correctEncoding(this._encoding, version); let fieldBytes; - if (version > 3) { + if (version === Id3v2Version.V24) { // v4 frames have each field separated by a delimiter const truthyVectors = truthyFields.map(tf => ByteVector.fromString(tf, encoding)); fieldBytes = ByteVector.join(ByteVector.getTextDelimiter(encoding), truthyVectors); diff --git a/src/id3v2/frames/uniqueFileIdentifierFrame.ts b/src/id3v2/frames/uniqueFileIdentifierFrame.ts index a20247d4..d23129f0 100644 --- a/src/id3v2/frames/uniqueFileIdentifierFrame.ts +++ b/src/id3v2/frames/uniqueFileIdentifierFrame.ts @@ -4,6 +4,7 @@ import {ByteVector, StringType} from "../../byteVector"; import {CorruptFileError} from "../../errors"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; +import {Id3v2Version} from "../enums"; /** * Implements support for ID3v2 Unique File Identifier (UFID) frames. @@ -22,16 +23,15 @@ export default class UniqueFileIdentifierFrame extends Frame { * Constructs and initializes a new instance by parsing the fields from the field bytes. * @param header Header of the frame * @param fieldBytes Bytes that contain the fields of the frame - * @param version ID3v2 version the frame was originally encoded with + * @param _version ID3v2 version the frame was originally encoded with */ public static fromFieldBytes( header: FrameHeader, fieldBytes: ByteVector, - version: number + _version: Id3v2Version ): UniqueFileIdentifierFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); - Guards.byte(version, "version"); // Owner identifier $00 // Identifier diff --git a/src/id3v2/frames/unknownFrame.ts b/src/id3v2/frames/unknownFrame.ts index 067b34bb..aba38545 100644 --- a/src/id3v2/frames/unknownFrame.ts +++ b/src/id3v2/frames/unknownFrame.ts @@ -3,6 +3,7 @@ import FrameHeader from "./frameHeader"; import {ByteVector} from "../../byteVector"; import {FrameIdentifier} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; +import {Id3v2Version} from "../enums"; /** * Fallback type when no other frame class works for a given frame. @@ -16,12 +17,11 @@ export default class UnknownFrame extends Frame { * Constructs and initialized a new instance by storing the body bytes. * @param header Header of the frame * @param fieldBytes Bytes that contain the body of the frame - * @param version ID3v2 version the frame was originally encoded with + * @param _version ID3v2 version the frame was originally encoded with */ - public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: number): UnknownFrame { + public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, _version: Id3v2Version): UnknownFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); - Guards.byte(version, "version"); const frame = new UnknownFrame(header); frame.data = fieldBytes.toByteVector(); diff --git a/src/id3v2/frames/unsynchronizedLyricsFrame.ts b/src/id3v2/frames/unsynchronizedLyricsFrame.ts index e0c74004..49fe0ea1 100644 --- a/src/id3v2/frames/unsynchronizedLyricsFrame.ts +++ b/src/id3v2/frames/unsynchronizedLyricsFrame.ts @@ -5,6 +5,7 @@ import {ByteVector, StringType} from "../../byteVector"; import {CorruptFileError} from "../../errors"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; +import {Id3v2Version} from "../enums"; /** * Extends {@link Frame} implementing support for ID3v2 unsynchronized lyrics (USLT) frames. @@ -25,16 +26,15 @@ export default class UnsynchronizedLyricsFrame extends Frame { * Constructs and initializes a new instance by parsing the fields from the field bytes. * @param header Header of the frame * @param fieldBytes Bytes that contain the fields of the frame - * @param version ID3v2 version the frame was originally encoded with + * @param _version ID3v2 version the frame was originally encoded with */ public static fromFieldBytes( header: FrameHeader, fieldBytes: ByteVector, - version: number + _version: Id3v2Version ): UnsynchronizedLyricsFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); - Guards.byte(version, "version"); if (fieldBytes.length < 4) { throw new CorruptFileError("Unsynchronized lyrics frame must contain at least 4 bytes."); @@ -161,7 +161,7 @@ export default class UnsynchronizedLyricsFrame extends Frame { } /** @inheritDoc */ - protected renderFields(version: number): ByteVector { + protected renderFields(version: Id3v2Version): ByteVector { const encoding = UnsynchronizedLyricsFrame.correctEncoding(this.textEncoding, version); return ByteVector.concatenate( encoding, diff --git a/src/id3v2/frames/urlLinkFrame.ts b/src/id3v2/frames/urlLinkFrame.ts index 172d0fa7..126df069 100644 --- a/src/id3v2/frames/urlLinkFrame.ts +++ b/src/id3v2/frames/urlLinkFrame.ts @@ -3,6 +3,7 @@ import FrameHeader from "./frameHeader"; import {ByteVector, StringType} from "../../byteVector"; import {FrameIdentifier} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; +import {Id3v2Version} from "../enums"; /** * Provides ID3v2 URL Link frame implementation (section 4.3.1) covering `W000` to `WZZZ`, @@ -44,12 +45,11 @@ export default class UrlLinkFrame extends Frame { * Constructs and initializes a new instance by parsing the fields from the field bytes. * @param header Header of the frame * @param fieldBytes Bytes that contain the fields of the frame - * @param version ID3v2 version the frame was originally encoded with + * @param _version ID3v2 version the frame was originally encoded with */ - public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: number): UrlLinkFrame { + public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, _version: Id3v2Version): UrlLinkFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); - Guards.byte(version, "version"); const frame = new UrlLinkFrame(header); @@ -110,7 +110,7 @@ export default class UrlLinkFrame extends Frame { } /** @inheritDoc */ - protected renderFields(_version: number): ByteVector { + protected renderFields(_version: Id3v2Version): ByteVector { if (!this._url) { return ByteVector.empty(); } diff --git a/src/id3v2/frames/userTextInformationFrame.ts b/src/id3v2/frames/userTextInformationFrame.ts index afff5f00..1b36b7ba 100644 --- a/src/id3v2/frames/userTextInformationFrame.ts +++ b/src/id3v2/frames/userTextInformationFrame.ts @@ -5,6 +5,7 @@ import {ByteVector, StringType} from "../../byteVector"; import {CorruptFileError} from "../../errors"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; +import {Id3v2Version} from "../enums"; export default class UserTextInformationFrame extends Frame { private _description: string; @@ -21,16 +22,15 @@ export default class UserTextInformationFrame extends Frame { * Constructs and initializes a new instance by parsing the fields from the field bytes. * @param header Header of the frame * @param fieldBytes Bytes that contain the fields of the frame - * @param version ID3v2 version the frame was originally encoded with + * @param _version ID3v2 version the frame was originally encoded with */ public static fromFieldBytes( header: FrameHeader, fieldBytes: ByteVector, - version: number + _version: Id3v2Version ): UserTextInformationFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); - Guards.byte(version, "version"); if (fieldBytes.length < 1) { throw new CorruptFileError("User text identifier frame must contain at least 1 byte."); @@ -132,7 +132,7 @@ export default class UserTextInformationFrame extends Frame { } /** @inheritDoc */ - protected renderFields(version: number): ByteVector { + protected renderFields(version: Id3v2Version): ByteVector { if (!this._description && this._textFields.length === 0) { return ByteVector.empty(); } diff --git a/src/id3v2/frames/userUrlLinkFrame.ts b/src/id3v2/frames/userUrlLinkFrame.ts index e7bac4f8..c5af8b4a 100644 --- a/src/id3v2/frames/userUrlLinkFrame.ts +++ b/src/id3v2/frames/userUrlLinkFrame.ts @@ -4,6 +4,7 @@ import Id3v2Settings from "../id3v2Settings"; import {ByteVector, StringType} from "../../byteVector"; import {FrameIdentifiers} from "../frameIdentifiers"; import {ArrayUtils, Guards} from "../../utils"; +import {Id3v2Version} from "../enums"; /** * Provides support for ID3v2 User URL Link frames (WXXX). @@ -23,12 +24,15 @@ export default class UserUrlLinkFrame extends Frame { * Constructs and initializes a new instance by parsing the fields from the field bytes. * @param header Header of the frame * @param fieldBytes Bytes that contain the fields of the frame - * @param version ID3v2 version the frame was originally encoded with + * @param _version ID3v2 version the frame was originally encoded with */ - public static fromFieldBytes(header: FrameHeader, fieldBytes: ByteVector, version: number): UserUrlLinkFrame { + public static fromFieldBytes( + header: FrameHeader, + fieldBytes: ByteVector, + _version: Id3v2Version + ): UserUrlLinkFrame { Guards.truthy(header, "header"); Guards.truthy(fieldBytes, "fieldBytes"); - Guards.byte(version, "version"); if (fieldBytes.length < 3) { throw new Error("User URL link frame is smaller than minimum size."); @@ -141,7 +145,7 @@ export default class UserUrlLinkFrame extends Frame { return `[${this._description}] ${this._url}`; } - protected renderFields(version: number): ByteVector { + protected renderFields(version: Id3v2Version): ByteVector { if (!this._description && !this._url) { return ByteVector.empty(); } diff --git a/test-unit/id3v2/privateFrameTests.ts b/test-unit/id3v2/privateFrameTests.ts index 1330e0f2..a23a2d34 100644 --- a/test-unit/id3v2/privateFrameTests.ts +++ b/test-unit/id3v2/privateFrameTests.ts @@ -8,7 +8,7 @@ import PropertyTests from "../utilities/propertyTests"; import PrivateFrame from "../../src/id3v2/frames/privateFrame"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {FrameFlags} from "../../src/id3v2/enums"; +import {FrameFlags, Id3v2Version} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -22,7 +22,7 @@ const assertFrame = (frame: PrivateFrame, o: string, d: ByteVector) => { } @suite class Id3v2_PrivateFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: Id3v2Version) => Frame { return PrivateFrame.fromFieldBytes; } @@ -33,13 +33,13 @@ const assertFrame = (frame: PrivateFrame, o: string, d: ByteVector) => { const header = new FrameHeader(FrameIdentifiers.PRIV, FrameFlags.None, fieldBytes.length); // Act / Assert - assert.throws(() => { PrivateFrame.fromFieldBytes(header, fieldBytes, 4); }); + assert.throws(() => { PrivateFrame.fromFieldBytes(header, fieldBytes, Id3v2Version.V24); }); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_ownerOnly(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_ownerOnly(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( ByteVector.fromString("fux", StringType.Latin1), // Owner @@ -54,10 +54,10 @@ const assertFrame = (frame: PrivateFrame, o: string, d: ByteVector) => { assertFrame(frame, "fux", ByteVector.empty()); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_dataOnly(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_dataOnly(version: Id3v2Version) { // Arrange const dataBytes = ByteVector.concatenate(0x01, 0x02, 0x03, 0x04); const fieldBytes = ByteVector.concatenate( @@ -73,10 +73,10 @@ const assertFrame = (frame: PrivateFrame, o: string, d: ByteVector) => { assertFrame(frame, "", dataBytes); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_ownerAndData(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_ownerAndData(version: Id3v2Version) { // Arrange const dataBytes = ByteVector.concatenate(0x01, 0x02, 0x03, 0x04); const fieldBytes = ByteVector.concatenate( @@ -239,12 +239,12 @@ const assertFrame = (frame: PrivateFrame, o: string, d: ByteVector) => { const frame = PrivateFrame.fromFields(); // Act / Assert - assert.throws(() => frame.render(2)); + assert.throws(() => frame.render(Id3v2Version.V22)); } - @params(3, "v3") - @params(4, "v4") - public render_v34(version: number) { + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public render_v34(version: Id3v2Version) { // Arrange const dataBytes = ByteVector.fromByteArray([0x01, 0x02, 0x03, 0x04]); const fieldBytes = ByteVector.concatenate( @@ -273,15 +273,15 @@ const assertFrame = (frame: PrivateFrame, o: string, d: ByteVector) => { 0x00 // Separator ); const header = new FrameHeader(FrameIdentifiers.PRIV, FrameFlags.None, fieldBytes.length); - const frame = PrivateFrame.fromFieldBytes(header, fieldBytes, 4); + const frame = PrivateFrame.fromFieldBytes(header, fieldBytes, Id3v2Version.V24); // Act - const output = frame.render(4); + const output = frame.render(Id3v2Version.V24); // Assert assert.isOk(output); - const expected = ByteVector.concatenate(header.render(4), fieldBytes); + const expected = ByteVector.concatenate(header.render(Id3v2Version.V24), fieldBytes); Testers.bvEqual(output, expected); } @@ -294,15 +294,15 @@ const assertFrame = (frame: PrivateFrame, o: string, d: ByteVector) => { dataBytes // Data ); const header = new FrameHeader(FrameIdentifiers.PRIV, FrameFlags.None, fieldBytes.length); - const frame = PrivateFrame.fromFieldBytes(header, fieldBytes, 4); + const frame = PrivateFrame.fromFieldBytes(header, fieldBytes, Id3v2Version.V24); // Act - const output = frame.render(4); + const output = frame.render(Id3v2Version.V24); // Assert assert.isOk(output); - const expected = ByteVector.concatenate(header.render(4), fieldBytes); + const expected = ByteVector.concatenate(header.render(Id3v2Version.V24), fieldBytes); Testers.bvEqual(output, expected); } } diff --git a/test-unit/id3v2/relativeVolumeFrameTests.ts b/test-unit/id3v2/relativeVolumeFrameTests.ts index aa191d6c..8e34c8a8 100644 --- a/test-unit/id3v2/relativeVolumeFrameTests.ts +++ b/test-unit/id3v2/relativeVolumeFrameTests.ts @@ -8,7 +8,7 @@ import PropertyTests from "../utilities/propertyTests"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ChannelData, RelativeVolumeFrame} from "../../src/id3v2/frames/relativeVolumeFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {ChannelType, FrameFlags} from "../../src/id3v2/enums"; +import {ChannelType, FrameFlags, Id3v2Version} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -284,14 +284,14 @@ const assertFrame = (frame: RelativeVolumeFrame, c: ChannelData[], i: string) => } @suite class Id3v2_RelativeVolumeFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: FrameHeader, b: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, b: ByteVector, v: Id3v2Version) => Frame { return RelativeVolumeFrame.fromFieldBytes; } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_emptyFrame_throws(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_emptyFrame_throws(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.empty(); const header = new FrameHeader(FrameIdentifiers.RVA2, FrameFlags.None, fieldBytes.length); @@ -300,10 +300,10 @@ const assertFrame = (frame: RelativeVolumeFrame, c: ChannelData[], i: string) => assert.throws(() => RelativeVolumeFrame.fromFieldBytes(header, fieldBytes, version)); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_identifierOnly(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_identifierOnly(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate(ByteVector.fromString("foobarbaz", StringType.Latin1), 0x00); const header = new FrameHeader(FrameIdentifiers.RVA2, FrameFlags.None, fieldBytes.length); @@ -315,10 +315,10 @@ const assertFrame = (frame: RelativeVolumeFrame, c: ChannelData[], i: string) => assertFrame(frame, [], "foobarbaz"); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_oneChannelData(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_oneChannelData(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( ByteVector.fromString("foobarbaz", StringType.Latin1), 0x00, // Identifier + delimiter @@ -340,10 +340,10 @@ const assertFrame = (frame: RelativeVolumeFrame, c: ChannelData[], i: string) => assertFrame(frame, [channelData], "foobarbaz"); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_twoChannelData(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_twoChannelData(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( ByteVector.fromString("foobarbaz", StringType.Latin1), 0x00, // Identifier + delimiter @@ -376,10 +376,10 @@ const assertFrame = (frame: RelativeVolumeFrame, c: ChannelData[], i: string) => assertFrame(frame, [cd2, cd1], "foobarbaz"); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_incompleteChannelDataAtBits(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_incompleteChannelDataAtBits(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( ByteVector.fromString("foobarbaz", StringType.Latin1), 0x00, // Identifier + delimiter @@ -405,10 +405,10 @@ const assertFrame = (frame: RelativeVolumeFrame, c: ChannelData[], i: string) => assertFrame(frame, [cd1], "foobarbaz"); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_incompleteChannelDataAtPeak(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_incompleteChannelDataAtPeak(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( ByteVector.fromString("foobarbaz", StringType.Latin1), 0x00, // Identifier + delimiter @@ -629,10 +629,10 @@ const assertFrame = (frame: RelativeVolumeFrame, c: ChannelData[], i: string) => ); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public render_noChannelData(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public render_noChannelData(version: Id3v2Version) { // Arrange const frame = RelativeVolumeFrame.fromFields("foobarbaz"); @@ -646,9 +646,9 @@ const assertFrame = (frame: RelativeVolumeFrame, c: ChannelData[], i: string) => Testers.bvEqual(output, expected); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") public render_oneChannelData(version: number) { // Arrange const frame = RelativeVolumeFrame.fromFields("foobarbaz"); @@ -673,10 +673,10 @@ const assertFrame = (frame: RelativeVolumeFrame, c: ChannelData[], i: string) => Testers.bvEqual(result, expected); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public render_twoChannelData(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public render_twoChannelData(version: Id3v2Version) { // Arrange const frame = RelativeVolumeFrame.fromFields("foobarbaz"); frame.setPeakBits(ChannelType.Subwoofer, 32); diff --git a/test-unit/id3v2/synchronizedLyricsFrameTests.ts b/test-unit/id3v2/synchronizedLyricsFrameTests.ts index 78d0a9cc..317b4e15 100644 --- a/test-unit/id3v2/synchronizedLyricsFrameTests.ts +++ b/test-unit/id3v2/synchronizedLyricsFrameTests.ts @@ -8,7 +8,7 @@ import Id3v2Settings from "../../src/id3v2/id3v2Settings"; import PropertyTests from "../utilities/propertyTests"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {FrameFlags, SynchronizedTextType, TimestampFormat} from "../../src/id3v2/enums"; +import {FrameFlags, Id3v2Version, SynchronizedTextType, TimestampFormat} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {SynchronizedLyricsFrame, SynchronizedText} from "../../src/id3v2/frames/synchronizedLyricsFrame"; import {Testers} from "../utilities/testers"; @@ -66,14 +66,14 @@ const assertFrame = ( } @suite class Id3v2_SynchronizedLyricsFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: FrameHeader, d:ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d:ByteVector, v: Id3v2Version) => Frame { return SynchronizedLyricsFrame.fromFieldBytes; } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_notEnoughBytes(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_notEnoughBytes(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.fromByteArray([0x00, 0x00, 0x00, 0x00, 0x00]); const header = new FrameHeader(FrameIdentifiers.SYLT, FrameFlags.None, fieldBytes.length); @@ -82,10 +82,10 @@ const assertFrame = ( assert.throws(() => { SynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, version); }); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_missingDelimiter(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_missingDelimiter(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.Latin1, // Text encoding @@ -100,10 +100,10 @@ const assertFrame = ( assert.throws(() => { SynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, version); }); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_noDelimiterForSynchronizedText(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_noDelimiterForSynchronizedText(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.Latin1, // Text encoding @@ -120,10 +120,10 @@ const assertFrame = ( assert.throws(() => { SynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, version); }); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_incompleteSynchronizedText(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_incompleteSynchronizedText(version: Id3v2Version) { // Arrange const content1 = new SynchronizedText(123, "foo"); const content2 = new SynchronizedText(456, "bar"); @@ -144,10 +144,10 @@ const assertFrame = ( assert.throws(() => { SynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, version); }); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_noData(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_noData(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.UTF16BE, // Encoding @@ -174,10 +174,10 @@ const assertFrame = ( ); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_oneLyric(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_oneLyric(version: Id3v2Version) { // Arrange const lyric1 = new SynchronizedText(123, "foo"); @@ -207,10 +207,10 @@ const assertFrame = ( ); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_twoLyrics(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_twoLyrics(version: Id3v2Version) { // Arrange const lyric1 = new SynchronizedText(123, "foo"); const lyric2 = new SynchronizedText(456, "bar"); @@ -262,7 +262,7 @@ const assertFrame = ( const header = new FrameHeader(FrameIdentifiers.SYLT, FrameFlags.None, fieldBytes.length); // Act - const frame = SynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, 4); + const frame = SynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, Id3v2Version.V24); // Assert assertFrame( @@ -608,10 +608,10 @@ const assertFrame = ( assert.deepEqual(result, [frame1, frame2]); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public render_noLyrics(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public render_noLyrics(version: Id3v2Version) { // Arrange const frame = SynchronizedLyricsFrame.fromFields( "foo", @@ -641,10 +641,10 @@ const assertFrame = ( Testers.bvEqual(output, expected); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public render_falsyLyrics(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public render_falsyLyrics(version: Id3v2Version) { // Arrange const frame = SynchronizedLyricsFrame.fromFields( "foo", @@ -674,10 +674,10 @@ const assertFrame = ( Testers.bvEqual(output, expected); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public render_oneLyric(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public render_oneLyric(version: Id3v2Version) { // Arrange const lyric1 = new SynchronizedText(123, "fux"); const frame = SynchronizedLyricsFrame.fromFields( @@ -709,10 +709,10 @@ const assertFrame = ( Testers.bvEqual(output, expected); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public render_twoLyric(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public render_twoLyric(version: Id3v2Version) { // Arrange const lyric2 = new SynchronizedText(234, "bux"); const lyric1 = new SynchronizedText(123, "fux"); @@ -762,7 +762,7 @@ const assertFrame = ( ); // Act - const output = frame.render(4); + const output = frame.render(Id3v2Version.V24); // Assert assert.isOk(output); @@ -778,7 +778,7 @@ const assertFrame = ( lyric2.render(encoding) // Lyric 2 ); const header = new FrameHeader(FrameIdentifiers.SYLT, FrameFlags.None, fieldBytes.length); - const expected = ByteVector.concatenate(header.render(4), fieldBytes); + const expected = ByteVector.concatenate(header.render(Id3v2Version.V24), fieldBytes); Testers.bvEqual(output, expected); } } diff --git a/test-unit/id3v2/termsOfUseFrameTests.ts b/test-unit/id3v2/termsOfUseFrameTests.ts index acd83961..fabc7d6c 100644 --- a/test-unit/id3v2/termsOfUseFrameTests.ts +++ b/test-unit/id3v2/termsOfUseFrameTests.ts @@ -9,7 +9,7 @@ import PropertyTests from "../utilities/propertyTests"; import TermsOfUseFrame from "../../src/id3v2/frames/termsOfUseFrame"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {FrameFlags} from "../../src/id3v2/enums"; +import {FrameFlags, Id3v2Version} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -24,14 +24,14 @@ const assertFrame = (frame: TermsOfUseFrame, language: string, text: string, tex } @suite class Id3v2_TermsOfUseFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: Id3v2Version) => Frame { return TermsOfUseFrame.fromFieldBytes; } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_notEnoughBytes(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_notEnoughBytes(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate(0x00, 0x00); const header = new FrameHeader(FrameIdentifiers.USER, FrameFlags.None, fieldBytes.length); @@ -40,10 +40,10 @@ const assertFrame = (frame: TermsOfUseFrame, language: string, text: string, tex assert.throws(() => { TermsOfUseFrame.fromFieldBytes(header, fieldBytes, version); }); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_withoutText(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_withoutText(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.Latin1, // Encoding @@ -58,10 +58,10 @@ const assertFrame = (frame: TermsOfUseFrame, language: string, text: string, tex assertFrame(frame, "eng", "", StringType.Latin1); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_withText(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_withText(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.Latin1, // Encoding @@ -89,7 +89,7 @@ const assertFrame = (frame: TermsOfUseFrame, language: string, text: string, tex const header = new FrameHeader(FrameIdentifiers.USER, FrameFlags.None, fieldBytes.length); // Act - const frame = TermsOfUseFrame.fromFieldBytes(header, fieldBytes, 4); + const frame = TermsOfUseFrame.fromFieldBytes(header, fieldBytes, Id3v2Version.V24); // Assert assertFrame(frame, "eng", "foobarbaz", encoding); @@ -271,7 +271,7 @@ const assertFrame = (frame: TermsOfUseFrame, language: string, text: string, tex const frame = TermsOfUseFrame.fromFields("foo", "bar", StringType.Latin1); // Act / Assert - assert.throws(() => frame.render(2)); + assert.throws(() => frame.render(Id3v2Version.V22)); } @params(undefined, "undefined") @@ -282,7 +282,7 @@ const assertFrame = (frame: TermsOfUseFrame, language: string, text: string, tex const frame = TermsOfUseFrame.fromFields(text, "foo", StringType.Latin1); // Act - const result = frame.render(4); + const result = frame.render(Id3v2Version.V24); // Assert const fieldBytes = ByteVector.concatenate( @@ -290,13 +290,13 @@ const assertFrame = (frame: TermsOfUseFrame, language: string, text: string, tex ByteVector.fromString("foo", StringType.Latin1), // Language ); const header = new FrameHeader(FrameIdentifiers.USER, FrameFlags.None, fieldBytes.length); - const expected = ByteVector.concatenate(header.render(4), fieldBytes); + const expected = ByteVector.concatenate(header.render(Id3v2Version.V24), fieldBytes); Testers.bvEqual(result, expected); } - @params(3, "v3") - @params(4, "v4") - public render_withText(version: number) { + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public render_withText(version: Id3v2Version) { // Arrange const frame = TermsOfUseFrame.fromFields("bar", "foo", StringType.Latin1); @@ -321,7 +321,7 @@ const assertFrame = (frame: TermsOfUseFrame, language: string, text: string, tex const frame = TermsOfUseFrame.fromFields("bar", "foo", encoding); // Act - const result = frame.render(4); + const result = frame.render(Id3v2Version.V24); // Assert const fieldBytes = ByteVector.concatenate( @@ -330,7 +330,7 @@ const assertFrame = (frame: TermsOfUseFrame, language: string, text: string, tex ByteVector.fromString("bar", encoding) // Text ); const header = new FrameHeader(FrameIdentifiers.USER, FrameFlags.None, fieldBytes.length); - const expected = ByteVector.concatenate(header.render(4), fieldBytes); + const expected = ByteVector.concatenate(header.render(Id3v2Version.V24), fieldBytes); Testers.bvEqual(result, expected); } } diff --git a/test-unit/id3v2/textInformationFrameTests.ts b/test-unit/id3v2/textInformationFrameTests.ts index 2765716b..5c85505c 100644 --- a/test-unit/id3v2/textInformationFrameTests.ts +++ b/test-unit/id3v2/textInformationFrameTests.ts @@ -9,7 +9,7 @@ import PropertyTests from "../utilities/propertyTests"; import TextInformationFrame from "../../src/id3v2/frames/textInformationFrame"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {FrameFlags} from "../../src/id3v2/enums"; +import {FrameFlags, Id3v2Version} from "../../src/id3v2/enums"; import {FrameIdentifier, FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -24,14 +24,14 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text } @suite class Id3v2_TextInformationFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: Id3v2Version) => Frame { return TextInformationFrame.fromFieldBytes; } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_empty_throws(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_empty_throws(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.empty(); const header = new FrameHeader(FrameIdentifiers.TCOP, FrameFlags.None, fieldBytes.length); @@ -40,10 +40,10 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text assert.throws(() => TextInformationFrame.fromFieldBytes(header, fieldBytes, version)); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_noText_returnsEmptyFrame(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_noText_returnsEmptyFrame(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.fromByte(StringType.UTF16BE); const header = new FrameHeader(FrameIdentifiers.TCOP, FrameFlags.None, fieldBytes.length); @@ -55,10 +55,10 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text assertFrame(frame, FrameIdentifiers.TCOP, [], StringType.UTF16BE); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_nullText_returnsEmptyFrame(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_nullText_returnsEmptyFrame(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.UTF16BE, // Encoding @@ -73,9 +73,9 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text assertFrame(frame, FrameIdentifiers.TCOP, [], StringType.UTF16BE); } - @params(2, "v2") - @params(3, "v2") - public fromFieldBytes_v3NotSplitType_returnsSingleTextField(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v2") + public fromFieldBytes_v3NotSplitType_returnsSingleTextField(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.Latin1, // Encoding @@ -90,9 +90,9 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text assertFrame(frame, FrameIdentifiers.TALB, ["fux/bux"], StringType.Latin1); } - @params(2, "v2") - @params(3, "v2") - public fromFieldBytes_v3SplitType_returnsFrameSplitBySlash(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v2") + public fromFieldBytes_v3SplitType_returnsFrameSplitBySlash(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.Latin1, // Encoding @@ -107,9 +107,9 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text assertFrame(frame, FrameIdentifiers.TCOM, ["fux", "bux"], StringType.Latin1); } - @params(2, "v2") - @params(3, "v2") - public fromFieldBytes_v3WithNullBytes_discardsDataAfterNull(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v2") + public fromFieldBytes_v3WithNullBytes_discardsDataAfterNull(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.Latin1, // Encoding @@ -139,7 +139,7 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text const header = new FrameHeader(FrameIdentifiers.TCOP, FrameFlags.None, fieldBytes.length); // Act - const frame = TextInformationFrame.fromFieldBytes(header, fieldBytes, 4); + const frame = TextInformationFrame.fromFieldBytes(header, fieldBytes, Id3v2Version.V24); // Assert assertFrame(frame,FrameIdentifiers.TCOP, ["fux", "bux"], encoding); @@ -376,10 +376,10 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text assert.deepEqual(result, [frame1, frame2]); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public render_empty_returnEmptyVector(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public render_empty_returnEmptyVector(version: Id3v2Version) { // Arrange const frame = TextInformationFrame.fromFields(FrameIdentifiers.TALB, []); @@ -391,10 +391,10 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text assert.strictEqual(result.length, 0); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public render_falsyValues_returnEmptyVector(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public render_falsyValues_returnEmptyVector(version: Id3v2Version) { // Arrange const frame = TextInformationFrame.fromFields(FrameIdentifiers.TALB, [undefined, null, ""]); @@ -413,7 +413,7 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text const frame = TextInformationFrame.fromFields(FrameIdentifiers.TALB, ["foo", "bar", "baz"], encoding); // Act - const result = frame.render(4); + const result = frame.render(Id3v2Version.V24); // Assert assert.isOk(result); @@ -427,15 +427,15 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text ByteVector.fromString("baz", encoding) // ... ); const header = new FrameHeader(FrameIdentifiers.TALB, FrameFlags.None, fieldBytes.length); - const expected = ByteVector.concatenate(header.render(4), fieldBytes); + const expected = ByteVector.concatenate(header.render(Id3v2Version.V24), fieldBytes); Testers.bvEqual(result, expected); } - @params([2, StringType.Latin1], "v2_single_byte") - @params([2, StringType.UTF16BE], "v2_multi_byte") - @params([3, StringType.Latin1], "v3_single_byte") - @params([3, StringType.UTF16BE], "v3_multi_byte") - public render_v3WithSplit([version, encoding]: [number, StringType]) { + @params([Id3v2Version.V22, StringType.Latin1], "v2_single_byte") + @params([Id3v2Version.V22, StringType.UTF16BE], "v2_multi_byte") + @params([Id3v2Version.V23, StringType.Latin1], "v3_single_byte") + @params([Id3v2Version.V23, StringType.UTF16BE], "v3_multi_byte") + public render_v3WithSplit([version, encoding]: [Id3v2Version, StringType]) { // Arrange const frame = TextInformationFrame.fromFields(FrameIdentifiers.TCOP, ["fux", "bux"], encoding); @@ -454,11 +454,11 @@ const assertFrame = (frame: TextInformationFrame, frameId: FrameIdentifier, text Testers.bvEqual(output, expected); } - @params([2, StringType.Latin1], "v2_single_byte") - @params([2, StringType.UTF16BE], "v2_multi_byte") - @params([3, StringType.Latin1], "v3_single_byte") - @params([3, StringType.UTF16BE], "v3_multi_byte") - public render_v3WithoutSplit([version, encoding]: [number, StringType]) { + @params([Id3v2Version.V22, StringType.Latin1], "v2_single_byte") + @params([Id3v2Version.V22, StringType.UTF16BE], "v2_multi_byte") + @params([Id3v2Version.V23, StringType.Latin1], "v3_single_byte") + @params([Id3v2Version.V23, StringType.UTF16BE], "v3_multi_byte") + public render_v3WithoutSplit([version, encoding]: [Id3v2Version, StringType]) { // Arrange const frame = TextInformationFrame.fromFields(FrameIdentifiers.TCOP, ["fux"], encoding); diff --git a/test-unit/id3v2/uniqueFileIdentifierFrameTests.ts b/test-unit/id3v2/uniqueFileIdentifierFrameTests.ts index 2e8b2f3a..1a64815c 100644 --- a/test-unit/id3v2/uniqueFileIdentifierFrameTests.ts +++ b/test-unit/id3v2/uniqueFileIdentifierFrameTests.ts @@ -8,7 +8,7 @@ import PropertyTests from "../utilities/propertyTests"; import UniqueFileIdentifierFrame from "../../src/id3v2/frames/uniqueFileIdentifierFrame"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {FrameFlags} from "../../src/id3v2/enums"; +import {FrameFlags, Id3v2Version} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -26,14 +26,14 @@ const assertFrame = (frame: UniqueFileIdentifierFrame, o: string, i: ByteVector) } @suite class Id3v2_UniqueFileIdentifierFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: Id3v2Version) => Frame { return UniqueFileIdentifierFrame.fromFieldBytes; } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_empty_throws(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_empty_throws(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.empty(); const header = new FrameHeader(FrameIdentifiers.UFID, FrameFlags.None, fieldBytes.length); @@ -42,10 +42,10 @@ const assertFrame = (frame: UniqueFileIdentifierFrame, o: string, i: ByteVector) assert.throws(() => UniqueFileIdentifierFrame.fromFieldBytes(header, fieldBytes, version)); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_oneField_throws(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_oneField_throws(version: Id3v2Version) { // Arrange const fieldBytes = testIdentifier; const header = new FrameHeader(FrameIdentifiers.UFID, FrameFlags.None, fieldBytes.length); @@ -54,10 +54,10 @@ const assertFrame = (frame: UniqueFileIdentifierFrame, o: string, i: ByteVector) assert.throws(() => UniqueFileIdentifierFrame.fromFieldBytes(header, fieldBytes, version)); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_threeFields(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_threeFields(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( ByteVector.fromString(testOwner, StringType.Latin1), // Owner @@ -74,10 +74,10 @@ const assertFrame = (frame: UniqueFileIdentifierFrame, o: string, i: ByteVector) assertFrame(frame, testOwner, expectedData); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_validData_returnsFrame(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_validData_returnsFrame(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( ByteVector.fromString(testOwner, StringType.Latin1), // Owner @@ -258,10 +258,10 @@ const assertFrame = (frame: UniqueFileIdentifierFrame, o: string, i: ByteVector) assert.deepEqual(result, [frame1, frame2]); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public render_returnsByteVector(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public render_returnsByteVector(version: Id3v2Version) { // Arrange const frame = UniqueFileIdentifierFrame.fromFields(testOwner, testIdentifier); diff --git a/test-unit/id3v2/unknownFrameTests.ts b/test-unit/id3v2/unknownFrameTests.ts index c359fee4..b6772d3b 100644 --- a/test-unit/id3v2/unknownFrameTests.ts +++ b/test-unit/id3v2/unknownFrameTests.ts @@ -7,7 +7,7 @@ import FrameConstructorTests from "./frameConstructorTests"; import FrameHeader from "../../src/id3v2/frames/frameHeader"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {FrameFlags} from "../../src/id3v2/enums"; +import {FrameFlags, Id3v2Version} from "../../src/id3v2/enums"; import {FrameIdentifier, FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -24,14 +24,14 @@ const assertFrame = (frame: UnknownFrame, fi: FrameIdentifier, d: ByteVector) => } @suite class Id3v2_UnknownFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: Id3v2Version) => Frame { return UnknownFrame.fromFieldBytes; } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_validParams_returnsFrame(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_validParams_returnsFrame(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.fromString("foo bar baz", StringType.UTF8); const header = new FrameHeader(FrameIdentifiers.WXXX, FrameFlags.None, fieldBytes.length); @@ -76,10 +76,10 @@ const assertFrame = (frame: UnknownFrame, fi: FrameIdentifier, d: ByteVector) => } @suite class Id3v2_UnknownFrame_MethodTests { - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public clone_returnsCopy(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public clone_returnsCopy(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.fromString("foo bar baz", StringType.UTF8); const header = new FrameHeader(FrameIdentifiers.WXXX, FrameFlags.None, fieldBytes.length); @@ -173,10 +173,10 @@ const assertFrame = (frame: UnknownFrame, fi: FrameIdentifier, d: ByteVector) => assert.deepEqual(result, [frame1, frame2]); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public render_returnsByteVector(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public render_returnsByteVector(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.fromString("foo bar baz", StringType.UTF8); const header = new FrameHeader(FrameIdentifiers.WXXX, FrameFlags.None, fieldBytes.length); diff --git a/test-unit/id3v2/unsynchronizedLyricsFrameTests.ts b/test-unit/id3v2/unsynchronizedLyricsFrameTests.ts index eb023600..af053f03 100644 --- a/test-unit/id3v2/unsynchronizedLyricsFrameTests.ts +++ b/test-unit/id3v2/unsynchronizedLyricsFrameTests.ts @@ -9,7 +9,7 @@ import PropertyTests from "../utilities/propertyTests"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import UnsynchronizedLyricsFrame from "../../src/id3v2/frames/unsynchronizedLyricsFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {FrameFlags} from "../../src/id3v2/enums"; +import {FrameFlags, Id3v2Version} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -25,14 +25,14 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: } @suite class Id3v2_UnsynchronizedLyricsFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: Id3v2Version) => Frame { return UnsynchronizedLyricsFrame.fromFieldBytes; } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_tooFewBytes_throws(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_tooFewBytes_throws(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.fromByte(StringType.Latin1); const header = new FrameHeader(FrameIdentifiers.USLT, FrameFlags.None, fieldBytes.length); @@ -41,10 +41,10 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: assert.throws(() => { UnsynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, version); }); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_requiredBytesOnly(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_requiredBytesOnly(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.Latin1, // Encoding @@ -59,10 +59,10 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: assertFrame(frame, "", "eng", "", StringType.Latin1); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_descriptionOnly(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_descriptionOnly(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.Latin1, // Encoding @@ -78,10 +78,10 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: assertFrame(frame, "", "eng", "foobarbaz", StringType.Latin1); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_lyricsOnly(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_lyricsOnly(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.Latin1, // Encoding @@ -98,10 +98,10 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: assertFrame(frame, "", "eng", "foobarbaz", StringType.Latin1); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_descriptionAndLyrics(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_descriptionAndLyrics(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.Latin1, // Encoding @@ -133,7 +133,7 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: const header = new FrameHeader(FrameIdentifiers.USLT, FrameFlags.None, fieldBytes.length); // Act - const frame = UnsynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, 4); + const frame = UnsynchronizedLyricsFrame.fromFieldBytes(header, fieldBytes, Id3v2Version.V24); // Assert assertFrame(frame, "foo", "eng", "bar", encoding); @@ -335,13 +335,13 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: assert.deepEqual(result, [frame1, frame2]); } - @params([2, StringType.Latin1], "v2_single_byte") - @params([2, StringType.UTF16BE], "v2_multibyte") - @params([3, StringType.Latin1], "v3_single_byte") - @params([3, StringType.UTF16BE], "v3_multibyte") - @params([4, StringType.Latin1], "v4_single_byte") - @params([4, StringType.UTF16BE], "v4_multibyte") - public render([version, encoding]: [number, StringType]) { + @params([Id3v2Version.V22, StringType.Latin1], "v2_single_byte") + @params([Id3v2Version.V22, StringType.UTF16BE], "v2_multibyte") + @params([Id3v2Version.V23, StringType.Latin1], "v3_single_byte") + @params([Id3v2Version.V23, StringType.UTF16BE], "v3_multibyte") + @params([Id3v2Version.V24, StringType.Latin1], "v4_single_byte") + @params([Id3v2Version.V24, StringType.UTF16BE], "v4_multibyte") + public render([version, encoding]: [Id3v2Version, StringType]) { // Arrange const frame = UnsynchronizedLyricsFrame.fromFields("foo", "bar", "eng", encoding); @@ -363,10 +363,10 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: Testers.bvEqual(output, expectedBytes); } - @params([2, StringType.UTF16], "v2") - @params([3, StringType.UTF16], "v3") - @params([4, StringType.UTF8], "v4") - public render_utf8([version, outputEncoding]: [number, StringType]) { + @params([Id3v2Version.V22, StringType.UTF16], "v2") + @params([Id3v2Version.V23, StringType.UTF16], "v3") + @params([Id3v2Version.V24, StringType.UTF8], "v4") + public render_utf8([version, outputEncoding]: [Id3v2Version, StringType]) { // Arrange const frame = UnsynchronizedLyricsFrame.fromFields("foo", "bar", "eng", StringType.UTF8); @@ -394,7 +394,7 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: const frame = UnsynchronizedLyricsFrame.fromFields("foo", undefined, "eng", StringType.Latin1); // Act - const result = frame.render(4); + const result = frame.render(Id3v2Version.V24); // Assert assert.isOk(result); @@ -406,7 +406,7 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: ByteVector.getTextDelimiter(StringType.Latin1), // Delimiter ); const header = new FrameHeader(FrameIdentifiers.USLT, FrameFlags.None, expectedFieldBytes.length); - const expectedBytes = ByteVector.concatenate(header.render(4), expectedFieldBytes); + const expectedBytes = ByteVector.concatenate(header.render(Id3v2Version.V24), expectedFieldBytes); Testers.bvEqual(result, expectedBytes); } @@ -416,7 +416,7 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: const frame = UnsynchronizedLyricsFrame.fromFields("", "foo", "eng", StringType.Latin1); // Act - const result = frame.render(4); + const result = frame.render(Id3v2Version.V24); // Assert assert.isOk(result); @@ -428,7 +428,7 @@ const assertFrame = (frame: UnsynchronizedLyricsFrame, d: string, l: string, t: ByteVector.fromString("foo", StringType.Latin1), // Lyrics ); const header = new FrameHeader(FrameIdentifiers.USLT, FrameFlags.None, expectedFieldBytes.length); - const expectedBytes = ByteVector.concatenate(header.render(4), expectedFieldBytes); + const expectedBytes = ByteVector.concatenate(header.render(Id3v2Version.V24), expectedFieldBytes); Testers.bvEqual(result, expectedBytes); } } diff --git a/test-unit/id3v2/urlLinkFrameTests.ts b/test-unit/id3v2/urlLinkFrameTests.ts index 2a0617dd..5ab32c76 100644 --- a/test-unit/id3v2/urlLinkFrameTests.ts +++ b/test-unit/id3v2/urlLinkFrameTests.ts @@ -7,7 +7,7 @@ import FrameHeader from "../../src/id3v2/frames/frameHeader"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import UrlLinkFrame from "../../src/id3v2/frames/urlLinkFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {FrameFlags} from "../../src/id3v2/enums"; +import {FrameFlags, Id3v2Version} from "../../src/id3v2/enums"; import {FrameIdentifier, FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -19,14 +19,14 @@ const assertFrame = (frame: UrlLinkFrame, identifier: FrameIdentifier, text: str } @suite class Id3v2_UrlLinkFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: Id3v2Version) => Frame { return UrlLinkFrame.fromFieldBytes; } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_itsGood(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_itsGood(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.fromString("foo", StringType.Latin1); const header = new FrameHeader(FrameIdentifiers.WCOM, FrameFlags.None, fieldBytes.length); @@ -38,10 +38,10 @@ const assertFrame = (frame: UrlLinkFrame, identifier: FrameIdentifier, text: str assertFrame(output, FrameIdentifiers.WCOM, "foo"); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_trailingNullBytes(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_trailingNullBytes(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( ByteVector.fromString("foo", StringType.Latin1), @@ -56,10 +56,10 @@ const assertFrame = (frame: UrlLinkFrame, identifier: FrameIdentifier, text: str assertFrame(output, FrameIdentifiers.WCOM, "foo"); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_multipleFields(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_multipleFields(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( ByteVector.fromString("foo", StringType.Latin1), @@ -293,7 +293,7 @@ const assertFrame = (frame: UrlLinkFrame, identifier: FrameIdentifier, text: str const frame = UrlLinkFrame.fromFields(FrameIdentifiers.WCOM); // Act - const result = frame.render(4); + const result = frame.render(Id3v2Version.V24); // Assert assert.isOk(result); @@ -306,14 +306,14 @@ const assertFrame = (frame: UrlLinkFrame, identifier: FrameIdentifier, text: str const frame = UrlLinkFrame.fromFields(FrameIdentifiers.WCOM, "foo"); // Act - const result = frame.render(4); + const result = frame.render(Id3v2Version.V24); // Assert assert.isOk(result); const expectedBytes = ByteVector.concatenate( - FrameIdentifiers.WCOM.render(4), - ByteVector.fromUint(3), + FrameIdentifiers.WCOM.render(Id3v2Version.V24), + ByteVector.fromUint(Id3v2Version.V23), ByteVector.fromUshort(FrameFlags.None), ByteVector.fromString("foo", StringType.Latin1) ); diff --git a/test-unit/id3v2/userTextInformationFrameTests.ts b/test-unit/id3v2/userTextInformationFrameTests.ts index 4a4602d3..eeb1ea7c 100644 --- a/test-unit/id3v2/userTextInformationFrameTests.ts +++ b/test-unit/id3v2/userTextInformationFrameTests.ts @@ -8,7 +8,7 @@ import Id3v2Settings from "../../src/id3v2/id3v2Settings"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import UserTextInformationFrame from "../../src/id3v2/frames/userTextInformationFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {FrameFlags} from "../../src/id3v2/enums"; +import {FrameFlags, Id3v2Version} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -29,14 +29,14 @@ const assertFrame = ( } @suite class Id3v2_UserInformationFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: Id3v2Version) => Frame { return UserTextInformationFrame.fromFieldBytes; } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_emptyFrame_throw(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_emptyFrame_throw(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.empty(); const header = new FrameHeader(FrameIdentifiers.TXXX, FrameFlags.None, fieldBytes.length); @@ -45,10 +45,10 @@ const assertFrame = ( assert.throws(() => UserTextInformationFrame.fromFieldBytes(header, fieldBytes, version)); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_encodingOnly(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_encodingOnly(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.fromByte(StringType.UTF16LE); const header = new FrameHeader(FrameIdentifiers.TXXX, FrameFlags.None, fieldBytes.length); @@ -60,10 +60,10 @@ const assertFrame = ( assertFrame(frame, "", [], StringType.UTF16LE); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_illFormedOneField(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_illFormedOneField(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.UTF16BE, @@ -78,10 +78,10 @@ const assertFrame = ( assertFrame(output, "", ["foo"], StringType.UTF16BE); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_illFormedThreeFields(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_illFormedThreeFields(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.UTF16BE, @@ -100,10 +100,10 @@ const assertFrame = ( assertFrame(output, "foo", ["bar", "baz"], StringType.UTF16BE); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_wellFormed(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_wellFormed(version: Id3v2Version) { // Assert const fieldData = ByteVector.concatenate( StringType.Latin1, @@ -133,7 +133,7 @@ const assertFrame = ( const header = new FrameHeader(FrameIdentifiers.TXXX, FrameFlags.None, fieldBytes.length); // Act - const output = UserTextInformationFrame.fromFieldBytes(header, fieldBytes, 4); + const output = UserTextInformationFrame.fromFieldBytes(header, fieldBytes, Id3v2Version.V24); // Assert assertFrame(output, "foo", ["bar"], encoding); @@ -322,13 +322,13 @@ const assertFrame = ( const frame = UserTextInformationFrame.fromFields("foo", ["bar", "baz"], StringType.Latin1); // Act - const result = frame.render(4); + const result = frame.render(Id3v2Version.V24); // Assert assert.isOk(result); const expected = ByteVector.concatenate( - FrameIdentifiers.TXXX.render(4), + FrameIdentifiers.TXXX.render(Id3v2Version.V24), ByteVector.fromUint(12), ByteVector.fromUshort(FrameFlags.None), StringType.Latin1, @@ -347,7 +347,7 @@ const assertFrame = ( const frame = UserTextInformationFrame.fromFields(undefined, undefined, StringType.Latin1); // Act - const result = frame.render(4); + const result = frame.render(Id3v2Version.V24); // Assert assert.isOk(result); @@ -360,13 +360,13 @@ const assertFrame = ( const frame = UserTextInformationFrame.fromFields(undefined, ["foo"], StringType.Latin1); // Act - const result = frame.render(4); + const result = frame.render(Id3v2Version.V24); // Assert assert.isOk(result); const expected = ByteVector.concatenate( - FrameIdentifiers.TXXX.render(4), + FrameIdentifiers.TXXX.render(Id3v2Version.V24), ByteVector.fromUint(5), ByteVector.fromUshort(FrameFlags.None), StringType.Latin1, @@ -382,13 +382,13 @@ const assertFrame = ( const frame = UserTextInformationFrame.fromFields("foo", undefined, StringType.Latin1); // Act - const result = frame.render(4); + const result = frame.render(Id3v2Version.V24); // Assert assert.isOk(result); const expected = ByteVector.concatenate( - FrameIdentifiers.TXXX.render(4), + FrameIdentifiers.TXXX.render(Id3v2Version.V24), ByteVector.fromUint(5), ByteVector.fromUshort(FrameFlags.None), StringType.Latin1, @@ -405,13 +405,13 @@ const assertFrame = ( frame.text = ["bar"]; // Act - const result = frame.render(4); + const result = frame.render(Id3v2Version.V24); // Assert assert.isOk(result); const expected = ByteVector.concatenate( - FrameIdentifiers.TXXX.render(4), + FrameIdentifiers.TXXX.render(Id3v2Version.V24), ByteVector.fromUint(15), ByteVector.fromUshort(FrameFlags.None), StringType.UTF16LE, diff --git a/test-unit/id3v2/userUrlLinkFrameTests.ts b/test-unit/id3v2/userUrlLinkFrameTests.ts index 83f878b5..136e4e0d 100644 --- a/test-unit/id3v2/userUrlLinkFrameTests.ts +++ b/test-unit/id3v2/userUrlLinkFrameTests.ts @@ -8,7 +8,7 @@ import Id3v2Settings from "../../src/id3v2/id3v2Settings"; import UnknownFrame from "../../src/id3v2/frames/unknownFrame"; import UserUrlLinkFrame from "../../src/id3v2/frames/userUrlLinkFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {FrameFlags} from "../../src/id3v2/enums"; +import {FrameFlags, Id3v2Version} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; @@ -23,7 +23,7 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, } @suite class Id3v2_UserUrlLinkFrame_ConstructorTests extends FrameConstructorTests { - public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame { + public get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: Id3v2Version) => Frame { return UserUrlLinkFrame.fromFieldBytes; } @@ -40,10 +40,10 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, assert.strictEqual(frame.textEncoding, Id3v2Settings.defaultEncoding); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_tooSmall(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_tooSmall(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.fromSize(1); const header = new FrameHeader(FrameIdentifiers.WXXX, FrameFlags.None, fieldBytes.length); @@ -52,10 +52,10 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, assert.throws(() => UserUrlLinkFrame.fromFieldBytes(header, fieldBytes, version)); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_illFormedTagLib(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_illFormedTagLib(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.Latin1, @@ -70,10 +70,10 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, assertFrame(output, "foo", "bar", StringType.Latin1); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_illFormedOneField(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_illFormedOneField(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.UTF16BE, @@ -88,10 +88,10 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, assertFrame(output, "", "foo", StringType.UTF16BE); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_illFormedThreeFields(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_illFormedThreeFields(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.UTF16BE, // Encoding @@ -111,10 +111,10 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, assertFrame(output, "foo", "bar", StringType.UTF16BE); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public fromFieldBytes_wellFormed(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public fromFieldBytes_wellFormed(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.concatenate( StringType.Latin1, @@ -144,7 +144,7 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, const header = new FrameHeader(FrameIdentifiers.WXXX, FrameFlags.None, fieldBytes.length); // Act - const output = UserUrlLinkFrame.fromFieldBytes(header, fieldBytes, 4); + const output = UserUrlLinkFrame.fromFieldBytes(header, fieldBytes, Id3v2Version.V24); // Assert assertFrame(output, "foo", "bar", encoding); @@ -299,7 +299,7 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, frame.textEncoding = StringType.Latin1; // Act - const result = frame.render(4); + const result = frame.render(Id3v2Version.V24); // Assert assert.isOk(result); @@ -313,13 +313,13 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, frame.textEncoding = StringType.Latin1; // Act - const result = frame.render(4); + const result = frame.render(Id3v2Version.V24); // Assert assert.isOk(result); const expectedBytes = ByteVector.concatenate( - FrameIdentifiers.WXXX.render(4), + FrameIdentifiers.WXXX.render(Id3v2Version.V24), ByteVector.fromUint(5), ByteVector.fromUshort(FrameFlags.None), ByteVector.fromByte(StringType.Latin1), @@ -336,13 +336,13 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, frame.textEncoding = StringType.Latin1; // Act - const result = frame.render(4); + const result = frame.render(Id3v2Version.V24); // Assert assert.isOk(result); const expectedBytes = ByteVector.concatenate( - FrameIdentifiers.WXXX.render(4), + FrameIdentifiers.WXXX.render(Id3v2Version.V24), ByteVector.fromUint(5), ByteVector.fromUshort(FrameFlags.None), ByteVector.fromByte(StringType.Latin1), @@ -359,13 +359,13 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, frame.textEncoding = StringType.Latin1; // Act - const result = frame.render(4); + const result = frame.render(Id3v2Version.V24); // Assert assert.isOk(result); const expectedBytes = ByteVector.concatenate( - FrameIdentifiers.WXXX.render(4), + FrameIdentifiers.WXXX.render(Id3v2Version.V24), ByteVector.fromUint(8), ByteVector.fromUshort(FrameFlags.None), ByteVector.fromByte(StringType.Latin1), @@ -383,13 +383,13 @@ const assertFrame = (frame: UserUrlLinkFrame, description: string, text: string, frame.textEncoding = StringType.UTF16LE // Act - const result = frame.render(4); + const result = frame.render(Id3v2Version.V24); // Assert assert.isOk(result); const expectedBytes = ByteVector.concatenate( - FrameIdentifiers.WXXX.render(4), + FrameIdentifiers.WXXX.render(Id3v2Version.V24), ByteVector.fromUint(12), ByteVector.fromUshort(FrameFlags.None), ByteVector.fromByte(StringType.UTF16LE), From 1566e0f71ca2b2d5fcc594006a95ebf7985be294 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Sat, 8 Aug 2026 15:09:24 -0500 Subject: [PATCH 16/18] The rest of them, and cleanup the id3v2 tests --- src/id3v2/frames/frameFactory.ts | 16 +- test-unit/id3v2/attachmentsFrameTests.ts | 2 +- test-unit/id3v2/commentsFrameTests.ts | 4 +- test-unit/id3v2/eventTimeCodeFrameTests.ts | 4 +- test-unit/id3v2/frameConstructorTests.ts | 7 +- test-unit/id3v2/frameFactoryTests.ts | 407 +++++++++--------- test-unit/id3v2/frameHeaderTests.ts | 2 +- test-unit/id3v2/genreFrameTests.ts | 4 +- .../id3v2/musicCdIdentifierFrameTests.ts | 2 +- test-unit/id3v2/relativeVolumeFrameTests.ts | 2 +- test-unit/id3v2/tagHeaderTests.ts | 14 +- 11 files changed, 244 insertions(+), 220 deletions(-) diff --git a/src/id3v2/frames/frameFactory.ts b/src/id3v2/frames/frameFactory.ts index 763e396c..2400d413 100644 --- a/src/id3v2/frames/frameFactory.ts +++ b/src/id3v2/frames/frameFactory.ts @@ -20,7 +20,7 @@ import {ByteVector} from "../../byteVector"; import {CorruptFileError, NotImplementedError} from "../../errors"; import {EventTimeCodeFrame} from "./eventTimeCodeFrame"; import {File} from "../../file"; -import {FrameFlags} from "../enums"; +import {FrameFlags, Id3v2Version} from "../enums"; import {FrameIdentifier, FrameIdentifiers} from "../frameIdentifiers"; import {RelativeVolumeFrame} from "./relativeVolumeFrame"; import {SynchronizedLyricsFrame} from "./synchronizedLyricsFrame"; @@ -33,9 +33,9 @@ import {Guards, NumberUtils} from "../../utils"; * @param header The header that describes the frame. * @param version ID3v2 version the frame is encoded with. Must be unsigned 8-bit int */ -export type FrameCreator = (data: ByteVector, offset: number, header: FrameHeader, version: number) => Frame; +export type FrameCreator = (data: ByteVector, offset: number, header: FrameHeader, version: Id3v2Version) => Frame; -type InternalFrameCreator = (header: FrameHeader, fieldBytes: ByteVector, version: number) => Frame; +type InternalFrameCreator = (header: FrameHeader, fieldBytes: ByteVector, version: Id3v2Version) => Frame; /** * Performs the necessary operations to determine and create the correct child classes of @@ -95,7 +95,7 @@ export class Id3v2FrameFactory { * Creates a {@link Frame} object by reading it from a file. * @param file File that contains at least one frame * @param offset Index into the data block where the frame header begins - * @param version ID3v2 version the frame is encoded with. Must be unsigned 8-bit int + * @param version ID3v2 version the frame is encoded with * @param unsyncedAtTagLevel Whether the entire tag has already been unsynchronized * @returns Frame|undefined * Frame read from the file is returned if it was read, `undefined` is returned if no frame @@ -104,7 +104,7 @@ export class Id3v2FrameFactory { public static createFrameFromFile( file: File, offset: number, - version: number, + version: Id3v2Version, unsyncedAtTagLevel: boolean ): {frame: Frame, totalSize: number}|undefined { Guards.truthy(file, "file"); @@ -141,7 +141,7 @@ export class Id3v2FrameFactory { * Creates a {@link Frame} object by reading it from raw frame data. * @param data Block of data containing at least one frame. * @param offset Index into the data block where the frame header begins. - * @param version ID3v2 version the frame is encoded with. Must be unsigned 8-bit int + * @param version ID3v2 version the frame is encoded with * @param unsyncedAtTagLevel Whether the entire tag has already been unsynchronized * @returns Frame|undefined * Frame read from the file is returned if it was read, `undefined` is returned if no frame @@ -150,7 +150,7 @@ export class Id3v2FrameFactory { public static createFrameFromTagBytes( data: ByteVector, offset: number, - version: number, + version: Id3v2Version, unsyncedAtTagLevel: boolean ): {frame: Frame, totalSize: number}|undefined { Guards.truthy(data, "data"); @@ -196,7 +196,7 @@ export class Id3v2FrameFactory { private static createFrameFromFieldBytes( header: FrameHeader, payloadBytes: ByteVector, - version: number, + version: Id3v2Version, unsynchedAtTagLevel: boolean ): Frame { // Make sure we got the same number of bytes as the frame says diff --git a/test-unit/id3v2/attachmentsFrameTests.ts b/test-unit/id3v2/attachmentsFrameTests.ts index 606f3b77..5d9a9016 100644 --- a/test-unit/id3v2/attachmentsFrameTests.ts +++ b/test-unit/id3v2/attachmentsFrameTests.ts @@ -214,7 +214,7 @@ const verifyFrame = ( const header = new FrameHeader(FrameIdentifiers.APIC, FrameFlags.None, fieldBytes.length); // Act - const frame = AttachmentFrame.fromFieldBytes(header, fieldBytes, 2); + const frame = AttachmentFrame.fromFieldBytes(header, fieldBytes, Id3v2Version.V22); // Assert verifyFrame( diff --git a/test-unit/id3v2/commentsFrameTests.ts b/test-unit/id3v2/commentsFrameTests.ts index 788e7705..d135378c 100644 --- a/test-unit/id3v2/commentsFrameTests.ts +++ b/test-unit/id3v2/commentsFrameTests.ts @@ -340,7 +340,7 @@ const verifyFrame = ( @params([Id3v2Version.V23, StringType.UTF16BE], "v3_multibyte") @params([Id3v2Version.V24, StringType.Latin1], "v4_single_byte") @params([Id3v2Version.V24, StringType.UTF16BE], "v4_multibyte") - public render([version, encoding]: [number, StringType]) { + public render([version, encoding]: [Id3v2Version, StringType]) { // Arrange const frame = CommentsFrame.fromFields("bar", "foo", "eng", encoding); @@ -365,7 +365,7 @@ const verifyFrame = ( @params([Id3v2Version.V22, StringType.UTF16], "v2") @params([Id3v2Version.V23, StringType.UTF16], "v3") @params([Id3v2Version.V24, StringType.UTF8], "v4") - public render_utf8([version, outputEncoding]: [number, StringType]) { + public render_utf8([version, outputEncoding]: [Id3v2Version, StringType]) { // Arrange const frame = CommentsFrame.fromFields("bar", "foo", "eng", StringType.UTF8); diff --git a/test-unit/id3v2/eventTimeCodeFrameTests.ts b/test-unit/id3v2/eventTimeCodeFrameTests.ts index f225fd16..bd921a37 100644 --- a/test-unit/id3v2/eventTimeCodeFrameTests.ts +++ b/test-unit/id3v2/eventTimeCodeFrameTests.ts @@ -133,7 +133,7 @@ const assertFrame = (frame: EventTimeCodeFrame, e: EventTimeCode[], t: Timestamp @params(Id3v2Version.V22, "v2") @params(Id3v2Version.V23, "v3") @params(Id3v2Version.V24, "v4") - public fromFieldBytes_withEvents(version: number) { + public fromFieldBytes_withEvents(version: Id3v2Version) { // Arrange const event1 = new EventTimeCode(EventType.Profanity, 123); const event2 = new EventTimeCode(EventType.KeyChange, 456); @@ -154,7 +154,7 @@ const assertFrame = (frame: EventTimeCodeFrame, e: EventTimeCode[], t: Timestamp @params(Id3v2Version.V22, "v2") @params(Id3v2Version.V23, "v3") @params(Id3v2Version.V24, "v4") - public fromFieldBytes_incompleteEvent(version: number) { + public fromFieldBytes_incompleteEvent(version: Id3v2Version) { // Arrange const event1 = new EventTimeCode(EventType.Profanity, 123); const event2 = new EventTimeCode(EventType.KeyChange, 456); diff --git a/test-unit/id3v2/frameConstructorTests.ts b/test-unit/id3v2/frameConstructorTests.ts index 26eeac97..00e008b5 100644 --- a/test-unit/id3v2/frameConstructorTests.ts +++ b/test-unit/id3v2/frameConstructorTests.ts @@ -3,12 +3,13 @@ import {test} from "@testdeck/mocha"; import Frame from "../../src/id3v2/frames/frame"; import FrameHeader from "../../src/id3v2/frames/frameHeader"; import {ByteVector} from "../../src/byteVector"; +import {Id3v2Version} from "../../src/id3v2/enums"; import {FrameIdentifiers} from "../../src/id3v2/frameIdentifiers"; import {Testers} from "../utilities/testers"; export default abstract class FrameConstructorTests { - public abstract get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: number) => Frame; + public abstract get fromFieldBytes(): (h: FrameHeader, d: ByteVector, v: Id3v2Version) => Frame; @test public fromFieldBytes_falsyHeader_throws() { @@ -16,7 +17,7 @@ export default abstract class FrameConstructorTests { const data = ByteVector.empty(); // Act/Assert - Testers.testTruthy((v: FrameHeader) => { this.fromFieldBytes(v, data, 4); }); + Testers.testTruthy((v: FrameHeader) => { this.fromFieldBytes(v, data, Id3v2Version.V24); }); } @test @@ -25,6 +26,6 @@ export default abstract class FrameConstructorTests { const header = new FrameHeader(FrameIdentifiers.WCOM); // Act/Assert - Testers.testTruthy((v: ByteVector) => { this.fromFieldBytes(header, v, 4); }); + Testers.testTruthy((v: ByteVector) => { this.fromFieldBytes(header, v, Id3v2Version.V24); }); } } diff --git a/test-unit/id3v2/frameFactoryTests.ts b/test-unit/id3v2/frameFactoryTests.ts index 9efb163c..b1018cce 100644 --- a/test-unit/id3v2/frameFactoryTests.ts +++ b/test-unit/id3v2/frameFactoryTests.ts @@ -20,7 +20,7 @@ import UrlLinkFrame from "../../src/id3v2/frames/urlLinkFrame"; import UserTextInformationFrame from "../../src/id3v2/frames/userTextInformationFrame"; import UserUrlLinkFrame from "../../src/id3v2/frames/userUrlLinkFrame"; import {ByteVector, StringType} from "../../src/byteVector"; -import {FrameFlags, TimestampFormat} from "../../src/id3v2/enums"; +import {FrameFlags, Id3v2Version, TimestampFormat} from "../../src/id3v2/enums"; import {EventTimeCodeFrame} from "../../src/id3v2/frames/eventTimeCodeFrame"; import {File} from "../../src/file"; import {FrameCreator, Id3v2FrameFactory} from "../../src/id3v2/frames/frameFactory"; @@ -57,7 +57,7 @@ import {NumberUtils} from "../../src/utils"; @test public createFrameFromFile_falsyFile() { // Act / Assert - Testers.testTruthy((v: File) => Id3v2FrameFactory.createFrameFromFile(v, 123, 4, false)); + Testers.testTruthy((v: File) => Id3v2FrameFactory.createFrameFromFile(v, 123, Id3v2Version.V24, false)); } @test @@ -66,7 +66,7 @@ import {NumberUtils} from "../../src/utils"; const file = TestFile.mockFile(); // Act / Assert - Testers.testSafeUint((v) => Id3v2FrameFactory.createFrameFromFile(file, v, 4, false)); + Testers.testSafeUint((v) => Id3v2FrameFactory.createFrameFromFile(file, v, Id3v2Version.V24, false)); } @test @@ -78,10 +78,10 @@ import {NumberUtils} from "../../src/utils"; Testers.testByte((v) => Id3v2FrameFactory.createFrameFromFile(file, 0, v, false)); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public createFrameFromFile_noHeader(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public createFrameFromFile_noHeader(version: Id3v2Version) { // Arrange const size = FrameHeader.getBaseSize(version); const data = ByteVector.fromSize(size - 1); @@ -91,10 +91,10 @@ import {NumberUtils} from "../../src/utils"; assert.throws(() => Id3v2FrameFactory.createFrameFromFile(file, 0, version, false)); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public createFrameFromFile_noHeaderAfterOffset(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public createFrameFromFile_noHeaderAfterOffset(version: Id3v2Version) { // Arrange const size = FrameHeader.getBaseSize(version); const data = ByteVector.fromSize(size + 9, 0x00); @@ -104,10 +104,10 @@ import {NumberUtils} from "../../src/utils"; assert.throws(() => Id3v2FrameFactory.createFrameFromFile(file, 10, version, false)); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public createFrameFromFile_padding(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public createFrameFromFile_padding(version: Id3v2Version) { // Arrange const size = FrameHeader.getBaseSize(version); const data = ByteVector.fromSize(size + 1, 0x00); @@ -129,36 +129,36 @@ import {NumberUtils} from "../../src/utils"; ); // Act - const output = Id3v2FrameFactory.createFrameFromFile(file, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, AttachmentFrame, 4); + FrameFactoryTests.validateOutput(output, AttachmentFrame, Id3v2Version.V24); } @test public createFrameFromFile_comm() { // Arrange - const data = CommentsFrame.fromFields("foo", "bar").render(4); + const data = CommentsFrame.fromFields("foo", "bar").render(Id3v2Version.V24); const file = TestFile.getFile(data); // Act - const output = Id3v2FrameFactory.createFrameFromFile(file, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, CommentsFrame, 4); + FrameFactoryTests.validateOutput(output, CommentsFrame, Id3v2Version.V24); } @test public createFrameFromFile_etco() { // Arrange - const data = EventTimeCodeFrame.fromFields(TimestampFormat.AbsoluteMilliseconds).render(4); + const data = EventTimeCodeFrame.fromFields(TimestampFormat.AbsoluteMilliseconds).render(Id3v2Version.V24); const file = TestFile.getFile(data); // Act - const output = Id3v2FrameFactory.createFrameFromFile(file, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, EventTimeCodeFrame, 4); + FrameFactoryTests.validateOutput(output, EventTimeCodeFrame, Id3v2Version.V24); } @test @@ -170,10 +170,10 @@ import {NumberUtils} from "../../src/utils"; ); // Act - const output = Id3v2FrameFactory.createFrameFromFile(file, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, AttachmentFrame, 4); + FrameFactoryTests.validateOutput(output, AttachmentFrame, Id3v2Version.V24); } @test @@ -185,114 +185,114 @@ import {NumberUtils} from "../../src/utils"; ); // Act - const output = Id3v2FrameFactory.createFrameFromFile(file, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, MusicCdIdentifierFrame, 4); + FrameFactoryTests.validateOutput(output, MusicCdIdentifierFrame, Id3v2Version.V24); } @test public createFrameFromFile_pcnt() { // Arrange - const data = PlayCountFrame.fromFields(BigInt(123)).render(4); + const data = PlayCountFrame.fromFields(BigInt(123)).render(Id3v2Version.V24); const file = TestFile.getFile(data); // Act - const output = Id3v2FrameFactory.createFrameFromFile(file, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, PlayCountFrame, 4); + FrameFactoryTests.validateOutput(output, PlayCountFrame, Id3v2Version.V24); } @test public createFrameFromFile_popm() { // Arrange - const data = PopularimeterFrame.fromFields("foo", 123).render(4); + const data = PopularimeterFrame.fromFields("foo", 123).render(Id3v2Version.V24); const file = TestFile.getFile(data); // Act - const output = Id3v2FrameFactory.createFrameFromFile(file, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, PopularimeterFrame, 4); + FrameFactoryTests.validateOutput(output, PopularimeterFrame, Id3v2Version.V24); } @test public createFrameFromFile_priv() { // Arrange - const data = PrivateFrame.fromFields("foo", ByteVector.fromUint(123)).render(4); + const data = PrivateFrame.fromFields("foo", ByteVector.fromUint(123)).render(Id3v2Version.V24); const file = TestFile.getFile(data); // Act - const output = Id3v2FrameFactory.createFrameFromFile(file, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, PrivateFrame, 4); + FrameFactoryTests.validateOutput(output, PrivateFrame, Id3v2Version.V24); } @test public createFrameFromFile_rva2() { // Arrange - const data = RelativeVolumeFrame.fromFields("foo").render(4); + const data = RelativeVolumeFrame.fromFields("foo").render(Id3v2Version.V24); const file = TestFile.getFile(data); // Act - const output = Id3v2FrameFactory.createFrameFromFile(file, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, RelativeVolumeFrame, 4); + FrameFactoryTests.validateOutput(output, RelativeVolumeFrame, Id3v2Version.V24); } @test public createFrameFromFrame_sylt() { // Arrange - const data = SynchronizedLyricsFrame.fromFields("foo").render(4); + const data = SynchronizedLyricsFrame.fromFields("foo").render(Id3v2Version.V24); const file = TestFile.getFile(data); // Act - const output = Id3v2FrameFactory.createFrameFromFile(file, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, SynchronizedLyricsFrame, 4); + FrameFactoryTests.validateOutput(output, SynchronizedLyricsFrame, Id3v2Version.V24); } @test public createFrameFromFile_textFrame() { // Arrange - const data = TextInformationFrame.fromFields(FrameIdentifiers.TCOM, ["foo"]).render(4); + const data = TextInformationFrame.fromFields(FrameIdentifiers.TCOM, ["foo"]).render(Id3v2Version.V24); const file = TestFile.getFile(data); // Act - const output = Id3v2FrameFactory.createFrameFromFile(file, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, TextInformationFrame, 4); + FrameFactoryTests.validateOutput(output, TextInformationFrame, Id3v2Version.V24); } @test public createFrameFromFile_txxx() { // Arrange - const data = UserTextInformationFrame.fromFields("foo", ["foo"]).render(4); + const data = UserTextInformationFrame.fromFields("foo", ["foo"]).render(Id3v2Version.V24); const file = TestFile.getFile(data); // Act - const output = Id3v2FrameFactory.createFrameFromFile(file, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, UserTextInformationFrame, 4); + FrameFactoryTests.validateOutput(output, UserTextInformationFrame, Id3v2Version.V24); } @test public createFrameFromFile_ufid() { // Arrange - const data = UniqueFileIdentifierFrame.fromFields("foo", ByteVector.fromByte(0x05)).render(4); + const data = UniqueFileIdentifierFrame.fromFields("foo", ByteVector.fromByte(0x05)).render(Id3v2Version.V24); const file = TestFile.getFile(data); // Act - const output = Id3v2FrameFactory.createFrameFromFile(file, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, UniqueFileIdentifierFrame, 4); + FrameFactoryTests.validateOutput(output, UniqueFileIdentifierFrame, Id3v2Version.V24); } @test @@ -300,15 +300,15 @@ import {NumberUtils} from "../../src/utils"; // Arrange const data = ByteVector.concatenate( 0x00, 0x00, - UniqueFileIdentifierFrame.fromFields("foo", ByteVector.fromByte(0x05)).render(4) + UniqueFileIdentifierFrame.fromFields("foo", ByteVector.fromByte(0x05)).render(Id3v2Version.V24) ); const file = TestFile.getFile(data); // Act - const output = Id3v2FrameFactory.createFrameFromFile(file, 2, 4, false); + const output = Id3v2FrameFactory.createFrameFromFile(file, 2, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, UniqueFileIdentifierFrame, 4); + FrameFactoryTests.validateOutput(output, UniqueFileIdentifierFrame, Id3v2Version.V24); } @test @@ -320,62 +320,62 @@ import {NumberUtils} from "../../src/utils"; ); // Act - const output = Id3v2FrameFactory.createFrameFromFile(file, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, UnknownFrame, 4); + FrameFactoryTests.validateOutput(output, UnknownFrame, Id3v2Version.V24); } @test public createFrameFromFile_urlFrame() { // Arrange - const data = UrlLinkFrame.fromFields(FrameIdentifiers.WCOM, "foo").render(4); + const data = UrlLinkFrame.fromFields(FrameIdentifiers.WCOM, "foo").render(Id3v2Version.V24); const file = TestFile.getFile(data); // Act - const output = Id3v2FrameFactory.createFrameFromFile(file, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, UrlLinkFrame, 4); + FrameFactoryTests.validateOutput(output, UrlLinkFrame, Id3v2Version.V24); } @test public createFrameFromFile_user() { // Arrange - const data = TermsOfUseFrame.fromFields("foo").render(4); + const data = TermsOfUseFrame.fromFields("foo").render(Id3v2Version.V24); const file = TestFile.getFile(data); // Act - const output = Id3v2FrameFactory.createFrameFromFile(file, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, TermsOfUseFrame, 4); + FrameFactoryTests.validateOutput(output, TermsOfUseFrame, Id3v2Version.V24); } @test public createFrameFromFile_uslt() { // Arrange - const data = UnsynchronizedLyricsFrame.fromFields("foo", "bar").render(4); + const data = UnsynchronizedLyricsFrame.fromFields("foo", "bar").render(Id3v2Version.V24); const file = TestFile.getFile(data); // Act - const output = Id3v2FrameFactory.createFrameFromFile(file, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, UnsynchronizedLyricsFrame, 4); + FrameFactoryTests.validateOutput(output, UnsynchronizedLyricsFrame, Id3v2Version.V24); } @test public createFrameFromFile_wxxx() { // Arrange - const data = UserUrlLinkFrame.fromFields("foo", "bar").render(4); + const data = UserUrlLinkFrame.fromFields("foo", "bar").render(Id3v2Version.V24); const file = TestFile.getFile(data); // Act - const output = Id3v2FrameFactory.createFrameFromFile(file, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, UserUrlLinkFrame, 4); + FrameFactoryTests.validateOutput(output, UserUrlLinkFrame, Id3v2Version.V24); } @test @@ -383,22 +383,26 @@ import {NumberUtils} from "../../src/utils"; // Arrange const fieldBytes = ByteVector.fromByteArray([0x01, 0x02, 0x03]); const header = new FrameHeader(FrameIdentifiers.RVRB, FrameFlags.None, fieldBytes.length); - const data = ByteVector.concatenate(header.render(3), fieldBytes); + const data = ByteVector.concatenate(header.render(Id3v2Version.V23), fieldBytes); const file = TestFile.getFile(data); const mockCreator = Mock.ofType(); - mockCreator.setup(c => c(It.isValue(fieldBytes), It.isValue(0), It.isAny(), It.isValue(3))) - .throws(new Error()); + mockCreator.setup(c => c( + It.isValue(fieldBytes), + It.isValue(0), + It.isAny(), + It.isValue(Id3v2Version.V23) + )).throws(new Error()); Id3v2FrameFactory.addFrameCreator(mockCreator.object); try { // Act - const output = Id3v2FrameFactory.createFrameFromFile(file, 0, 3, false); + const output = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V23, false); // Assert FrameFactoryTests.validateOutput(output, UnknownFrame, data.length); mockCreator.verify( - (c) => c(It.isValue(fieldBytes), It.isValue(0), It.isAny(), It.isValue(3)), + (c) => c(It.isValue(fieldBytes), It.isValue(0), It.isAny(), It.isValue(Id3v2Version.V23)), Times.atLeastOnce() ); } finally { @@ -412,20 +416,24 @@ import {NumberUtils} from "../../src/utils"; public createFrameFromFile_customWithMatch() { // Arrange const frame = PlayCountFrame.fromFields(); - const data = frame.render(4); + const data = frame.render(Id3v2Version.V24); const file = TestFile.getFile(data); - const fieldBytes = data.subarray(FrameHeader.getBaseSize(4)); + const fieldBytes = data.subarray(FrameHeader.getBaseSize(Id3v2Version.V24)); const mockCreator = Mock.ofType(); - mockCreator.setup((c) => c(It.isValue(fieldBytes), It.isValue(0), It.isAny(), It.isValue(4))) - .returns(() => frame); + mockCreator.setup((c) => c( + It.isValue(fieldBytes), + It.isValue(0), + It.isAny(), + It.isValue(Id3v2Version.V24) + )).returns(() => frame); Id3v2FrameFactory.addFrameCreator(mockCreator.object); try { // Act - const output = Id3v2FrameFactory.createFrameFromFile(file, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V24, false); // Assert assert.isOk(output) @@ -433,7 +441,7 @@ import {NumberUtils} from "../../src/utils"; assert.strictEqual(output.totalSize, data.length); mockCreator.verify( - (c) => c(It.isValue(fieldBytes), It.isValue(0), It.isAny(), It.isValue(4)), + (c) => c(It.isValue(fieldBytes), It.isValue(0), It.isAny(), It.isValue(Id3v2Version.V24)), Times.atLeastOnce() ); @@ -448,20 +456,24 @@ import {NumberUtils} from "../../src/utils"; public createFrameFromFile_customWithoutMatch() { // Arrange const frame = UnknownFrame.fromFields(FrameIdentifiers.RVRB, ByteVector.fromByteArray([0x01, 0x02, 0x03])); - const data = frame.render(4); + const data = frame.render(Id3v2Version.V24); const file = TestFile.getFile(data); - const fieldBytes = data.subarray(FrameHeader.getBaseSize(4)); + const fieldBytes = data.subarray(FrameHeader.getBaseSize(Id3v2Version.V24)); const mockCreator = Mock.ofType(); - mockCreator.setup((c) => c(It.isValue(fieldBytes), It.isValue(0), It.isAny(), It.isValue(4))) - .returns(() => undefined); + mockCreator.setup((c) => c( + It.isValue(fieldBytes), + It.isValue(0), + It.isAny(), + It.isValue(Id3v2Version.V24) + )).returns(() => undefined); Id3v2FrameFactory.addFrameCreator(mockCreator.object); try { // Act - const output = Id3v2FrameFactory.createFrameFromFile(file, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V24, false); // Assert FrameFactoryTests.validateOutput(output, UnknownFrame, data.length); @@ -469,7 +481,7 @@ import {NumberUtils} from "../../src/utils"; assert.strictEqual(output.totalSize, data.length); mockCreator.verify( - (c) => c(It.isValue(fieldBytes), It.isValue(0), It.isAny(), It.isValue(4)), + (c) => c(It.isValue(fieldBytes), It.isValue(0), It.isAny(), It.isValue(Id3v2Version.V24)), Times.atLeastOnce() ); @@ -480,10 +492,10 @@ import {NumberUtils} from "../../src/utils"; } } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public createFrameFromFile_fieldBytesHeaderMismatch(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public createFrameFromFile_fieldBytesHeaderMismatch(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.fromSize(10); const header = new FrameHeader(FrameIdentifiers.RVRB, FrameFlags.None, fieldBytes.length + 5); @@ -500,11 +512,11 @@ import {NumberUtils} from "../../src/utils"; // Note: Tag-level unsynchronization is only available in ID3v2.3 const fieldBytes = ByteVector.fromSize(10); const header = new FrameHeader(FrameIdentifiers.RVRB, FrameFlags.Unsynchronized, fieldBytes.length); - const data = ByteVector.concatenate(header.render(3), fieldBytes); + const data = ByteVector.concatenate(header.render(Id3v2Version.V23), fieldBytes); const file = TestFile.getFile(data); // Act - const result = Id3v2FrameFactory.createFrameFromFile(file, 0, 3, true); + const result = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V23, true); // Assert assert.isOk(result); @@ -521,11 +533,11 @@ import {NumberUtils} from "../../src/utils"; // Note: Frame-level unsynchronization is only available in ID3v2.4 const fieldBytes = ByteVector.fromByteArray([0xFF, 0x00, 0xE0]); const header = new FrameHeader(FrameIdentifiers.RVRB, FrameFlags.Unsynchronized, fieldBytes.length); - const data = ByteVector.concatenate(header.render(4), fieldBytes); + const data = ByteVector.concatenate(header.render(Id3v2Version.V24), fieldBytes); const file = TestFile.getFile(data); // Act - const result = Id3v2FrameFactory.createFrameFromFile(file, 0, 4, false); + const result = Id3v2FrameFactory.createFrameFromFile(file, 0, Id3v2Version.V24, false); // Assert assert.isOk(result); @@ -538,9 +550,9 @@ import {NumberUtils} from "../../src/utils"; Testers.bvEqual((result.frame).data, ByteVector.fromByteArray([0xFF, 0xE0])); } - @params(3, "v3") - @params(4, "v4") - public createFrameFromFile_v4ExtendedHeader(version: number) { + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public createFrameFromFile_v4ExtendedHeader(version: Id3v2Version) { // Arrange // Note: v2 does not support extended frame header const fieldBytes = ByteVector.fromSize(10); @@ -573,7 +585,7 @@ import {NumberUtils} from "../../src/utils"; @test public createFrameFromTagBytes_falsyData() { // Act / Assert - Testers.testTruthy((v) => Id3v2FrameFactory.createFrameFromTagBytes(v, 0, 2, false)); + Testers.testTruthy((v) => Id3v2FrameFactory.createFrameFromTagBytes(v, 0, Id3v2Version.V22, false)); } @test @@ -582,7 +594,7 @@ import {NumberUtils} from "../../src/utils"; const data = ByteVector.empty(); // Act / Assert - Testers.testSafeUint((v) => Id3v2FrameFactory.createFrameFromTagBytes(data, v, 2, false)); + Testers.testSafeUint((v) => Id3v2FrameFactory.createFrameFromTagBytes(data, v, Id3v2Version.V22, false)); } @test @@ -594,10 +606,10 @@ import {NumberUtils} from "../../src/utils"; Testers.testByte((v) => Id3v2FrameFactory.createFrameFromTagBytes(data, 0, v, false)); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public createFrameFromTagBytes_noHeader(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public createFrameFromTagBytes_noHeader(version: Id3v2Version) { // Arrange const size = FrameHeader.getBaseSize(version); const data = ByteVector.fromSize(size - 1); @@ -606,10 +618,10 @@ import {NumberUtils} from "../../src/utils"; assert.throws(() => Id3v2FrameFactory.createFrameFromTagBytes(data, 0, version, false)); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public createFrameFroMTagBytes_noHeaderAfterOffset(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public createFrameFroMTagBytes_noHeaderAfterOffset(version: Id3v2Version) { // Arrange const size = FrameHeader.getBaseSize(version); const data = ByteVector.fromSize(size + 9, 0x00); @@ -618,10 +630,10 @@ import {NumberUtils} from "../../src/utils"; assert.throws(() => Id3v2FrameFactory.createFrameFromTagBytes(data, 10, version, false)); } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public createFrameFromTagBytes_padding(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public createFrameFromTagBytes_padding(version: Id3v2Version) { // Arrange const size = FrameHeader.getBaseSize(version); const data = ByteVector.fromSize(size + 1, 0x00); @@ -642,34 +654,34 @@ import {NumberUtils} from "../../src/utils"; ); // Act - const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, AttachmentFrame, 4); + FrameFactoryTests.validateOutput(output, AttachmentFrame, Id3v2Version.V24); } @test public createFrameFromTagBytes_comm() { // Arrange - const data = CommentsFrame.fromFields("foo", "bar").render(4); + const data = CommentsFrame.fromFields("foo", "bar").render(Id3v2Version.V24); // Act - const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, CommentsFrame, 4); + FrameFactoryTests.validateOutput(output, CommentsFrame, Id3v2Version.V24); } @test public createFrameFromTagBytes_etco() { // Arrange - const data = EventTimeCodeFrame.fromFields().render(4); + const data = EventTimeCodeFrame.fromFields().render(Id3v2Version.V24); // Act - const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, EventTimeCodeFrame, 4); + FrameFactoryTests.validateOutput(output, EventTimeCodeFrame, Id3v2Version.V24); } @test @@ -681,10 +693,10 @@ import {NumberUtils} from "../../src/utils"; ); // Act - const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, AttachmentFrame, 4); + FrameFactoryTests.validateOutput(output, AttachmentFrame, Id3v2Version.V24); } @test @@ -696,107 +708,107 @@ import {NumberUtils} from "../../src/utils"; ); // Act - const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, MusicCdIdentifierFrame, 4); + FrameFactoryTests.validateOutput(output, MusicCdIdentifierFrame, Id3v2Version.V24); } @test public createFrameFromTagBytes_pcnt() { // Arrange - const data = PlayCountFrame.fromFields(BigInt(123)).render(4); + const data = PlayCountFrame.fromFields(BigInt(123)).render(Id3v2Version.V24); // Act - const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, PlayCountFrame, 4); + FrameFactoryTests.validateOutput(output, PlayCountFrame, Id3v2Version.V24); } @test public createFrameFromTagBytes_popm() { // Arrange - const data = PopularimeterFrame.fromFields("foo", 123).render(4); + const data = PopularimeterFrame.fromFields("foo", 123).render(Id3v2Version.V24); // Act - const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, PopularimeterFrame, 4); + FrameFactoryTests.validateOutput(output, PopularimeterFrame, Id3v2Version.V24); } @test public createFrameFromTagBytes_priv() { // Arrange - const data = PrivateFrame.fromFields("foo", ByteVector.fromUint(123)).render(4); + const data = PrivateFrame.fromFields("foo", ByteVector.fromUint(123)).render(Id3v2Version.V24); // Act - const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, PrivateFrame, 4); + FrameFactoryTests.validateOutput(output, PrivateFrame, Id3v2Version.V24); } @test public createFrameFromTagBytes_rva2() { // Arrange - const data = RelativeVolumeFrame.fromFields("foo").render(4); + const data = RelativeVolumeFrame.fromFields("foo").render(Id3v2Version.V24); // Act - const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, RelativeVolumeFrame, 4); + FrameFactoryTests.validateOutput(output, RelativeVolumeFrame, Id3v2Version.V24); } @test public createFrameFromTagBytes_sylt() { // Arrange - const data = SynchronizedLyricsFrame.fromFields("foo").render(4); + const data = SynchronizedLyricsFrame.fromFields("foo").render(Id3v2Version.V24); // Act - const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, SynchronizedLyricsFrame, 4); + FrameFactoryTests.validateOutput(output, SynchronizedLyricsFrame, Id3v2Version.V24); } @test public createFrameFromTagBytes_textFrame() { // Arrange const frame = TextInformationFrame.fromFields(FrameIdentifiers.TCOM, ["foo"]); - const data = frame.render(4); + const data = frame.render(Id3v2Version.V24); // Act - const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, TextInformationFrame, 4); + FrameFactoryTests.validateOutput(output, TextInformationFrame, Id3v2Version.V24); } @test public createFrameFromTagBytes_txxx() { // Arrange - const data = UserTextInformationFrame.fromFields("foo", ["bar"]).render(4); + const data = UserTextInformationFrame.fromFields("foo", ["bar"]).render(Id3v2Version.V24); // Act - const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, UserTextInformationFrame, 4); + FrameFactoryTests.validateOutput(output, UserTextInformationFrame, Id3v2Version.V24); } @test public createFrameFromTagBytes_ufid() { // Arrange - const data = UniqueFileIdentifierFrame.fromFields("foo", ByteVector.fromByte(0x08)).render(4); + const data = UniqueFileIdentifierFrame.fromFields("foo", ByteVector.fromByte(0x08)).render(Id3v2Version.V24); // Act - const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, UniqueFileIdentifierFrame, 4); + FrameFactoryTests.validateOutput(output, UniqueFileIdentifierFrame, Id3v2Version.V24); } @test @@ -808,10 +820,10 @@ import {NumberUtils} from "../../src/utils"; ); // Act - const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, UnknownFrame, 4); + FrameFactoryTests.validateOutput(output, UnknownFrame, Id3v2Version.V24); } @test @@ -826,59 +838,59 @@ import {NumberUtils} from "../../src/utils"; ); // Act - const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 10, 4, false); + const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 10, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, UnknownFrame, 4); + FrameFactoryTests.validateOutput(output, UnknownFrame, Id3v2Version.V24); } @test public createFrameFromTagBytes_urlFrame() { // Arrange const frame = UrlLinkFrame.fromFields(FrameIdentifiers.WCOM, "foo"); - const data = frame.render(4); + const data = frame.render(Id3v2Version.V24); // Act - const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, UrlLinkFrame, 4); + FrameFactoryTests.validateOutput(output, UrlLinkFrame, Id3v2Version.V24); } @test public createFrameFromTagBytes_user() { // Arrange - const data = TermsOfUseFrame.fromFields("foo").render(4); + const data = TermsOfUseFrame.fromFields("foo").render(Id3v2Version.V24); // Act - const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, TermsOfUseFrame, 4); + FrameFactoryTests.validateOutput(output, TermsOfUseFrame, Id3v2Version.V24); } @test public createFrameFromTagBytes_uslt() { // Arrange - const data = UnsynchronizedLyricsFrame.fromFields("foo", "bar").render(4); + const data = UnsynchronizedLyricsFrame.fromFields("foo", "bar").render(Id3v2Version.V24); // Act - const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, UnsynchronizedLyricsFrame, 4); + FrameFactoryTests.validateOutput(output, UnsynchronizedLyricsFrame, Id3v2Version.V24); } @test public createFrameFromTagBytes_wxxx() { // Arrange - const data = UserUrlLinkFrame.fromFields("foo", "bar").render(4); + const data = UserUrlLinkFrame.fromFields("foo", "bar").render(Id3v2Version.V24); // Act - const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V24, false); // Assert - FrameFactoryTests.validateOutput(output, UserUrlLinkFrame, 4); + FrameFactoryTests.validateOutput(output, UserUrlLinkFrame, Id3v2Version.V24); } @test @@ -886,21 +898,24 @@ import {NumberUtils} from "../../src/utils"; // Arrange const fieldBytes = ByteVector.fromByteArray([0x01, 0x02, 0x03]); const header = new FrameHeader(FrameIdentifiers.RVRB, FrameFlags.None, fieldBytes.length); - const data = ByteVector.concatenate(header.render(3), fieldBytes); + const data = ByteVector.concatenate(header.render(Id3v2Version.V23), fieldBytes); const mockCreator = Mock.ofType(); - mockCreator.setup(c => c(It.isValue(fieldBytes), It.isValue(0), It.isAny(), It.isValue(3))) - .throws(new Error()); + mockCreator.setup(c => c( + It.isValue(fieldBytes), + It.isValue(0), It.isAny(), + It.isValue(Id3v2Version.V23)) + ).throws(new Error()); Id3v2FrameFactory.addFrameCreator(mockCreator.object); try { // Act - const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 3, false); + const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V23, false); // Assert FrameFactoryTests.validateOutput(output, UnknownFrame, data.length); mockCreator.verify( - (c) => c(It.isValue(fieldBytes), It.isValue(0), It.isAny(), It.isValue(3)), + (c) => c(It.isValue(fieldBytes), It.isValue(0), It.isAny(), It.isValue(Id3v2Version.V23)), Times.atLeastOnce() ); } finally { @@ -914,19 +929,23 @@ import {NumberUtils} from "../../src/utils"; public createFrameFromTagBytes_customWithMatch() { // Arrange const frame = PlayCountFrame.fromFields(BigInt(123)); - const data = frame.render(4); + const data = frame.render(Id3v2Version.V24); - const fieldBytes = data.subarray(FrameHeader.getBaseSize(4)); + const fieldBytes = data.subarray(FrameHeader.getBaseSize(Id3v2Version.V24)); const mockCreator = Mock.ofType(); - mockCreator.setup((c) => c(It.isValue(fieldBytes), It.isValue(0), It.isAny(), It.isValue(4))) - .returns(() => frame); + mockCreator.setup((c) => c( + It.isValue(fieldBytes), + It.isValue(0), + It.isAny(), + It.isValue(Id3v2Version.V24) + )).returns(() => frame); Id3v2FrameFactory.addFrameCreator(mockCreator.object); try { // Act - const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V24, false); // Assert assert.isOk(output) @@ -934,7 +953,7 @@ import {NumberUtils} from "../../src/utils"; assert.strictEqual(output.totalSize, data.length); mockCreator.verify( - (c) => c(It.isValue(fieldBytes), It.isValue(0), It.isAny(), It.isValue(4)), + (c) => c(It.isValue(fieldBytes), It.isValue(0), It.isAny(), It.isValue(Id3v2Version.V24)), Times.atLeastOnce() ); @@ -949,19 +968,23 @@ import {NumberUtils} from "../../src/utils"; public createFrameFromTagBytes_customWithoutMatch() { // Arrange const frame = UnknownFrame.fromFields(FrameIdentifiers.RVRB, ByteVector.fromByteArray([0x01, 0x02, 0x03])); - const data = frame.render(4); + const data = frame.render(Id3v2Version.V24); - const fieldBytes = data.subarray(FrameHeader.getBaseSize(4)); + const fieldBytes = data.subarray(FrameHeader.getBaseSize(Id3v2Version.V24)); const mockCreator = Mock.ofType(); - mockCreator.setup((c) => c(It.isValue(fieldBytes), It.isValue(0), It.isAny(), It.isValue(4))) - .returns(() => undefined); + mockCreator.setup((c) => c( + It.isValue(fieldBytes), + It.isValue(0), + It.isAny(), + It.isValue(Id3v2Version.V24) + )).returns(() => undefined); Id3v2FrameFactory.addFrameCreator(mockCreator.object); try { // Act - const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 4, false); + const output = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V24, false); // Assert FrameFactoryTests.validateOutput(output, UnknownFrame, data.length); @@ -969,7 +992,7 @@ import {NumberUtils} from "../../src/utils"; assert.strictEqual(output.totalSize, data.length); mockCreator.verify( - (c) => c(It.isValue(fieldBytes), It.isValue(0), It.isAny(), It.isValue(4)), + (c) => c(It.isValue(fieldBytes), It.isValue(0), It.isAny(), It.isValue(Id3v2Version.V24)), Times.atLeastOnce() ); @@ -980,10 +1003,10 @@ import {NumberUtils} from "../../src/utils"; } } - @params(2, "v2") - @params(3, "v3") - @params(4, "v4") - public createFrameFromTagBytes_fieldBytesHeaderMismatch(version: number) { + @params(Id3v2Version.V22, "v2") + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public createFrameFromTagBytes_fieldBytesHeaderMismatch(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.fromSize(10); const header = new FrameHeader(FrameIdentifiers.RVRB, FrameFlags.None, fieldBytes.length + 5); @@ -999,10 +1022,10 @@ import {NumberUtils} from "../../src/utils"; // Note: Tag-level unsynchronization is only available in ID3v2.3 const fieldBytes = ByteVector.fromSize(10); const header = new FrameHeader(FrameIdentifiers.RVRB, FrameFlags.Unsynchronized, fieldBytes.length); - const data = ByteVector.concatenate(header.render(3), fieldBytes); + const data = ByteVector.concatenate(header.render(Id3v2Version.V23), fieldBytes); // Act - const result = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 3, true); + const result = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V23, true); // Assert assert.isOk(result); @@ -1019,10 +1042,10 @@ import {NumberUtils} from "../../src/utils"; // Note: Frame-level unsynchronization is only available in ID3v2.4 const fieldBytes = ByteVector.fromByteArray([0xFF, 0x00, 0xE0]); const header = new FrameHeader(FrameIdentifiers.RVRB, FrameFlags.Unsynchronized, fieldBytes.length); - const data = ByteVector.concatenate(header.render(4), fieldBytes); + const data = ByteVector.concatenate(header.render(Id3v2Version.V24), fieldBytes); // Act - const result = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, 4, false); + const result = Id3v2FrameFactory.createFrameFromTagBytes(data, 0, Id3v2Version.V24, false); // Assert assert.isOk(result); @@ -1035,9 +1058,9 @@ import {NumberUtils} from "../../src/utils"; Testers.bvEqual((result.frame).data, ByteVector.fromByteArray([0xFF, 0xE0])); } - @params(3, "v3") - @params(4, "v4") - public createFrameFromTagBytes_v4ExtendedHeader(version: number) { + @params(Id3v2Version.V23, "v3") + @params(Id3v2Version.V24, "v4") + public createFrameFromTagBytes_v34ExtendedHeader(version: Id3v2Version) { // Arrange // Note: v2 does not support extended frame header const fieldBytes = ByteVector.fromSize(10); @@ -1066,7 +1089,7 @@ import {NumberUtils} from "../../src/utils"; private static getTestData(frameIdentifier: FrameIdentifier, fieldBytes: ByteVector): ByteVector { const header = new FrameHeader(frameIdentifier, FrameFlags.None, fieldBytes.length); - return ByteVector.concatenate(header.render(4), fieldBytes); + return ByteVector.concatenate(header.render(Id3v2Version.V24), fieldBytes); } private static getTestFile(frameIdentifier: FrameIdentifier, fieldBytes: ByteVector): File { @@ -1078,7 +1101,7 @@ import {NumberUtils} from "../../src/utils"; output: {frame: Frame; totalSize: number}, // eslint-disable-next-line @typescript-eslint/ban-types classType: Function, - id3v2Version: number + id3v2Version: Id3v2Version ) { assert.ok(output); diff --git a/test-unit/id3v2/frameHeaderTests.ts b/test-unit/id3v2/frameHeaderTests.ts index 354b5132..42f0d43c 100644 --- a/test-unit/id3v2/frameHeaderTests.ts +++ b/test-unit/id3v2/frameHeaderTests.ts @@ -18,7 +18,7 @@ import {NumberUtils} from "../../src/utils"; const testBytes = ByteVector.empty(); // Act / Assert - Testers.testTruthy((v: ByteVector) => FrameHeader.fromData(v, 3)); + Testers.testTruthy((v: ByteVector) => FrameHeader.fromData(v, Id3v2Version.V23)); Testers.testUint((v) => FrameHeader.fromData(testBytes, v)); assert.throws(() => FrameHeader.fromData(testBytes, 1)); assert.throws(() => FrameHeader.fromData(testBytes, 5)); diff --git a/test-unit/id3v2/genreFrameTests.ts b/test-unit/id3v2/genreFrameTests.ts index 3e8429eb..4bea27ee 100644 --- a/test-unit/id3v2/genreFrameTests.ts +++ b/test-unit/id3v2/genreFrameTests.ts @@ -247,7 +247,7 @@ class Id3v2_GenreFrameTests extends FrameConstructorTests { ByteVector.getTextDelimiter(StringType.UTF16BE) ); - this.testFrameParse(4, payload, ["Classical", "Cover"]); + this.testFrameParse(Id3v2Version.V24, payload, ["Classical", "Cover"]); } // endregion @@ -530,7 +530,7 @@ class Id3v2_GenreFrameTests extends FrameConstructorTests { ... this.getDelimitedStrings(expected) ); const expectedHeader = new FrameHeader(FrameIdentifiers.TCON, FrameFlags.None, expectedBody.length); - const expectedBytes = ByteVector.concatenate(expectedHeader.render(4), expectedBody); + const expectedBytes = ByteVector.concatenate(expectedHeader.render(Id3v2Version.V24), expectedBody); Testers.bvEqual(result, expectedBytes); } diff --git a/test-unit/id3v2/musicCdIdentifierFrameTests.ts b/test-unit/id3v2/musicCdIdentifierFrameTests.ts index fbba63f7..8328d1f8 100644 --- a/test-unit/id3v2/musicCdIdentifierFrameTests.ts +++ b/test-unit/id3v2/musicCdIdentifierFrameTests.ts @@ -163,7 +163,7 @@ import {Testers} from "../utilities/testers"; @params(Id3v2Version.V22, "v2") @params(Id3v2Version.V23, "v3") @params(Id3v2Version.V24, "v4") - public render_returnsByteVector(version: number) { + public render_returnsByteVector(version: Id3v2Version) { // Arrange const fieldBytes = ByteVector.fromString("foo bar baz", StringType.UTF8); const header = new FrameHeader(FrameIdentifiers.MCDI, FrameFlags.None, fieldBytes.length); diff --git a/test-unit/id3v2/relativeVolumeFrameTests.ts b/test-unit/id3v2/relativeVolumeFrameTests.ts index 8e34c8a8..435b26d1 100644 --- a/test-unit/id3v2/relativeVolumeFrameTests.ts +++ b/test-unit/id3v2/relativeVolumeFrameTests.ts @@ -649,7 +649,7 @@ const assertFrame = (frame: RelativeVolumeFrame, c: ChannelData[], i: string) => @params(Id3v2Version.V22, "v2") @params(Id3v2Version.V23, "v3") @params(Id3v2Version.V24, "v4") - public render_oneChannelData(version: number) { + public render_oneChannelData(version: Id3v2Version) { // Arrange const frame = RelativeVolumeFrame.fromFields("foobarbaz"); frame.setPeakBits(ChannelType.Subwoofer, 32); diff --git a/test-unit/id3v2/tagHeaderTests.ts b/test-unit/id3v2/tagHeaderTests.ts index d47974c1..e66c000f 100644 --- a/test-unit/id3v2/tagHeaderTests.ts +++ b/test-unit/id3v2/tagHeaderTests.ts @@ -174,7 +174,7 @@ const getTestHeader = (majorVersion: Id3v2Version, minorVersion: number, flags: @test public setFlags_v3_invalidFlags() { // Arrange - const header = getTestHeader(3, 0, TagFlags.None); + const header = getTestHeader(Id3v2Version.V23, 0, TagFlags.None); // Act / Assert assert.throws(() => { header.flags = TagFlags.FooterPresent }); @@ -237,10 +237,10 @@ const getTestHeader = (majorVersion: Id3v2Version, minorVersion: number, flags: const header = getTestHeader(Id3v2Version.V24, 0, flags); // Act - header.majorVersion = 2; + header.majorVersion = Id3v2Version.V22; // Assert - assert.equal(header.majorVersion, 2); + assert.equal(header.majorVersion, Id3v2Version.V22); assert.isFalse(NumberUtils.hasFlag(header.flags, flags)); } @@ -251,10 +251,10 @@ const getTestHeader = (majorVersion: Id3v2Version, minorVersion: number, flags: const header = getTestHeader(Id3v2Version.V24, 0, flags); // Act - header.majorVersion = 3; + header.majorVersion = Id3v2Version.V23; // Assert - assert.equal(header.majorVersion, 3); + assert.equal(header.majorVersion, Id3v2Version.V23); assert.isFalse(NumberUtils.hasFlag(header.flags, flags)); } @@ -277,10 +277,10 @@ const getTestHeader = (majorVersion: Id3v2Version, minorVersion: number, flags: const header = getTestHeader(version, 0, TagFlags.None); // Act - header.revisionNumber = 2; + header.revisionNumber = Id3v2Version.V22; // Assert - assert.equal(header.revisionNumber, 2); + assert.equal(header.revisionNumber, Id3v2Version.V22); } @params(Id3v2Version.V22, "v2") From ebf947052ccac600d134e32350e64623989ba167 Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Sat, 8 Aug 2026 23:46:32 -0500 Subject: [PATCH 17/18] Fixing last bits in sandwich tags --- src/id3v2/frames/eventTimeCodeFrame.ts | 2 +- src/id3v2/id3v2Tag.ts | 4 ++-- src/sandwich/endTag.ts | 4 ++-- src/sandwich/startTag.ts | 1 + 4 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/id3v2/frames/eventTimeCodeFrame.ts b/src/id3v2/frames/eventTimeCodeFrame.ts index cf5ba2b8..4c01d403 100644 --- a/src/id3v2/frames/eventTimeCodeFrame.ts +++ b/src/id3v2/frames/eventTimeCodeFrame.ts @@ -93,7 +93,7 @@ export class EventTimeCodeFrame extends Frame { * Constructs and initializes a new instance by parsing the fields from the field bytes. * @param header Header of the frame * @param fieldBytes Bytes that contain the fields of the frame - * @param _version + * @param _version Version that the frame was originally encoded */ public static fromFieldBytes( header: FrameHeader, diff --git a/src/id3v2/id3v2Tag.ts b/src/id3v2/id3v2Tag.ts index 7ea052c4..1a72d6d5 100644 --- a/src/id3v2/id3v2Tag.ts +++ b/src/id3v2/id3v2Tag.ts @@ -45,7 +45,7 @@ export default class Id3v2Tag extends Tag { */ public static fromEmpty(): Id3v2Tag { const tag = new Id3v2Tag(); - tag._header = new TagHeader(0, 0, TagFlags.None, 0); + tag._header = new TagHeader(Id3v2Settings.defaultVersion, 0, TagFlags.None, 0); return tag; } @@ -192,7 +192,7 @@ export default class Id3v2Tag extends Tag { this._header.majorVersion = value; // Migrate any incompatible frames that have direct migrations - const v23ToV4 = (originalVersion === Id3v2Version.V22 || originalVersion== Id3v2Version.V23) && + const v23ToV4 = (originalVersion === Id3v2Version.V22 || originalVersion === Id3v2Version.V23) && value === Id3v2Version.V24; const v4ToV23 = originalVersion === Id3v2Version.V24 && (value === Id3v2Version.V22 || value === Id3v2Version.V23); diff --git a/src/sandwich/endTag.ts b/src/sandwich/endTag.ts index ac4e8487..6a4cbdf9 100644 --- a/src/sandwich/endTag.ts +++ b/src/sandwich/endTag.ts @@ -9,7 +9,7 @@ import {ApeTagFooter} from "../ape/apeTagFooter"; import {ByteVector} from "../byteVector"; import {CorruptFileError, UnsupportedFormatError} from "../errors"; import {File, ReadStyle} from "../file"; -import {TagFlags as Id3v2TagFlags} from "../id3v2/enums"; +import {Id3v2Version, TagFlags as Id3v2TagFlags} from "../id3v2/enums"; import {Tag, TagTypes} from "../tag"; import {Guards} from "../utils"; @@ -56,7 +56,7 @@ export default class EndTag extends CombinedTag { // ID3v2 tags must be told to write a footer const id3v2Tag = Id3v2Tag.fromEmpty(); // @TODO: have default version be configurable - id3v2Tag.version = 4; + id3v2Tag.version = Id3v2Version.V24; id3v2Tag.flags |= Id3v2TagFlags.FooterPresent; tag = id3v2Tag; break; diff --git a/src/sandwich/startTag.ts b/src/sandwich/startTag.ts index cc812873..f848b0c2 100644 --- a/src/sandwich/startTag.ts +++ b/src/sandwich/startTag.ts @@ -128,6 +128,7 @@ class StartTagParser extends TagParser { } } } catch (e) { + // @TODO: Maybe we should have an "invalid tag" type. if (!(e instanceof CorruptFileError)) { throw e; } From 2ae8dab0b189554df087c57ba1ae9d403473d69f Mon Sep 17 00:00:00 2001 From: Ben Russell Date: Sun, 9 Aug 2026 00:18:28 -0500 Subject: [PATCH 18/18] Address :robot: feedback round 1 --- docs/classes/Id3v2TagFooter.md | 2 +- docs/classes/Id3v2TagHeader.md | 10 +++++----- docs/enums/Id3v2TagHeaderFlags.md | 2 +- docs/modules.md | 2 +- src/index.ts | 1 + test-unit/id3v2/urlLinkFrameTests.ts | 8 ++++---- 6 files changed, 13 insertions(+), 12 deletions(-) diff --git a/docs/classes/Id3v2TagFooter.md b/docs/classes/Id3v2TagFooter.md index aac06e2a..18a975fc 100644 --- a/docs/classes/Id3v2TagFooter.md +++ b/docs/classes/Id3v2TagFooter.md @@ -210,7 +210,7 @@ same tag. | Name | Type | Description | | :------ | :------ | :------ | -| `header` | [`TagHeader`](Id3v2TagHeader.md) | Header from which to base the new footer | +| `header` | [`Id3v2TagHeader`](Id3v2TagHeader.md) | Header from which to base the new footer | #### Returns diff --git a/docs/classes/Id3v2TagHeader.md b/docs/classes/Id3v2TagHeader.md index 431e7611..efe3ee41 100644 --- a/docs/classes/Id3v2TagHeader.md +++ b/docs/classes/Id3v2TagHeader.md @@ -1,6 +1,6 @@ -[node-taglib-sharp](../README.md) / [Exports](../modules.md) / TagHeader +[node-taglib-sharp](../README.md) / [Exports](../modules.md) / Id3v2TagHeader -# Class: TagHeader +# Class: Id3v2TagHeader This class provides a representation of an ID3v2 tag header which can be read from and written to disk. @@ -32,7 +32,7 @@ to disk. ### constructor -• **new TagHeader**() +• **new Id3v2TagHeader**() ## Properties @@ -182,7 +182,7 @@ ___ ### fromData -▸ `Static` **fromData**(`data`): [`TagHeader`](Id3v2TagHeader.md) +▸ `Static` **fromData**(`data`): [`Id3v2TagHeader`](Id3v2TagHeader.md) Constructs and initializes a new instance by reading it from the raw header data. @@ -194,4 +194,4 @@ Constructs and initializes a new instance by reading it from the raw header data #### Returns -[`TagHeader`](Id3v2TagHeader.md) +[`Id3v2TagHeader`](Id3v2TagHeader.md) diff --git a/docs/enums/Id3v2TagHeaderFlags.md b/docs/enums/Id3v2TagHeaderFlags.md index ac7e17a3..758b6a15 100644 --- a/docs/enums/Id3v2TagHeaderFlags.md +++ b/docs/enums/Id3v2TagHeaderFlags.md @@ -2,7 +2,7 @@ # Enumeration: Id3v2TagHeaderFlags -Indicates the flags applied to a [TagHeader](../classes/Id3v2TagHeader.md) object. +Indicates the flags applied to a [Id3v2TagHeader](../classes/Id3v2TagHeader.md) object. ## Table of contents diff --git a/docs/modules.md b/docs/modules.md index 8bdd06d6..bd7de908 100644 --- a/docs/modules.md +++ b/docs/modules.md @@ -90,7 +90,7 @@ - [Id3v2SynchronizedLyricsFrame](classes/Id3v2SynchronizedLyricsFrame.md) - [Id3v2Tag](classes/Id3v2Tag.md) - [Id3v2TagFooter](classes/Id3v2TagFooter.md) -- [TagHeader](classes/Id3v2TagHeader.md) +- [Id3v2TagHeader](classes/Id3v2TagHeader.md) - [Id3v2TermsOfUseFrame](classes/Id3v2TermsOfUseFrame.md) - [Id3v2TextInformationFrame](classes/Id3v2TextInformationFrame.md) - [Id3v2UniqueFileIdentifierFrame](classes/Id3v2UniqueFileIdentifierFrame.md) diff --git a/src/index.ts b/src/index.ts index 43ac71c0..a5e51757 100644 --- a/src/index.ts +++ b/src/index.ts @@ -75,6 +75,7 @@ export { ChannelType as Id3v2RelativeVolumeFrameChannelType, EventType as Id3v2EventType, FrameFlags as Id3v2FrameFlags, + Id3v2Version, SynchronizedTextType as Id3v2SynchronizedTextType, TagFlags as Id3v2TagHeaderFlags, TimestampFormat as Id3v2TimestampFormat diff --git a/test-unit/id3v2/urlLinkFrameTests.ts b/test-unit/id3v2/urlLinkFrameTests.ts index 5ab32c76..db7a9ec7 100644 --- a/test-unit/id3v2/urlLinkFrameTests.ts +++ b/test-unit/id3v2/urlLinkFrameTests.ts @@ -312,10 +312,10 @@ const assertFrame = (frame: UrlLinkFrame, identifier: FrameIdentifier, text: str assert.isOk(result); const expectedBytes = ByteVector.concatenate( - FrameIdentifiers.WCOM.render(Id3v2Version.V24), - ByteVector.fromUint(Id3v2Version.V23), - ByteVector.fromUshort(FrameFlags.None), - ByteVector.fromString("foo", StringType.Latin1) + FrameIdentifiers.WCOM.render(Id3v2Version.V24), // Frame identifier + ByteVector.fromUint(3), // Frame size + ByteVector.fromUshort(FrameFlags.None), // Frame flags + ByteVector.fromString("foo", StringType.Latin1) // URL ); Testers.bvEqual(result, expectedBytes); }