Skip to content

Commit

Permalink
wip: module feature
Browse files Browse the repository at this point in the history
  • Loading branch information
Yogu committed Jul 17, 2024
1 parent 46adf4f commit 8425575
Show file tree
Hide file tree
Showing 29 changed files with 1,268 additions and 41 deletions.
84 changes: 84 additions & 0 deletions spec/model/create-model.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@ import { expect } from 'chai';
import { DocumentNode } from 'graphql';
import gql from 'graphql-tag';
import { createSimpleModel } from './model-spec.helper';
import { parseProject } from '../../src/schema/schema-builder';
import { Project, ProjectSource } from '../../core-exports';
import { Severity, ValidationContext, createModel } from '../../src/model';
import { expectSingleErrorToInclude, expectToBeValid } from './implementation/validation-utils';

describe('createModel', () => {
it('translates _key: String @key properly', () => {
Expand Down Expand Up @@ -376,4 +380,84 @@ describe('createModel', () => {
expect(type.getFieldOrThrow('createdAt').isHidden).to.be.false;
expect(type.getFieldOrThrow('test2').isHidden).to.be.true;
});

describe('with modules', () => {
it('extracts the module definitions', () => {
const validationContext = new ValidationContext();
const parsedProject = parseProject(
new Project([
new ProjectSource(
'modules.json',
JSON.stringify({
modules: ['module1', 'module2'],
}),
),
]),
validationContext,
);
expectToBeValid(validationContext.asResult());
const model = createModel(parsedProject, {
withModuleDefinitions: true,
});
expectToBeValid(model);
const modules = model.modules;
expect(modules).to.have.lengthOf(2);
const module1 = modules[0];
expect(module1.name).to.equal('module1');
expect(module1.loc?.start.offset).to.equal(12);
expect(module1.loc?.end.offset).to.equal(21);
});

it('does not allow module declarations if withModuleDeclarations is not set', () => {
const validationContext = new ValidationContext();
const parsedProject = parseProject(
new Project([
new ProjectSource(
'modules.json',
JSON.stringify({
modules: ['module1', 'module2'],
}),
),
]),
validationContext,
);
expectToBeValid(validationContext.asResult());
const model = createModel(parsedProject);
expectSingleErrorToInclude(
model,
'Module declarations are not supported in this context.',
);
const modules = model.modules;
expect(modules).to.have.lengthOf(0);
});

it('does not allow duplicate module names', () => {
const validationContext = new ValidationContext();
const parsedProject = parseProject(
new Project([
new ProjectSource(
'modules.json',
JSON.stringify({
modules: ['module1', 'module1'],
}),
),
]),
validationContext,
);
expectToBeValid(validationContext.asResult());
const model = createModel(parsedProject, {
withModuleDefinitions: true,
});
const validationResult = model.validate();
expect(validationResult.messages.length).to.equal(2);
expect(validationResult.messages[0].severity).to.equal(Severity.ERROR);
expect(validationResult.messages[0].message).to.equal(
'Duplicate module declaration: "module1".',
);
expect(validationResult.messages[1].severity).to.equal(Severity.ERROR);
expect(validationResult.messages[1].message).to.equal(
'Duplicate module declaration: "module1".',
);
});
});
});
19 changes: 14 additions & 5 deletions spec/model/implementation/validation-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,27 +5,36 @@ import {
ValidationContext,
} from '../../../src/model/validation/validation-context';

export function validate(component: ModelComponent): ValidationResult {
export function validate(component: ModelComponent | ValidationResult): ValidationResult {
if (component instanceof ValidationResult) {
return component;
}
const context = new ValidationContext();
component.validate(context);
return context.asResult();
}

export function expectToBeValid(component: ModelComponent) {
export function expectToBeValid(component: ModelComponent | ValidationResult) {
const result = validate(component);
expect(result.hasMessages(), result.toString()).to.be.false;
}

export function expectSingleErrorToInclude(component: ModelComponent, errorPart: string) {
export function expectSingleErrorToInclude(
component: ModelComponent | ValidationResult,
errorPart: string,
) {
expectSingleMessageToInclude(component, errorPart, Severity.ERROR);
}

export function expectSingleWarningToInclude(component: ModelComponent, errorPart: string) {
export function expectSingleWarningToInclude(
component: ModelComponent | ValidationResult,
errorPart: string,
) {
expectSingleMessageToInclude(component, errorPart, Severity.WARNING);
}

export function expectSingleMessageToInclude(
component: ModelComponent,
component: ModelComponent | ValidationResult,
errorPart: string,
severity: Severity,
) {
Expand Down
55 changes: 31 additions & 24 deletions spec/schema/ast-validation-modules/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export function assertValidatorAcceptsAndDoesNotWarn(
export interface ValidationOptions {
readonly permissionProfiles?: PermissionProfileConfigMap;
timeToLive?: ReadonlyArray<TimeToLiveConfig>;
withModuleDefinitions?: boolean;
}

export function validate(
Expand Down Expand Up @@ -81,33 +82,39 @@ export function validate(
return intermediateResult;
}

const model = createModel({
sources: [
{
kind: ParsedProjectSourceBaseKind.GRAPHQL,
document: ast,
namespacePath: [],
},
{
kind: ParsedProjectSourceBaseKind.OBJECT,
object: {
permissionProfiles: options.permissionProfiles || {
default: {
permissions: [
{
roles: ['admin'],
access: 'readWrite',
},
],
const model = createModel(
{
sources: [
{
kind: ParsedProjectSourceBaseKind.GRAPHQL,
document: ast,
namespacePath: [],
},
{
kind: ParsedProjectSourceBaseKind.OBJECT,
object: {
permissionProfiles: options.permissionProfiles || {
default: {
permissions: [
{
roles: ['admin'],
access: 'readWrite',
},
],
},
},
timeToLive: options.timeToLive,
modules: options.withModuleDefinitions
? ['module1', 'module2', 'module3']
: undefined,
},
timeToLive: options.timeToLive,
namespacePath: [],
pathLocationMap: {},
},
namespacePath: [],
pathLocationMap: {},
},
],
});
],
},
{ withModuleDefinitions: options.withModuleDefinitions },
);
const astResults = validatePostMerge(ast, model);

return new ValidationResult([
Expand Down
Loading

0 comments on commit 8425575

Please sign in to comment.