Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions scripts/validate-metadata.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,8 +156,8 @@ function expectArray(errors, value, label, filePath) {
}
}

function validateMetadataFile(metadataFile, errors) {
const metadata = parseMetadataYaml(fs.readFileSync(metadataFile, 'utf8'));
async function validateMetadataFile(metadataFile, errors) {
const metadata = parseMetadataYaml(await fs.promises.readFile(metadataFile, 'utf8'));
const modelDir = path.dirname(metadataFile);
const modelFiles = listModelFiles(modelDir);
const readmePath = path.join(modelDir, 'README.md');
Expand Down Expand Up @@ -232,14 +232,12 @@ function validateMetadataFile(metadataFile, errors) {
}
}

function main() {
async function main() {
const root = path.resolve(__dirname, '..');
const metadataFiles = SEARCH_ROOTS.flatMap((searchRoot) => listMetadataFiles(path.join(root, searchRoot)));
const errors = [];

for (const metadataFile of metadataFiles) {
validateMetadataFile(metadataFile, errors);
}
await Promise.all(metadataFiles.map((metadataFile) => validateMetadataFile(metadataFile, errors)));

if (errors.length > 0) {
console.error(`Metadata validation failed with ${errors.length} issue(s):`);
Expand Down
36 changes: 18 additions & 18 deletions tests/validate-metadata.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ const path = require('path');
const os = require('os');
const { validateMetadataFile } = require('../scripts/validate-metadata');

function withTempDir(testFn) {
async function withTempDir(testFn) {
const tempDir = fs.mkdtempSync(path.join(os.tmpdir(), 'validate-metadata-test-'));
try {
testFn(tempDir);
await testFn(tempDir);
} finally {
fs.rmSync(tempDir, { recursive: true, force: true });
}
Expand Down Expand Up @@ -43,15 +43,15 @@ playground:
difficulty: "beginner"
`;

test('valid metadata file passes validation without errors', () => {
withTempDir((tempDir) => {
test('valid metadata file passes validation without errors', async () => {
await withTempDir(async (tempDir) => {
const metadataFile = path.join(tempDir, 'metadata.yaml');
fs.writeFileSync(metadataFile, VALID_METADATA_YAML);
fs.writeFileSync(path.join(tempDir, 'README.md'), '# Test Model');
fs.writeFileSync(path.join(tempDir, 'testmodel.bngl'), 'begin model\nend model');

const errors = [];
validateMetadataFile(metadataFile, errors);
await validateMetadataFile(metadataFile, errors);

assert.deepStrictEqual(errors, []);
});
Expand Down Expand Up @@ -149,29 +149,29 @@ test('missing README.md adds error', () => {
fs.writeFileSync(path.join(tempDir, 'testmodel.bngl'), 'begin model\nend model');

const errors = [];
validateMetadataFile(metadataFile, errors);
await validateMetadataFile(metadataFile, errors);

assert.strictEqual(errors.length, 1);
assert.match(errors[0], /missing README\.md/);
});
});

test('missing .bngl file adds error', () => {
withTempDir((tempDir) => {
test('missing .bngl file adds error', async () => {
await withTempDir(async (tempDir) => {
const metadataFile = path.join(tempDir, 'metadata.yaml');
fs.writeFileSync(metadataFile, VALID_METADATA_YAML);
fs.writeFileSync(path.join(tempDir, 'README.md'), '# Test Model');

const errors = [];
validateMetadataFile(metadataFile, errors);
await validateMetadataFile(metadataFile, errors);

assert.strictEqual(errors.length, 1);
assert.match(errors[0], /no \.bngl files found alongside metadata\.yaml/);
});
});

test('invalid metadata structure adds errors', () => {
withTempDir((tempDir) => {
test('invalid metadata structure adds errors', async () => {
await withTempDir(async (tempDir) => {
const metadataFile = path.join(tempDir, 'metadata.yaml');
const invalidYaml = `
id: "test-model"
Expand All @@ -184,7 +184,7 @@ category: "invalid-category"
fs.writeFileSync(path.join(tempDir, 'testmodel.bngl'), 'begin model\nend model');

const errors = [];
validateMetadataFile(metadataFile, errors);
await validateMetadataFile(metadataFile, errors);

assert.ok(errors.length > 0);
assert.ok(errors.some(e => e.includes('missing or invalid name')));
Expand All @@ -196,8 +196,8 @@ category: "invalid-category"
});
});

test('multiple models without collection adds error if no primary model', () => {
withTempDir((tempDir) => {
test('multiple models without collection adds error if no primary model', async () => {
await withTempDir(async (tempDir) => {
const metadataFile = path.join(tempDir, 'metadata.yaml');
fs.writeFileSync(metadataFile, VALID_METADATA_YAML); // id: "test-model"
fs.writeFileSync(path.join(tempDir, 'README.md'), '# Test Model');
Expand All @@ -206,15 +206,15 @@ test('multiple models without collection adds error if no primary model', () =>
fs.writeFileSync(path.join(tempDir, 'othermodel2.bngl'), 'begin model\nend model');

const errors = [];
validateMetadataFile(metadataFile, errors);
await validateMetadataFile(metadataFile, errors);

assert.strictEqual(errors.length, 1);
assert.match(errors[0], /multiple \.bngl files require either a collection section or a primary model file/);
});
});

test('multiple models with collection valid count', () => {
withTempDir((tempDir) => {
test('multiple models with collection valid count', async () => {
await withTempDir(async (tempDir) => {
const metadataFile = path.join(tempDir, 'metadata.yaml');
const collectionYaml = VALID_METADATA_YAML + `
collection:
Expand All @@ -229,7 +229,7 @@ collection:
fs.writeFileSync(path.join(tempDir, 'model2.bngl'), '');

const errors = [];
validateMetadataFile(metadataFile, errors);
await validateMetadataFile(metadataFile, errors);

assert.deepStrictEqual(errors, []);
});
Expand Down
Loading