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
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@
"author": "accordproject.org",
"license": "Apache-2.0",
"dependencies": {
"@accordproject/cicero-core": "^2.0.0",
"@accordproject/cicero-core": "^2.1.1",
"@accordproject/concerto-codegen": "4.1.3",
"@accordproject/concerto-core": "4.1.4",
"@accordproject/concerto-util": "4.1.4",
Expand Down
42 changes: 4 additions & 38 deletions test/TemplateArchiveProcessor.test.ts
Original file line number Diff line number Diff line change
@@ -1,36 +1,10 @@
import { cpSync, mkdtempSync, readFileSync, writeFileSync } from 'fs';
import { cpSync, mkdtempSync, writeFileSync } from 'fs';
import os from 'os';
import path from 'path';
import {Template} from '@accordproject/cicero-core';
import { TemplateArchiveProcessor, InitResponse, TriggerResponse } from '../src/TemplateArchiveProcessor';

const TEMPLATE_DIR = 'test/archives/latedeliveryandpenalty-typescript';
const TEMPLATE_MODEL_DIR = path.join(TEMPLATE_DIR, 'model');

function mockArchiveModelFetches() {
const originalFetch = global.fetch.bind(global);
const modelByUrl = new Map([
['https://models.accordproject.org/time@0.3.0.cto', readFileSync(path.join(TEMPLATE_MODEL_DIR, '@models.accordproject.org.time@0.3.0.cto'), 'utf-8')],
['https://models.accordproject.org/accordproject/contract@0.2.0.cto', readFileSync(path.join(TEMPLATE_MODEL_DIR, '@models.accordproject.org.accordproject.contract@0.2.0.cto'), 'utf-8')],
['https://models.accordproject.org/accordproject/runtime@0.2.0.cto', readFileSync(path.join(TEMPLATE_MODEL_DIR, '@models.accordproject.org.accordproject.runtime@0.2.0.cto'), 'utf-8')]
]);

return jest.spyOn(global, 'fetch').mockImplementation(async (input: string | URL | Request, init?: RequestInit) => {
const url = typeof input === 'string' ? input : input instanceof URL ? input.toString() : input.url;
const model = modelByUrl.get(url);

if (model !== undefined) {
return new Response(model, {
status: 200,
headers: {
'content-type': 'text/plain'
}
});
}

return originalFetch(input, init);
});
}

async function loadTemplate(logicSource?: string): Promise<Template> {
if (!logicSource) {
Expand All @@ -45,14 +19,6 @@ async function loadTemplate(logicSource?: string): Promise<Template> {
}

describe('template archive processor', () => {
beforeEach(() => {
mockArchiveModelFetches();
});

afterEach(() => {
jest.restoreAllMocks();
});

test('should draft a template', async () => {
const template = await loadTemplate();
const templateArchiveProcessor = new TemplateArchiveProcessor(template);
Expand Down Expand Up @@ -245,7 +211,7 @@ export default class PlainLogic {
};

it('rejects a request whose type does not extend the runtime Request', async () => {
const template = await Template.fromDirectory('test/archives/latedeliveryandpenalty-typescript', {offline: true});
const template = await loadTemplate();
const templateArchiveProcessor = new TemplateArchiveProcessor(template);
const stateResponse = await templateArchiveProcessor.init(VALID_DATA);
// A well-formed Response object is a valid Concerto instance (so it passes
Expand All @@ -262,7 +228,7 @@ export default class PlainLogic {
});

it('init does not throw for a stateless template (empty placeholder state)', async () => {
const template = await Template.fromDirectory('test/archives/latedeliveryandpenalty-typescript', {offline: true});
const template = await loadTemplate();
const templateArchiveProcessor = new TemplateArchiveProcessor(template);
// A stateless template (no compiled `init`) yields the empty placeholder `{ state: {} }`.
// init() must not try to serialize/validate that classless placeholder.
Expand All @@ -273,7 +239,7 @@ export default class PlainLogic {
});

it('does not exempt a non-empty state that is missing $class (only {} is skipped)', async () => {
const template = await Template.fromDirectory('test/archives/latedeliveryandpenalty-typescript', {offline: true});
const template = await loadTemplate();
const templateArchiveProcessor = new TemplateArchiveProcessor(template);
// A non-empty classless object is not the stateless placeholder - it must still be
// validated (and rejected), not silently skipped.
Expand Down
10 changes: 8 additions & 2 deletions test/TemplateMarkInterpreter.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ const CLAUSE_LIBRARY = {

const GOOD_TEMPLATES_ROOT = './test/templates/good';
const BAD_TEMPLATES_ROOT = './test/templates/bad';
const MONEY_MODEL_FILES = [
'@models.accordproject.org.money@0.3.0.cto',
'@models.accordproject.org.money@1.0.0.cto'
];

describe('templatemark interpreter', () => {
jest.setTimeout(30000);
Expand Down Expand Up @@ -70,8 +74,10 @@ describe('templatemark interpreter', () => {
const data = JSON.parse(readFileSync(`${GOOD_TEMPLATES_ROOT}/${templateName}/data.json`, 'utf-8'));

const modelManager = new ModelManager();
modelManager.addCTOModel(model, undefined, true);
await modelManager.updateExternalModels();
MONEY_MODEL_FILES.forEach(file => {
modelManager.addCTOModel(readFileSync(path.join(__dirname, 'models', file), 'utf-8'), file);
});
modelManager.addCTOModel(model);
const engine = new TemplateMarkInterpreter(modelManager, CLAUSE_LIBRARY);

const templateMarkTransformer = new TemplateMarkTransformer();
Expand Down
34 changes: 34 additions & 0 deletions test/models/@models.accordproject.org.money@0.3.0.cto
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

concerto version "^3.0.0"

namespace org.accordproject.money@0.3.0

/**
* Represents an amount of money.
*/
concept MonetaryAmount {
o Double doubleValue
o CurrencyCode currencyCode
}

/**
* Currency codes required by the offline template fixtures.
*/
enum CurrencyCode {
o EUR
o GBP
o USD
}
52 changes: 52 additions & 0 deletions test/models/@models.accordproject.org.money@1.0.0.cto
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
concerto version "^3.0.0"

namespace org.accordproject.money@1.0.0

/**
* An ISO 4217 alphabetic currency code.
*/
scalar CurrencyCode extends String regex=/^[A-Z]{3}$/

/**
* An approximate floating-point monetary amount.
*/
concept ApproximateAmount {
o Double doubleValue
o CurrencyCode currencyCode
}

/**
* A unit of account.
*/
concept Unit {
o String code
o String scheme default="iso4217"
o String identifier optional
o Integer scale range=[0,]
}

/**
* An arbitrary-precision integer encoded as a string.
*/
scalar BigInteger extends String regex=/^(0|-?[1-9][0-9]*)$/

/**
* A precise fixed-point monetary amount.
*/
concept PreciseAmount {
o BigInteger unscaledValue
o Unit unit
}
4 changes: 1 addition & 3 deletions test/templates/good/optional-nested/model.cto
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
namespace org.example.ap2.mandate@1.1.1
import org.accordproject.money@0.3.0.{MonetaryAmount} from https://models.accordproject.org/money@0.3.0.cto
import org.accordproject.time@0.3.0.{Duration} from https://models.accordproject.org/time@0.3.0.cto
import org.accordproject.party@0.2.0.{Party} from https://models.accordproject.org/accordproject/party@0.2.0.cto

concept Address {
o String line1
Expand Down Expand Up @@ -44,4 +42,4 @@ concept TemplateData {
o String[] favoriteColors
o AP2MandateData mandate
o Order order
}
}
Loading