Skip to content

Commit 2480508

Browse files
CCM-13342: src changes except yml from 2025-11-17/separate-workflows-for-docs-002
1 parent a3c1198 commit 2480508

File tree

12 files changed

+6336
-705
lines changed

12 files changed

+6336
-705
lines changed

src/cloudevents/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ deploy-ci:
147147
pwd && \
148148
ls -la
149149
@echo "from manual test tools versions file contains:"
150-
cat .tool-versions
150+
cat .tool-versions || echo " -> .tool-versions file not found in this directory"
151151
/usr/local/bin/asdf --version
152152
@echo "Setting up asdf environment and adding plugins"
153153
export ASDF_DATA_DIR=$$HOME/.asdf && \

src/cloudevents/package-lock.json

Lines changed: 4968 additions & 475 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cloudevents/readme-index.yaml

Lines changed: 83 additions & 179 deletions
Large diffs are not rendered by default.

src/cloudevents/tools/cache/__tests__/schema-cache-network.test.ts

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@ describe('schema-cache network operations', () => {
1919
}
2020
});
2121

22-
beforeAll((done) => {
22+
beforeAll(async () => {
23+
console.log('[TEST] Starting HTTP server setup...');
2324
// Create a local HTTP server for testing
2425
server = http.createServer((req, res) => {
26+
console.log(`[TEST] Server received request for: ${req.url}`);
2527
// Handle different test scenarios based on URL path
2628
if (req.url === '/schema.json') {
2729
res.writeHead(200, { 'Content-Type': 'application/json' });
@@ -50,15 +52,28 @@ describe('schema-cache network operations', () => {
5052
}
5153
});
5254

53-
server.listen(0, 'localhost', () => {
54-
const address = server.address() as AddressInfo;
55-
serverUrl = `http://localhost:${address.port}`;
56-
done();
55+
await new Promise<void>((resolve, reject) => {
56+
server.listen(0, '127.0.0.1', (err?: Error) => {
57+
if (err) {
58+
console.error('[TEST] Server failed to start:', err);
59+
reject(err);
60+
return;
61+
}
62+
const address = server.address() as AddressInfo;
63+
serverUrl = `http://127.0.0.1:${address.port}`;
64+
console.log(`[TEST] Server started successfully on ${serverUrl}`);
65+
resolve();
66+
});
5767
});
5868
});
5969

60-
afterAll((done) => {
61-
server.close(done);
70+
afterAll(async () => {
71+
await new Promise<void>((resolve, reject) => {
72+
server.close((err) => {
73+
if (err) reject(err);
74+
else resolve();
75+
});
76+
});
6277
});
6378

6479
beforeEach(() => {

src/cloudevents/tools/generator/__tests__/docs-generator.test.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -592,10 +592,19 @@ describe('DocsGenerator', () => {
592592
});
593593

594594
it('should process multiple schemas', async () => {
595-
// Create multiple schema files
596-
fs.writeFileSync(path.join(INPUT_DIR, 'schema1.schema.json'), JSON.stringify({ type: 'object' }));
597-
fs.writeFileSync(path.join(INPUT_DIR, 'schema2.schema.json'), JSON.stringify({ type: 'string' }));
598-
fs.writeFileSync(path.join(INPUT_DIR, 'schema3.schema.yml'), JSON.stringify({ type: 'number' }));
595+
// Create multiple schema files with unique IDs
596+
fs.writeFileSync(path.join(INPUT_DIR, 'schema1.schema.json'), JSON.stringify({
597+
$id: 'schema1.json',
598+
type: 'object'
599+
}));
600+
fs.writeFileSync(path.join(INPUT_DIR, 'schema2.schema.json'), JSON.stringify({
601+
$id: 'schema2.json',
602+
type: 'string'
603+
}));
604+
fs.writeFileSync(path.join(INPUT_DIR, 'schema3.schema.yml'), JSON.stringify({
605+
$id: 'schema3.json',
606+
type: 'number'
607+
}));
599608

600609
const config: DocsGeneratorConfig = {
601610
inputDir: INPUT_DIR,
@@ -606,6 +615,9 @@ describe('DocsGenerator', () => {
606615
const generator = new DocsGenerator(config);
607616
const result = await generator.generate();
608617

618+
if (!result.success) {
619+
console.error('Generation failed:', result.error);
620+
}
609621
expect(result.success).toBe(true);
610622
expect(result.schemasProcessed).toBe(3);
611623
});

src/cloudevents/tools/generator/docs-generator/generate-docs-cli.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -132,11 +132,23 @@ export async function handleCli(args: string[]): Promise<CliResult> {
132132
}
133133

134134
// Execute CLI if this module is run directly
135-
if (import.meta.url === `file://${process.argv[1]}`) {
136-
handleCli(process.argv.slice(2)).then((result) => {
137-
process.exit(result.exitCode);
138-
}).catch((err) => {
139-
console.error('Unexpected error:', err);
140-
process.exit(1);
141-
});
135+
// Note: This uses eval to prevent Jest/CommonJS from parsing import.meta
136+
// istanbul ignore next - CLI entry point, difficult to test in Jest
137+
// @ts-ignore
138+
try {
139+
const importMeta = eval('import.meta');
140+
if (importMeta && importMeta.url === `file://${process.argv[1]}`) {
141+
handleCli(process.argv.slice(2)).then((result) => {
142+
process.exit(result.exitCode);
143+
}).catch((err) => {
144+
console.error('Unexpected error:', err);
145+
process.exit(1);
146+
});
147+
}
148+
} catch {
149+
// Intentionally ignoring exception: import.meta not available in CommonJS/Jest environments.
150+
// This is expected when the module is imported rather than executed directly.
151+
if (process.env.DEBUG) {
152+
console.debug('Module loaded in CommonJS/Jest environment (import.meta not available)');
153+
}
142154
}

src/cloudevents/tools/generator/readme-generator/readme-index-generator.ts

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -199,20 +199,16 @@ export class ReadmeIndexGenerator {
199199
return this.metadata.schema_labels[baseName];
200200
}
201201

202-
let schemaType: string;
203-
204-
switch (category) {
205-
case "profile":
206-
schemaType = "Profile";
207-
break;
208-
case "events":
209-
schemaType = this.getSchemaName(filename).toLowerCase();
210-
break;
211-
default:
212-
schemaType = this.getSchemaName(filename);
202+
if (category === "profile") return "Profile";
203+
if (category === "definitions") return this.getSchemaName(filename);
204+
if (category === "data") {
205+
return this.getSchemaName(filename).replace(" Data", " Data");
206+
}
207+
if (category === "events") {
208+
return this.getSchemaName(filename).replace(" Event", " Event");
213209
}
214210

215-
return schemaType;
211+
return this.getSchemaName(filename);
216212
}
217213

218214
/**

src/cloudevents/tools/generator/readme-generator/update-readme-cli.ts

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -60,17 +60,29 @@ export async function handleCli(
6060
}
6161

6262
// Execute CLI if this module is run directly
63-
if (import.meta.url === `file://${process.argv[1]}`) {
64-
// Get the root directory (3 levels up from this file: tools/generator/readme-generator)
65-
const rootDir = new URL("../../../", import.meta.url).pathname;
66-
const args = process.argv.slice(2);
63+
// Note: This uses eval to prevent Jest/CommonJS from parsing import.meta
64+
// istanbul ignore next - CLI entry point, difficult to test in Jest
65+
// @ts-ignore
66+
try {
67+
const importMeta = eval('import.meta');
68+
if (importMeta && importMeta.url === `file://${process.argv[1]}`) {
69+
// Get the root directory (3 levels up from this file: tools/generator/readme-generator)
70+
const rootDir = new URL("../../../", importMeta.url).pathname;
71+
const args = process.argv.slice(2);
6772

68-
handleCli(args, rootDir)
69-
.then((result) => {
70-
process.exit(result.exitCode);
71-
})
72-
.catch((err) => {
73-
console.error("Unexpected error:", err);
74-
process.exit(1);
75-
});
73+
handleCli(args, rootDir)
74+
.then((result) => {
75+
process.exit(result.exitCode);
76+
})
77+
.catch((err) => {
78+
console.error("Unexpected error:", err);
79+
process.exit(1);
80+
});
81+
}
82+
} catch {
83+
// Intentionally ignoring exception: import.meta not available in CommonJS/Jest environments.
84+
// This is expected when the module is imported rather than executed directly.
85+
if (process.env.DEBUG) {
86+
console.debug("Module loaded in CommonJS/Jest environment (import.meta not available)");
87+
}
7688
}
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
/**
2+
* CLI tests for validate.ts
3+
* Tests the command-line interface by spawning processes with tsx
4+
* For faster validation tests using direct imports, see validator-integration.test.ts
5+
*/
6+
7+
import { beforeEach, afterEach, describe, expect, it } from '@jest/globals';
8+
import fs from 'fs';
9+
import path from 'path';
10+
import { spawnSync } from 'child_process';
11+
12+
const SCRIPT_PATH = path.join(__dirname, '..', 'validate.ts');
13+
const TEST_DIR = path.join(__dirname, 'temp-validate-cli-test');
14+
15+
/**
16+
* Helper to run validator CLI and handle exit codes
17+
* Uses tsx for faster execution than ts-node
18+
*/
19+
function runValidator(schemaPath: string, dataPath: string, baseDir?: string): { success: boolean; output: string; error: string } {
20+
try {
21+
const args = baseDir ? ['--base', baseDir, schemaPath, dataPath] : [schemaPath, dataPath];
22+
const result = spawnSync('npx', ['tsx', SCRIPT_PATH, ...args], {
23+
encoding: 'utf-8',
24+
timeout: 15000 // tsx is much faster than ts-node
25+
});
26+
27+
return {
28+
success: result.status === 0,
29+
output: result.stdout || '',
30+
error: result.stderr || ''
31+
};
32+
} catch (error) {
33+
return {
34+
success: false,
35+
output: '',
36+
error: String(error)
37+
};
38+
}
39+
}
40+
41+
describe('validate.ts CLI', () => {
42+
// Reduced timeout since tsx is much faster than ts-node
43+
jest.setTimeout(20000); // 20 seconds per test
44+
45+
beforeEach(() => {
46+
// Create test directory
47+
if (!fs.existsSync(TEST_DIR)) {
48+
fs.mkdirSync(TEST_DIR, { recursive: true });
49+
}
50+
});
51+
52+
afterEach(() => {
53+
// Clean up test directory
54+
if (fs.existsSync(TEST_DIR)) {
55+
fs.rmSync(TEST_DIR, { recursive: true, force: true });
56+
}
57+
});
58+
59+
describe('command line arguments', () => {
60+
it('should exit with error when no arguments provided', () => {
61+
const result = spawnSync('npx', ['tsx', SCRIPT_PATH], { encoding: 'utf-8', timeout: 15000 });
62+
expect(result.status).not.toBe(0);
63+
expect(result.stderr).toContain('Usage:');
64+
});
65+
66+
it('should exit with error when only schema argument provided', () => {
67+
const schemaFile = path.join(TEST_DIR, 'schema.json');
68+
fs.writeFileSync(schemaFile, JSON.stringify({ type: 'object' }));
69+
70+
const result = spawnSync('npx', ['tsx', SCRIPT_PATH, schemaFile], { encoding: 'utf-8', timeout: 15000 });
71+
expect(result.status).not.toBe(0);
72+
expect(result.stderr).toContain('Usage:');
73+
});
74+
});
75+
76+
describe('CLI output format', () => {
77+
it('should output "Valid!" for valid data', () => {
78+
const schemaFile = path.join(TEST_DIR, 'simple.schema.json');
79+
const dataFile = path.join(TEST_DIR, 'data.json');
80+
81+
fs.writeFileSync(schemaFile, JSON.stringify({
82+
type: 'object',
83+
properties: { name: { type: 'string' } }
84+
}));
85+
fs.writeFileSync(dataFile, JSON.stringify({ name: 'test' }));
86+
87+
const result = runValidator(schemaFile, dataFile);
88+
expect(result.success).toBe(true);
89+
expect(result.output).toContain('Valid!');
90+
});
91+
92+
it('should output error message for invalid data', () => {
93+
const schemaFile = path.join(TEST_DIR, 'required.schema.json');
94+
const dataFile = path.join(TEST_DIR, 'data.json');
95+
96+
fs.writeFileSync(schemaFile, JSON.stringify({
97+
type: 'object',
98+
properties: { name: { type: 'string' } },
99+
required: ['name']
100+
}));
101+
fs.writeFileSync(dataFile, JSON.stringify({}));
102+
103+
const result = runValidator(schemaFile, dataFile);
104+
expect(result.success).toBe(false);
105+
expect(result.error).toContain('Invalid:');
106+
});
107+
});
108+
109+
describe('--base option', () => {
110+
it('should accept --base option for schema directory', () => {
111+
const schemaFile = path.join(TEST_DIR, 'schema.json');
112+
const dataFile = path.join(TEST_DIR, 'data.json');
113+
114+
fs.writeFileSync(schemaFile, JSON.stringify({
115+
type: 'object',
116+
properties: { value: { type: 'string' } }
117+
}));
118+
fs.writeFileSync(dataFile, JSON.stringify({ value: 'test' }));
119+
120+
const result = runValidator(schemaFile, dataFile, TEST_DIR);
121+
expect(result.success).toBe(true);
122+
});
123+
});
124+
125+
describe('error handling', () => {
126+
it('should handle non-existent schema file', () => {
127+
const schemaFile = path.join(TEST_DIR, 'nonexistent.schema.json');
128+
const dataFile = path.join(TEST_DIR, 'data.json');
129+
130+
fs.writeFileSync(dataFile, JSON.stringify({ value: 'test' }));
131+
132+
const result = runValidator(schemaFile, dataFile);
133+
expect(result.success).toBe(false);
134+
});
135+
136+
it('should handle non-existent data file', () => {
137+
const schemaFile = path.join(TEST_DIR, 'schema.json');
138+
const dataFile = path.join(TEST_DIR, 'nonexistent.json');
139+
140+
fs.writeFileSync(schemaFile, JSON.stringify({ type: 'object' }));
141+
142+
const result = runValidator(schemaFile, dataFile);
143+
expect(result.success).toBe(false);
144+
});
145+
146+
it('should handle invalid JSON in data file', () => {
147+
const schemaFile = path.join(TEST_DIR, 'schema.json');
148+
const dataFile = path.join(TEST_DIR, 'data.json');
149+
150+
fs.writeFileSync(schemaFile, JSON.stringify({ type: 'object' }));
151+
fs.writeFileSync(dataFile, '{ invalid json }');
152+
153+
const result = runValidator(schemaFile, dataFile);
154+
expect(result.success).toBe(false);
155+
});
156+
});
157+
});

0 commit comments

Comments
 (0)