Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Advanced if diff #738

Merged
merged 21 commits into from
May 28, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
0ad4ca6
fix(util): tune yaml validation schema
narekhovhannisyan May 18, 2024
5248f24
fix(util): tune convert to xorable to handle objects
narekhovhannisyan May 18, 2024
98c8cd3
feat(lib): tune compare to do advanced execution check
narekhovhannisyan May 18, 2024
e6df2cd
fix(src): execution is present in catch
narekhovhannisyan May 18, 2024
ee57cab
fix(util): in helpers return empty string if piped source is unvailable
narekhovhannisyan May 23, 2024
e5e7d91
fix(util): move messages to strings, fix strategy
narekhovhannisyan May 23, 2024
810d56a
fix(types): add message to difference object
narekhovhannisyan May 23, 2024
f2908b7
feat(lib): introduce classified error to load
narekhovhannisyan May 23, 2024
0ffb6ed
feat(config): move all error messages from if-diff to strings
narekhovhannisyan May 23, 2024
f979d67
test(util): implement units for helpers
narekhovhannisyan May 23, 2024
79c1492
test(util): implement units for if diff cli args
narekhovhannisyan May 23, 2024
f8d6a07
test(lib): refine old tests, add units for if-diff loader
narekhovhannisyan May 23, 2024
a7d294f
test(mocks): refine json
narekhovhannisyan May 23, 2024
2617ccc
test(mocks): add readline
narekhovhannisyan May 23, 2024
9ee3932
chore(src): fetch changes from if-diff
narekhovhannisyan May 24, 2024
d0f35ac
test(util): gain unit coverage on args
narekhovhannisyan May 24, 2024
32ed6dc
test(util): add units for check if equal
narekhovhannisyan May 24, 2024
dacd809
test(lib): implement units for compare
narekhovhannisyan May 24, 2024
e10754a
test(lib): fix ts error in env
narekhovhannisyan May 24, 2024
2527051
chore(src): fetch changes from `main`
narekhovhannisyan May 28, 2024
096a460
chore(package): update lock file
narekhovhannisyan May 28, 2024
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
3 changes: 2 additions & 1 deletion package-lock.json

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

14 changes: 14 additions & 0 deletions src/__mocks__/json.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
export const readAndParseJson = async () => {
return {
'mock-carbon': {
description: 'an amount of carbon emitted into the atmosphere',
unit: 'gCO2e',
aggregation: 'sum',
},
'mock-cpu': {
description: 'number of cores available',
unit: 'cores',
aggregation: 'none',
},
};
};
20 changes: 20 additions & 0 deletions src/__mocks__/readline/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
export const createInterface = () => {
if (process.env.readline === 'no_manifest') {
return `
mock message in console
`;
}

if (process.env.readline === 'manifest') {
return (async function* (): any {
yield `
# start
name: mock-name
description: mock-description
# end
`;
})();
}

return [];
};
114 changes: 114 additions & 0 deletions src/__tests__/unit/lib/compare.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
import {compare} from '../../../lib/compare';

describe('lib/compare: ', () => {
describe('compare(): ', () => {
it('test if empty objects are equal.', () => {
const a = {};
const b = {};

const response = compare(a, b);
expect(Object.keys(response).length).toEqual(0);
});

it('tests for nested objects with arrays.', () => {
const a = {
tree: {
inputs: [1, 2],
},
};
const b = {
tree: {
inputs: [1, 2],
},
};

const response = compare(a, b);
expect(Object.keys(response).length).toEqual(0);
});

it('tests for nested objects with arrays (negative case).', () => {
const a = {
tree: {
inputs: [1, 2],
},
};
const b = {
tree: {
inputs: [1],
},
};

const response = compare(a, b);
expect(response.path).toEqual('tree.inputs.1');
expect(response.source).toEqual(2);
expect(response.target).toBeUndefined();
});

it('checks if execution params are ignored.', () => {
const a = {
tree: {
inputs: [1, 2],
},
execution: {
a: 'mock-a',
b: 'mock-b',
status: 'success',
},
};
const b = {
tree: {
inputs: [1, 2],
},
execution: {
status: 'success',
},
};

const response = compare(a, b);
expect(Object.keys(response).length).toEqual(0);
});

it('checks if error and status are in place, and others are ignored.', () => {
const a = {
tree: {
inputs: [1, 2],
},
execution: {
a: 'a',
b: 'b',
error: 'mock-error-message',
status: 'fail',
},
};
const b = {
tree: {
inputs: [1, 2],
},
execution: {
error: 'mock-error-message',
status: 'fail',
},
};

const response = compare(a, b);
expect(Object.keys(response).length).toEqual(0);
});

it('checks if arrays are equal.', () => {
const a = [1, 2];
const b = [1, 2];

const response = compare(a, b);
expect(Object.keys(response).length).toEqual(0);
});

it('checks if arrays are equal (first one is missing some items).', () => {
const a = [1];
const b = [1, 2];

const response = compare(a, b);
const expectedResponse = {path: '1', source: undefined, target: 2};
expect(response).toEqual(expectedResponse);
});
});
});
2 changes: 1 addition & 1 deletion src/__tests__/unit/lib/environment.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ describe('lib/envirnoment: ', () => {
it('checks environment response type.', async () => {
// @ts-ignore
const response = await injectEnvironment(context);
const {environment} = response.execution;
const environment = response.execution!.environment!;

expect(typeof environment['date-time']).toEqual('string');
expect(Array.isArray(environment.dependencies)).toBeTruthy();
Expand Down
170 changes: 82 additions & 88 deletions src/__tests__/unit/lib/load.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
jest.mock('fs/promises', () => require('../../../__mocks__/fs'));
jest.mock('../../../util/json', () => require('../../../__mocks__/json'));
jest.mock(
'mockavizta',
() => ({
Expand All @@ -12,119 +12,66 @@ jest.mock(
}),
{virtual: true}
);
jest.mock('../../../util/helpers', () => ({
parseManifestFromStdin: () => {
if (process.env.readline === 'valid-source') {
return `
name: 'mock-name'
description: 'mock-description'
`;
}
return '';
},
}));
jest.mock('../../../util/yaml', () => ({
openYamlFileAsObject: (path: string) => {
switch (path) {
case 'load-default.yml':
return 'raw-manifest';
case 'source-path.yml':
return 'source-manifest';
case 'target-path.yml':
return 'target-manifest';
default:
return '';
}
},
}));

import {load} from '../../../lib/load';
import {load, loadIfDiffFiles} from '../../../lib/load';

import {PARAMETERS} from '../../../config';

import {PluginParams} from '../../../types/interface';

import {STRINGS} from '../../../config';

const {INVALID_SOURCE} = STRINGS;

describe('lib/load: ', () => {
describe('load(): ', () => {
it('loads yaml with default parameters.', async () => {
const inputPath = 'mock.yaml';
const inputPath = 'load-default.yml';
const paramPath = undefined;

const result = await load(inputPath, paramPath);

const expectedValue = {
rawManifest: {
name: 'gsf-demo',
description: 'Hello',
tags: {
kind: 'web',
complexity: 'moderate',
category: 'cloud',
},
initialize: {
plugins: {
mockavizta: {
path: 'mockavizta',
method: 'Mockavizta',
},
},
},
tree: {
children: {
'front-end': {
pipeline: ['boavizta-cpu'],
config: {
'boavizta-cpu': {
'core-units': 24,
processor: 'Intel® Core™ i7-1185G7',
},
},
inputs: [
{
timestamp: '2023-07-06T00:00',
duration: 3600,
'cpu/utilization': 18.392,
},
{
timestamp: '2023-08-06T00:00',
duration: 3600,
'cpu/utilization': 16,
},
],
},
},
},
},
rawManifest: 'raw-manifest',
parameters: PARAMETERS,
};

expect(result).toEqual(expectedValue);
});

it('loads yaml with custom parameters.', async () => {
const inputPath = 'param-mock.yaml';
const inputPath = 'load-default.yml';
const paramPath = 'param-mock.json';

const result = await load(inputPath, paramPath);

const expectedValue = {
rawManifest: {
name: 'gsf-demo',
description: 'Hello',
tags: {
kind: 'web',
complexity: 'moderate',
category: 'cloud',
},
initialize: {
plugins: {
mockavizta: {
path: 'mockavizta',
method: 'Mockavizta',
},
},
},
tree: {
children: {
'front-end': {
pipeline: ['boavizta-cpu'],
config: {
'boavizta-cpu': {
'core-units': 24,
processor: 'Intel® Core™ i7-1185G7',
},
},
inputs: [
{
timestamp: '2023-07-06T00:00',
duration: 3600,
'cpu/utilization': 18.392,
},
{
timestamp: '2023-08-06T00:00',
duration: 3600,
'cpu/utilization': 16,
},
],
},
},
},
},
rawManifest: 'raw-manifest',
parameters: {
'mock-carbon': {
description: 'an amount of carbon emitted into the atmosphere',
Expand All @@ -142,4 +89,51 @@ describe('lib/load: ', () => {
expect(result).toEqual(expectedValue);
});
});

describe('loadIfDiffFiles(): ', () => {
it('rejects with invalid source error.', async () => {
const params = {
sourcePath: '',
targetPath: '',
};

try {
await loadIfDiffFiles(params);
} catch (error) {
if (error instanceof Error) {
expect(error).toBeInstanceOf(Error);
expect(error.message).toBe(INVALID_SOURCE);
}
}
});

it('successfully loads target, and source from stdin.', async () => {
process.env.readline = 'valid-source';
const params = {
targetPath: 'target-path.yml',
};

const response = await loadIfDiffFiles(params);
const expectedSource = {
name: 'mock-name',
description: 'mock-description',
};
const expectedTarget = 'target-manifest';
expect(response.rawSourceManifest).toEqual(expectedSource);
expect(response.rawTargetManifest).toEqual(expectedTarget);
});

it('successfully loads target, and source from stdin.', async () => {
const params = {
targetPath: 'target-path.yml',
sourcePath: 'source-path.yml',
};

const response = await loadIfDiffFiles(params);
const expectedSource = 'source-manifest';
const expectedTarget = 'target-manifest';
expect(response.rawSourceManifest).toEqual(expectedSource);
expect(response.rawTargetManifest).toEqual(expectedTarget);
});
});
});
Loading