Skip to content

Commit

Permalink
test: add utils/stats tests
Browse files Browse the repository at this point in the history
  • Loading branch information
byCedric committed Mar 17, 2024
1 parent c53885e commit cd86ab6
Show file tree
Hide file tree
Showing 6 changed files with 129 additions and 14 deletions.
4 changes: 2 additions & 2 deletions src/utils/__tests__/jsonl.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,8 @@ describe('appendJsonLine', () => {
*/
function fixture(name: string, { temporary = false }: { temporary?: boolean } = {}) {
const file = temporary
? path.join(__dirname, 'fixtures', `${name}.temp.jsonl`)
: path.join(__dirname, 'fixtures', `${name}.jsonl`);
? path.join(__dirname, 'fixtures/jsonl', `${name}.temp.jsonl`)
: path.join(__dirname, 'fixtures/jsonl', `${name}.jsonl`);

if (temporary) {
fs.writeFileSync(file, '');
Expand Down
117 changes: 117 additions & 0 deletions src/utils/__tests__/stats.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import { describe, expect, it } from 'bun:test';
import fs from 'fs';
import path from 'path';

import { name, version } from '../../../package.json';
import { AtlasValidationError } from '../errors';
import { getStatsPath, getStatsMetdata, createStatsFile, validateStatsFile } from '../stats';

describe('getStatsPath', () => {
it('returns default path `<project>/.expo/stats.jsonl`', () => {
expect(getStatsPath('<project>')).toBe('<project>/.expo/stats.jsonl');
});
});

describe('getStatsMetadata', () => {
it('returns package name and version', () => {
expect(getStatsMetdata()).toMatchObject({ name, version });
});
});

describe('createStatsFile', () => {
it('creates a stats file with the correct metadata', async () => {
const file = fixture('create-metadata', { temporary: true });
await createStatsFile(file);
await expect(fs.promises.readFile(file, 'utf8')).resolves.toBe(
JSON.stringify({ name, version }) + '\n'
);
});

it('overwrites invalid stats file', async () => {
const file = fixture('create-invalid', { temporary: true });
await fs.promises.writeFile(file, JSON.stringify({ name, version: '0.0.0' }) + '\n');
await createStatsFile(file);
await expect(fs.promises.readFile(file, 'utf8')).resolves.toBe(
JSON.stringify({ name, version }) + '\n'
);
});

it('reuses valid stats file', async () => {
const file = fixture('create-valid', { temporary: true });
await fs.promises.writeFile(file, JSON.stringify({ name, version }) + '\n');
await createStatsFile(file);
await expect(fs.promises.readFile(file, 'utf-8')).resolves.toBe(
JSON.stringify({ name, version }) + '\n'
);
});
});

describe('validateStatsFile', () => {
it('passes for valid stats file', async () => {
const file = fixture('validate-valid', { temporary: true });
await createStatsFile(file);
await expect(validateStatsFile(file)).resolves.pass();
});

it('fails for non-existing stats file', async () => {
await expect(validateStatsFile('./this-file-does-not-exists')).rejects.toThrow(
AtlasValidationError
);
});

it('fails for invalid stats file', async () => {
const file = fixture('validate-invalid', { temporary: true });
await fs.promises.writeFile(file, JSON.stringify({ name, version: '0.0.0' }) + '\n');
await expect(validateStatsFile(file)).rejects.toThrow(AtlasValidationError);
});

it('skips validation when EXPO_ATLAS_NO_STATS_VALIDATION is true-ish', async () => {
using _env = env('EXPO_ATLAS_NO_STATS_VALIDATION', 'true');
const file = fixture('validate-skip-invalid', { temporary: true });
await fs.promises.writeFile(file, JSON.stringify({ name, version: '0.0.0' }) + '\n');
await expect(validateStatsFile(file)).resolves.pass();
});
});

/**
* Get the file path to a fixture, by name.
* This automatically adds the required `.jsonl` or `.temp.jsonl` extension.
* Use `temporary: true` to keep it out of the repository, and reset the content automatically.
*/
function fixture(name: string, { temporary = false }: { temporary?: boolean } = {}) {
const file = temporary
? path.join(__dirname, 'fixtures/stats', `${name}.temp.jsonl`)
: path.join(__dirname, 'fixtures/stats', `${name}.jsonl`);

if (temporary) {
fs.writeFileSync(file, '');

Check failure on line 87 in src/utils/__tests__/stats.test.ts

View workflow job for this annotation

GitHub Actions / core

ENOENT: No such file or directory

at fixture (/home/runner/work/expo-atlas/expo-atlas/src/utils/__tests__/stats.test.ts:87:5) at /home/runner/work/expo-atlas/expo-atlas/src/utils/__tests__/stats.test.ts:23:18 at /home/runner/work/expo-atlas/expo-atlas/src/utils/__tests__/stats.test.ts:22:56

Check failure on line 87 in src/utils/__tests__/stats.test.ts

View workflow job for this annotation

GitHub Actions / core

ENOENT: No such file or directory

at fixture (/home/runner/work/expo-atlas/expo-atlas/src/utils/__tests__/stats.test.ts:87:5) at /home/runner/work/expo-atlas/expo-atlas/src/utils/__tests__/stats.test.ts:31:18 at /home/runner/work/expo-atlas/expo-atlas/src/utils/__tests__/stats.test.ts:30:39

Check failure on line 87 in src/utils/__tests__/stats.test.ts

View workflow job for this annotation

GitHub Actions / core

ENOENT: No such file or directory

at fixture (/home/runner/work/expo-atlas/expo-atlas/src/utils/__tests__/stats.test.ts:87:5) at /home/runner/work/expo-atlas/expo-atlas/src/utils/__tests__/stats.test.ts:40:18 at /home/runner/work/expo-atlas/expo-atlas/src/utils/__tests__/stats.test.ts:39:33

Check failure on line 87 in src/utils/__tests__/stats.test.ts

View workflow job for this annotation

GitHub Actions / core

ENOENT: No such file or directory

at fixture (/home/runner/work/expo-atlas/expo-atlas/src/utils/__tests__/stats.test.ts:87:5) at /home/runner/work/expo-atlas/expo-atlas/src/utils/__tests__/stats.test.ts:51:18 at /home/runner/work/expo-atlas/expo-atlas/src/utils/__tests__/stats.test.ts:50:37

Check failure on line 87 in src/utils/__tests__/stats.test.ts

View workflow job for this annotation

GitHub Actions / core

ENOENT: No such file or directory

at fixture (/home/runner/work/expo-atlas/expo-atlas/src/utils/__tests__/stats.test.ts:87:5) at /home/runner/work/expo-atlas/expo-atlas/src/utils/__tests__/stats.test.ts:63:18 at /home/runner/work/expo-atlas/expo-atlas/src/utils/__tests__/stats.test.ts:62:38

Check failure on line 87 in src/utils/__tests__/stats.test.ts

View workflow job for this annotation

GitHub Actions / core

ENOENT: No such file or directory

at fixture (/home/runner/work/expo-atlas/expo-atlas/src/utils/__tests__/stats.test.ts:87:5) at /home/runner/work/expo-atlas/expo-atlas/src/utils/__tests__/stats.test.ts:70:18 at /home/runner/work/expo-atlas/expo-atlas/src/utils/__tests__/stats.test.ts:68:74
}

return file;
}

/**
* Change the environment variable for the duration of a test.
* This uses explicit resource management to revert the environment variable after the test.
*/
function env(key: string, value?: string): { key: string; value?: string } & Disposable {
const original = process.env[key];

if (value === undefined) {
delete process.env[key];
} else {
process.env[key] = value;
}

return {
key,
value,
[Symbol.dispose]() {
if (original === undefined) {
delete process.env[key];
} else {
process.env[key] = value;
}
},
};
}
8 changes: 4 additions & 4 deletions src/utils/env.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
import { boolish } from 'getenv';

export const env = {
get EXPO_DEBUG() {
return boolish('EXPO_DEBUG', false);
get EXPO_ATLAS_DEBUG() {
return boolish('EXPO_ATLAS_DEBUG', false);
},
get EXPO_NO_STATS_VALIDATION() {
return boolish('EXPO_NO_STATS_VALIDATION', false);
get EXPO_ATLAS_NO_STATS_VALIDATION() {
return boolish('EXPO_ATLAS_NO_STATS_VALIDATION', false);
},
};
2 changes: 1 addition & 1 deletion src/utils/middleware.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export function createAtlasMiddleware(source: StatsSource) {

const middleware = connect();

if (env.EXPO_DEBUG) {
if (env.EXPO_ATLAS_DEBUG) {
middleware.use(morgan('tiny'));
}

Expand Down
12 changes: 5 additions & 7 deletions src/utils/stats.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import fs from 'fs';
import path from 'path';

import { parseJsonLine } from './jsonl';
import { appendJsonLine, parseJsonLine } from './jsonl';
import { name, version } from '../../package.json';
import { env } from '../utils/env';
import { AtlasValidationError } from '../utils/errors';
Expand All @@ -24,7 +24,7 @@ export async function validateStatsFile(statsFile: string, metadata = getStatsMe
throw new AtlasValidationError('STATS_FILE_NOT_FOUND', statsFile);
}

if (env.EXPO_NO_STATS_VALIDATION) {
if (env.EXPO_ATLAS_NO_STATS_VALIDATION) {
return;
}

Expand All @@ -42,14 +42,12 @@ export async function validateStatsFile(statsFile: string, metadata = getStatsMe
export async function createStatsFile(filePath: string) {
if (fs.existsSync(filePath)) {
try {
await validateStatsFile(filePath);
return await validateStatsFile(filePath);
} catch {
await fs.promises.writeFile(filePath, JSON.stringify(getStatsMetdata()) + '\n');
await fs.promises.writeFile(filePath, '');
}

return;
}

await fs.promises.mkdir(path.dirname(filePath), { recursive: true });
await fs.promises.writeFile(filePath, JSON.stringify(getStatsMetdata()) + '\n');
await appendJsonLine(filePath, getStatsMetdata());
}

0 comments on commit cd86ab6

Please sign in to comment.