Skip to content

Commit 00d23a0

Browse files
committed
chore: added tests for VirtualTar
1 parent 4d46e29 commit 00d23a0

File tree

11 files changed

+826
-612
lines changed

11 files changed

+826
-612
lines changed

src/Generator.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import type { FileType, FileStat } from './types';
22
import { GeneratorState, HeaderSize } from './types';
3+
import * as constants from './constants';
34
import * as errors from './errors';
45
import * as utils from './utils';
5-
import * as constants from './constants';
66

77
/**
88
* The TAR headers follow this structure:
@@ -174,7 +174,7 @@ class Generator {
174174
return data;
175175
} else {
176176
// Make sure we don't attempt to write extra data
177-
if (data.byteLength !== this.remainingBytes) {
177+
if (data.byteLength > this.remainingBytes) {
178178
throw new errors.ErrorVirtualTarGeneratorBlockSize(
179179
`Expected data to be ${this.remainingBytes} bytes but received ${data.byteLength} bytes`,
180180
);
@@ -210,8 +210,10 @@ class Generator {
210210
this.state = GeneratorState.ENDED;
211211
break;
212212
default:
213-
throw new errors.ErrorVirtualTarGeneratorEndOfArchive(
214-
'Exactly two null chunks should be generated consecutively to end archive',
213+
throw new errors.ErrorVirtualTarGeneratorInvalidState(
214+
`Expected state ${GeneratorState[GeneratorState.HEADER]} or ${
215+
GeneratorState[GeneratorState.NULL]
216+
} but got ${GeneratorState[this.state]}`,
215217
);
216218
}
217219
return new Uint8Array(constants.BLOCK_SIZE);

src/Parser.ts

Lines changed: 12 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import type { TokenHeader, TokenData, TokenEnd } from './types';
22
import { ParserState } from './types';
3-
import { HeaderOffset, HeaderSize, EntryType } from './types';
43
import * as constants from './constants';
54
import * as errors from './errors';
65
import * as utils from './utils';
@@ -11,11 +10,7 @@ class Parser {
1110

1211
protected parseHeader(array: Uint8Array): TokenHeader {
1312
// Validate header by checking checksum and magic string
14-
const headerChecksum = utils.extractOctal(
15-
array,
16-
HeaderOffset.CHECKSUM,
17-
HeaderSize.CHECKSUM,
18-
);
13+
const headerChecksum = utils.decodeChecksum(array);
1914
const calculatedChecksum = utils.calculateChecksum(array);
2015

2116
if (headerChecksum !== calculatedChecksum) {
@@ -24,22 +19,14 @@ class Parser {
2419
);
2520
}
2621

27-
const ustarMagic = utils.extractString(
28-
array,
29-
HeaderOffset.USTAR_NAME,
30-
HeaderSize.USTAR_NAME,
31-
);
22+
const ustarMagic = utils.decodeUstarMagic(array);
3223
if (ustarMagic !== constants.USTAR_NAME) {
3324
throw new errors.ErrorVirtualTarParserInvalidHeader(
3425
`Expected ustar magic to be '${constants.USTAR_NAME}', got '${ustarMagic}'`,
3526
);
3627
}
3728

38-
const ustarVersion = utils.extractString(
39-
array,
40-
HeaderOffset.USTAR_VERSION,
41-
HeaderSize.USTAR_VERSION,
42-
);
29+
const ustarVersion = utils.decodeUstarVersion(array);
4330
if (ustarVersion !== constants.USTAR_VERSION) {
4431
throw new errors.ErrorVirtualTarParserInvalidHeader(
4532
`Expected ustar version to be '${constants.USTAR_VERSION}', got '${ustarVersion}'`,
@@ -48,69 +35,14 @@ class Parser {
4835

4936
// Extract the relevant metadata from the header
5037
const filePath = utils.decodeFilePath(array);
51-
const fileSize = utils.extractOctal(
52-
array,
53-
HeaderOffset.FILE_SIZE,
54-
HeaderSize.FILE_SIZE,
55-
);
56-
const fileMtime = new Date(
57-
utils.extractOctal(
58-
array,
59-
HeaderOffset.FILE_MTIME,
60-
HeaderSize.FILE_MTIME,
61-
) * 1000,
62-
);
63-
const fileMode = utils.extractOctal(
64-
array,
65-
HeaderOffset.FILE_MODE,
66-
HeaderSize.FILE_MODE,
67-
);
68-
const ownerGid = utils.extractOctal(
69-
array,
70-
HeaderOffset.OWNER_GID,
71-
HeaderSize.OWNER_GID,
72-
);
73-
const ownerUid = utils.extractOctal(
74-
array,
75-
HeaderOffset.OWNER_UID,
76-
HeaderSize.OWNER_UID,
77-
);
78-
const ownerName = utils.extractString(
79-
array,
80-
HeaderOffset.LINK_NAME,
81-
HeaderSize.LINK_NAME,
82-
);
83-
const ownerGroupName = utils.extractString(
84-
array,
85-
HeaderOffset.OWNER_GROUPNAME,
86-
HeaderSize.OWNER_GROUPNAME,
87-
);
88-
const ownerUserName = utils.extractString(
89-
array,
90-
HeaderOffset.OWNER_USERNAME,
91-
HeaderSize.OWNER_USERNAME,
92-
);
93-
let fileType: 'file' | 'directory' | 'metadata';
94-
const type = utils.extractString(
95-
array,
96-
HeaderOffset.TYPE_FLAG,
97-
HeaderSize.TYPE_FLAG,
98-
);
99-
switch (type) {
100-
case EntryType.FILE:
101-
fileType = 'file';
102-
break;
103-
case EntryType.DIRECTORY:
104-
fileType = 'directory';
105-
break;
106-
case EntryType.EXTENDED:
107-
fileType = 'metadata';
108-
break;
109-
default:
110-
throw new errors.ErrorVirtualTarParserInvalidHeader(
111-
`Got invalid file type ${type}`,
112-
);
113-
}
38+
const fileSize = utils.decodeFileSize(array);
39+
const fileMtime = utils.decodeFileMtime(array);
40+
const fileMode = utils.decodeFileMode(array);
41+
const ownerUid = utils.decodeOwnerUid(array);
42+
const ownerGid = utils.decodeOwnerGid(array);
43+
const ownerUserName = utils.decodeOwnerUserName(array);
44+
const ownerGroupName = utils.decodeOwnerGroupName(array);
45+
const fileType = utils.decodeFileType(array);
11446

11547
return {
11648
type: 'header',
@@ -121,7 +53,6 @@ class Parser {
12153
fileSize,
12254
ownerGid,
12355
ownerUid,
124-
ownerName,
12556
ownerUserName,
12657
ownerGroupName,
12758
};
@@ -165,7 +96,7 @@ class Parser {
16596
this.state = ParserState.DATA;
16697
this.remainingBytes = headerToken.fileSize;
16798
}
168-
} else if (headerToken.fileType === 'metadata') {
99+
} else if (headerToken.fileType === 'extended') {
169100
// A header might not have any data but a metadata header will always
170101
// be followed by data.
171102
this.state = ParserState.DATA;

0 commit comments

Comments
 (0)