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

Build if-csv #891

Merged
merged 20 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
61201ce
feat(src): add util functions for if-csv
manushak Jul 8, 2024
04a5763
feat(src): add executeCsv helper function for if-csv
manushak Jul 8, 2024
142d957
feat(src): move `parseManifestFromStdin` function from if-diff helper…
manushak Jul 8, 2024
db51036
test(src): update tests according to changes
manushak Jul 8, 2024
981e925
feat(src): add string and types files for if-csv
manushak Jul 8, 2024
b96e466
feat(src): add config and types for args for if-csv
manushak Jul 8, 2024
8d199be
test(src): add test for helpers
manushak Jul 8, 2024
a24f1b4
feat(src): add logic for if-csv
manushak Jul 8, 2024
2cac2e3
feat(package): add if-csv script
manushak Jul 8, 2024
01ace66
fix(config): add failure string for if-csv
manushak Jul 10, 2024
ebf1770
fix(util): add getManifestData function
manushak Jul 10, 2024
083340d
fix(src): update logix to accpet executed manifest
manushak Jul 10, 2024
bcc872f
test(util): add tests for getManifestData function
manushak Jul 10, 2024
752c014
fix(package): add `if-csv` into package-loc.json
manushak Jul 10, 2024
96f086c
fix(util): improve getManifestData function
manushak Jul 10, 2024
9d8d1fd
fix(util): improve getManifestData function
manushak Jul 10, 2024
3474745
chore(src): fetch changes from main
narekhovhannisyan Jul 10, 2024
179238c
test(util): fix tests conflict after merging with the main
manushak Jul 10, 2024
e609d0c
fix(src): improve manifestData check
manushak Jul 16, 2024
669a422
fix(src): rename the `executeCsv` function into `generateCsv`
manushak Jul 16, 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
1 change: 1 addition & 0 deletions package-lock.json

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

4 changes: 3 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,8 @@
"if-diff": "./build/if-diff/index.js",
"if-run": "./build/if-run/index.js",
"if-env": "./build/if-env/index.js",
"if-check": "./build/if-check/index.js"
"if-check": "./build/if-check/index.js",
"if-csv": "./build/if-csv/index.js"
},
"bugs": {
"url": "https://github.com/Green-Software-Foundation/if/issues/new?assignees=&labels=feedback&projects=&template=feedback.md&title=Feedback+-+"
Expand Down Expand Up @@ -76,6 +77,7 @@
"fix": "gts fix",
"fix:package": "fixpack",
"if-check": "cross-env CURRENT_DIR=$(node -p \"process.env.INIT_CWD\") npx ts-node src/if-check/index.ts",
"if-csv": "cross-env CURRENT_DIR=$(node -p \"process.env.INIT_CWD\") npx ts-node src/if-csv/index.ts",
"if-diff": "npx ts-node src/if-diff/index.ts",
"if-env": "cross-env CURRENT_DIR=$(node -p \"process.env.INIT_CWD\") npx ts-node src/if-env/index.ts",
"if-run": "npx ts-node src/if-run/index.ts",
Expand Down
2 changes: 1 addition & 1 deletion src/__tests__/common/lib/load.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jest.mock(
}),
{virtual: true}
);
jest.mock('../../../if-diff/util/helpers', () => ({
jest.mock('../../../common/util/helpers', () => ({
parseManifestFromStdin: () => {
if (process.env.readline === 'valid-source') {
return `
Expand Down
44 changes: 44 additions & 0 deletions src/__tests__/common/util/helpers.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
jest.mock('node:readline/promises', () =>
require('../../../__mocks__/readline')
);

import {parseManifestFromStdin} from '../../../common/util/helpers';

describe('common/util/helpers: ', () => {
describe('parseManifestFromStdin(): ', () => {
it('returns empty string if there is no data in stdin.', async () => {
const response = await parseManifestFromStdin();
const expectedResult = '';

expect(response).toEqual(expectedResult);
});

it('returns empty string if nothing is piped.', async () => {
const originalIsTTY = process.stdin.isTTY;
process.stdin.isTTY = true;
const response = await parseManifestFromStdin();
const expectedResult = '';

expect(response).toEqual(expectedResult);
process.stdin.isTTY = originalIsTTY;
});

it('throws error if there is no manifest in stdin.', async () => {
process.env.readline = 'no_manifest';
expect.assertions(1);

const response = await parseManifestFromStdin();

expect(response).toEqual('');
});

it('returns empty string if there is no data in stdin.', async () => {
process.env.readline = 'manifest';
const response = await parseManifestFromStdin();
const expectedMessage =
'\nname: mock-name\ndescription: mock-description\n';

expect(response).toEqual(expectedMessage);
});
});
});
264 changes: 264 additions & 0 deletions src/__tests__/if-csv/util/helpers.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
import {jest} from '@jest/globals';
import * as fs from 'fs/promises';
import {stringify} from 'csv-stringify/sync';
import {ERRORS} from '@grnsft/if-core/utils';

import {generateCsv, getManifestData} from '../../../if-csv/util/helpers';
import {CsvOptions} from '../../../if-csv/types/csv';

const {ManifestValidationError} = ERRORS;

import {
tree,
context,
aggregated,
aggregation,
} from '../../../__mocks__/builtins/export-yaml';

jest.mock('fs/promises', () => {
const originalModule =
jest.requireActual<typeof import('fs/promises')>('fs/promises');
return {
__esModule: true,
...originalModule,
writeFile: jest.fn(() => Promise.resolve()),
};
});

describe('if-csv/util/helpers: ', () => {
describe('generateCsv(): ', () => {
it('generates CSV file with correct data.', async () => {
const outputPath = 'output';
const columns = ['Path', 'Aggregated', '2023-12-12T00:00:00.000Z'];
const matrix = [
columns,
['tree.carbon', 8000.000004051243, 8000.000004051243],
[
'tree.children.child-1.carbon',
4000.0000020256216,
4000.0000020256216,
],
[
'tree.children.child-2.carbon',
4000.0000020256216,
4000.0000020256216,
],
];
const reformedTree = Object.assign({}, tree, {
children: {
...tree.children,
'child-1': {
...tree.children['child-1'],
aggregated,
},
'child-2': {
...tree.children['child-2'],
aggregated,
},
},
});

const options: CsvOptions = {
tree: reformedTree,
context,
outputPath,
params: 'carbon',
};

await generateCsv(options);

expect(fs.writeFile).toHaveBeenCalledWith(
'output.csv',
stringify(matrix, {columns})
);
});

it('generates CSV file when the `outputs` type is missing.', async () => {
const outputPath = 'output';
const columns = ['Path', 'Aggregated', '2023-12-12T00:00:00.000Z'];
const matrix = [
columns,
['tree.carbon', 8000.000004051243, 8000.000004051243],
[
'tree.children.child-1.carbon',
4000.0000020256216,
4000.0000020256216,
],
[
'tree.children.child-2.carbon',
4000.0000020256216,
4000.0000020256216,
],
];

const reformedTree = Object.assign({}, tree, {
children: {
...tree.children,
'child-1': {
...tree.children['child-1'],
aggregated,
},
'child-2': {
...tree.children['child-2'],
aggregated,
},
},
});

const options: CsvOptions = {
tree: reformedTree,
context,
outputPath,
params: 'carbon',
};

await generateCsv(options);

expect.assertions(1);

expect(fs.writeFile).toHaveBeenCalledWith(
'output.csv',
stringify(matrix, {columns})
);
});

it('generates CSV file when `aggregation` persists.', async () => {
const outputPath = 'output';
const columns = ['Path', 'Aggregated', '2023-12-12T00:00:00.000Z'];
const matrix = [
columns,
['tree.carbon', 8000.000004051243, 8000.000004051243],
[
'tree.children.child-1.carbon',
4000.0000020256216,
4000.0000020256216,
],
[
'tree.children.child-2.carbon',
4000.0000020256216,
4000.0000020256216,
],
];

const reformedContext = Object.assign({}, context, {aggregation});
const reformedTree = Object.assign({}, tree, {
children: {
...tree.children,
'child-1': {
...tree.children['child-1'],
aggregated,
},
'child-2': {
...tree.children['child-2'],
aggregated,
},
},
});

const options: CsvOptions = {
tree: reformedTree,
context: reformedContext,
outputPath,
params: 'carbon',
};

await generateCsv(options);

expect.assertions(1);
expect(fs.writeFile).toHaveBeenCalledWith(
'output.csv',
stringify(matrix, {columns})
);
});

it('returns string when `outputPath` is not provided', async () => {
const columns = ['Path', 'Aggregated', '2023-12-12T00:00:00.000Z'];
const matrix = [
columns,
['tree.carbon', 8000.000004051243, 8000.000004051243],
[
'tree.children.child-1.carbon',
4000.0000020256216,
4000.0000020256216,
],
];

const options: CsvOptions = {
tree,
context,
outputPath: undefined,
params: 'carbon',
};

const result = await generateCsv(options);

expect.assertions(1);
expect(result).toEqual(stringify(matrix, {columns}));
});

it('generates CSV file when `aggregation` is missing.', async () => {
const outputPath = 'output';
const columns = ['Path', 'Aggregated', '2023-12-12T00:00:00.000Z'];
const matrix = [
columns,
['tree.carbon', 8000.000004051243, 8000.000004051243],
[
'tree.children.child-1.carbon',
4000.0000020256216,
4000.0000020256216,
],
[
'tree.children.child-2.carbon',
4000.0000020256216,
4000.0000020256216,
],
];

const options: CsvOptions = {
tree,
context,
outputPath,
params: 'carbon',
};

await generateCsv(options);

expect.assertions(1);
expect(fs.writeFile).toHaveBeenCalledWith(
'output.csv',
stringify(matrix, {columns})
);
});
});

describe('getManifestData(): ', () => {
it('returns correct manifest data.', async () => {
process.env.MOCK_MANIFEST = 'true';
const mockManifestPath = './src/__mocks__/mock-manifest.yaml';
const result = await getManifestData(mockManifestPath);

expect.assertions(2);
expect(result).toHaveProperty('description');
expect(result).toHaveProperty('tree');
});

it('throws an error when there is not `outputs` in the manifest.', async () => {
process.env.MOCK_MANIFEST = 'false';
const mockManifestPath = '';
const load = require('../../../common/lib/load');
const spyLoad = jest.spyOn(load, 'load');

spyLoad.mockReturnValue({
rawManifest: {tree: {children: {child: {}}}},
});
expect.assertions(1);
try {
await getManifestData(mockManifestPath);
} catch (error) {
expect(error).toEqual(
new ManifestValidationError('Manifest outputs are not available!')
);
}
});
});
});
4 changes: 2 additions & 2 deletions src/__tests__/if-diff/lib/load.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ jest.mock(
}),
{virtual: true}
);
jest.mock('../../../if-diff/util/helpers', () => ({
jest.mock('../../../common/util/helpers', () => ({
parseManifestFromStdin: () => {
if (process.env.readline === 'valid-source') {
return `
Expand Down Expand Up @@ -44,7 +44,7 @@ import {PluginParams} from '@grnsft/if-core/types';

import {loadIfDiffFiles} from '../../../if-diff/lib/load';

import {parseManifestFromStdin} from '../../../if-diff/util/helpers';
import {parseManifestFromStdin} from '../../../common/util/helpers';

import {STRINGS} from '../../../if-diff/config';

Expand Down
Loading