Skip to content
Closed
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
Binary file added .DS_Store
Binary file not shown.
19 changes: 19 additions & 0 deletions demo/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"name": "@contractual/demo",
"private": true,
"version": "0.0.0",
"license": "UNLICENSED",
"main": "dist/index.js",
"scripts": {
"test": "playwright test --config=playwright.config.ts"
},
"dependencies": {
"@contractual/client": "workspace:*",
"@contractual/fixtures": "workspace:*",
"@contractual/test": "workspace:*",
"@playwright/test": "^1.49.1"
},
"engines": {
"node": ">=18.12.0"
}
}
18 changes: 18 additions & 0 deletions demo/playwright.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import type { PlaywrightTestConfig } from '@playwright/test';

const config: PlaywrightTestConfig = {
name: 'demo-api',
testDir: __dirname,
testMatch: '*.e2e.test.ts',
workers: 1,
retries: 0,
use: {
baseURL: 'https://dash.readme.com/api/v1',
extraHTTPHeaders: {
'Content-Type': 'application/json',
Authorization: `Basic ${btoa('rdme_xn8s9h2390f02a267ff4123685499bbbf93db28092eb3fd3da3b817fa2d0b82a1ced11')}:`,
},
},
};

export default config;
27 changes: 27 additions & 0 deletions demo/readme-api.e2e.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { test } from '@contractual/test';
import { expect } from '@playwright/test';

// let createdVersionId: string;

test('create version', async ({ operation }) => {
await operation('basic version 1.2.0 from 1.0.0', async ({ response }) => {
expect(response.status).toBe(400);
});
});

// test('create version', async ({ operation }) => {
// const response = await operation('rc version with something else');
//
// expect(response.status).toBe(400);
// // expect(response.body._id).toBeDefined();
//
// // createdVersionId = response.body._id;
// });

test('delete version', async ({ operation }) => {
const response = await operation(() => ({
params: { versionId: createdVersionId },
}));

expect(response.body._id).toBeDefined();
});
32 changes: 32 additions & 0 deletions demo/reporter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import type {
Reporter,
TestCase,
TestResult,
FullResult,
FullConfig,
Suite,
} from '@playwright/test/reporter';

class ContractualReporter implements Reporter {
constructor(options: { customOption?: string } = {}) {
console.log(`my-awesome-reporter setup with customOption set to ${options.customOption}`);
}

onBegin(config: FullConfig, suite: Suite) {
console.log(`Starting the run with ${suite.allTests().length} tests`);
}

onTestBegin(test: TestCase) {
console.log(`Starting test ${test.title}`);
}

onTestEnd(test: TestCase, result: TestResult) {
console.log(`Finished test ${test.title}: ${result.status}`);
}

onEnd(result: FullResult) {
console.log(`Finished the run: ${result.status}`);
}
}

export default ContractualReporter;
3 changes: 3 additions & 0 deletions packages/cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,9 @@
"@contractual/generators.fixtures": "workspace:*",
"commander": "^12.1.0"
},
"devDependencies": {
"@contractual/fixtures": "workspace:*"
},
"publishConfig": {
"access": "public",
"provenance": true
Expand Down
3 changes: 3 additions & 0 deletions packages/fixtures/.eslintrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"extends": "../../.eslintrc"
}
1 change: 1 addition & 0 deletions packages/fixtures/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
!fixtures/*
16 changes: 16 additions & 0 deletions packages/fixtures/config/fixtures.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
{
"$schema": "https://json.schemastore.org/tsconfig",
"_version": "0.0.0",
"compilerOptions": {
"outDir": "../output",
"sourceMap": false,
"module": "esnext",
"target": "esnext",
"lib": ["esnext"],
"strict": true,
"esModuleInterop": true,
"skipLibCheck": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": false
}
}
24 changes: 24 additions & 0 deletions packages/fixtures/config/output/create-version.fixtures.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { registerFixtures } from '@contractual/fixtures';
export default registerFixtures('create version', {
'basic version': () => ({
body: {
version: 'string',
codename: 'string',
from: 'string',
is_stable: true,
is_beta: true,
is_hidden: true,
is_deprecated: true,
},
}),
'rc version': ({ extend }) => {
return extend({
'with something else': () => ({
body: {
version: 'string',
from: 'string',
},
}),
});
},
});
13 changes: 13 additions & 0 deletions packages/fixtures/config/output/delete-version.fixtures.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { registerFixtures } from '@contractual/fixtures';
export default registerFixtures('delete version', {
'basic delete': () => ({
params: {
versionId: 'string',
}
}),
'complex': () => ({
params: {
versionId: 'string',
}
}),
});
1 change: 1 addition & 0 deletions packages/fixtures/fixtures/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export const Fixtures = {} as unknown;
1 change: 1 addition & 0 deletions packages/fixtures/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './src';
12 changes: 12 additions & 0 deletions packages/fixtures/jest.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import type { Config } from 'jest';
import baseConfig from '../../jest.base.config';

const config: Config = {
...baseConfig(process.env.COVERAGE_DIR),
id: 'fixtures',
displayName: 'fixtures',
collectCoverageFrom: ['src/**/*.ts', 'test/**/*.ts'],
coveragePathIgnorePatterns: ['index.ts', 'types.ts'],
};

export default config;
24 changes: 24 additions & 0 deletions packages/fixtures/output/create-version.fixtures.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { registerFixtures } from '@contractual/fixtures';
export default registerFixtures('create version', {
'basic version': () => ({
body: {
version: 'string',
codename: 'string',
from: 'string',
is_stable: true,
is_beta: true,
is_hidden: true,
is_deprecated: true,
},
}),
'rc version': ({ extend }) => {
return extend({
'with something else': () => ({
body: {
version: 'string',
from: 'string',
},
}),
});
},
});
13 changes: 13 additions & 0 deletions packages/fixtures/output/delete-version.fixtures.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { registerFixtures } from '@contractual/fixtures';
export default registerFixtures('delete version', {
'basic delete': () => ({
params: {
versionId: 'string',
}
}),
'complex': () => ({
params: {
versionId: 'string',
}
}),
});
64 changes: 64 additions & 0 deletions packages/fixtures/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
{
"name": "@contractual/fixtures",
"private": false,
"version": "0.0.0",
"license": "Apache-2.0",
"type": "module",
"module": "dist/index.js",
"main": "dist/index.js",
"exports": {
".": {
"import": "./dist/src/index.js",
"require": "./dist/src/index.js"
},
"./config": {
"import": "./config/fixtures.json",
"require": "./config/fixtures.json"
},
"./fixtures": {
"import": "./dist/fixtures/index.js",
"require": "./dist/fixtures/index.js"
}
},
"repository": {
"type": "git",
"url": "https://github.com/contractual-dev/contractual.git",
"directory": "packages/fixtures"
},
"homepage": "https://contractual.dev",
"bugs": {
"url": "https://github.com/contractual-dev/contractual/issues"
},
"contributors": [
{
"name": "Omer Morad",
"email": "omer.moradd@gmail.com"
}
],
"engines": {
"node": ">=18.12.0"
},
"scripts": {
"prebuild": "pnpm rimraf dist",
"build": "pnpm tsc -p tsconfig.build.json",
"tester": "jest --coverage --verbose",
"lint": "pnpm eslint '{src,test}/**/*.ts'"
},
"files": [
"generator",
"config",
"dist",
"README.md"
],
"dependencies": {
"@contractual/client": "workspace:*",
"@contractual/types.fixtures": "workspace:*"
},
"devDependencies": {
"typescript": "~5.7.2"
},
"publishConfig": {
"access": "public",
"provenance": true
}
}
1 change: 1 addition & 0 deletions packages/fixtures/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './regsiter-fixtures.js';
63 changes: 63 additions & 0 deletions packages/fixtures/src/regsiter-fixtures.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
import type { ApiClientInput, ApiOperationToClientMethod } from '@contractual/contract';
import type { ApiOperations } from '@contractual/contract/contract';
import type {
FixtureCallback,
FixturesBuilder,
GeneratedFixtures,
} from '@contractual/types.fixtures';

export type RegisterFixturesReturnType<TOperation extends keyof typeof ApiOperations> = {
operation: TOperation;
fixtures: GeneratedFixtures<TOperation>;
};

export function registerFixtures<TOperation extends keyof typeof ApiOperations>(
operation: TOperation,
fixturesBuilder: FixturesBuilder<TOperation>
): RegisterFixturesReturnType<TOperation> {
const processFixture = (
callback: FixtureCallback<TOperation>,
baseKey: string
): GeneratedFixtures<TOperation> => {
// Define a flag to detect if `extend` was called
let extendCalled = false;

const fixture = callback({
extend: (extensions: FixturesBuilder<TOperation>) => {
// Mark that `extend` was called
extendCalled = true;

// Recursively process nested fixtures with updated keys
return Object.entries<FixtureCallback<TOperation>>(extensions).reduce(
(acc: GeneratedFixtures<TOperation>, [key, nestedCallback]) => {
const nestedKey = `${baseKey} ${key}`;
const nestedResult = processFixture(nestedCallback, nestedKey);

// Merge nested results without wrapping
return { ...acc, ...nestedResult };
},
{} as GeneratedFixtures<TOperation>
) as ApiClientInput<ApiOperationToClientMethod<TOperation>>;
},
});

// If `extend` was called, do NOT include the baseKey itself
if (extendCalled) {
return fixture as GeneratedFixtures<TOperation>;
}

// If no `extend` was called, return the baseKey fixture directly
return { [baseKey]: fixture };
};

// Process all top-level fixtures
const fixtures = Object.entries(fixturesBuilder).reduce<GeneratedFixtures<TOperation>>(
(result, [key, callback]) => ({
...result,
...processFixture(callback, key), // Add processed fixtures
}),
{} as GeneratedFixtures<TOperation>
);

return { operation, fixtures };
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`Register Fixtures Unit Spec should return the correct snapshot 1`] = `
{
"fixtures": {
"basic version": {
"body": {
"codename": "string",
"from": "string",
"is_beta": true,
"is_deprecated": true,
"is_hidden": true,
"is_stable": true,
"version": "string",
},
},
"rc version with something else": {
"body": {
"from": "string",
"version": "string",
},
},
},
"operation": "create version",
}
`;
Loading