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

Add mapping feature #923

Merged
merged 27 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
80ccf37
feat(package): update if-core version
manushak Jul 26, 2024
e9390c2
feat(types): add `PluginSettings` type
manushak Jul 26, 2024
335c267
feat(util): add `mapping` into manifest schema
manushak Jul 26, 2024
8ac1053
feat(util): add `mapOutput` helper function
manushak Jul 26, 2024
e492532
feat(lib): update init plugin logic to get an option attribute
manushak Jul 26, 2024
322caff
feat(builtins): update plugins to accept mapping parameter
manushak Jul 26, 2024
a7c5c47
docs(builtins): update docs correspondingly
manushak Jul 26, 2024
e0f9d4b
test(util): add test for mapOutput function
manushak Jul 26, 2024
954c5c0
test(lib): add missing `aggregation-method` into tests
manushak Jul 26, 2024
6904da5
test(builtins): update test corespondingly
manushak Jul 26, 2024
a63af71
Merge branch 'main' into mapping-feature
manushak Jul 29, 2024
f5f8b9b
fix(types): remove `PluginSettings` type
manushak Aug 2, 2024
d6d16d7
fix(lib): spread object params to be arguments of the plugin
manushak Aug 2, 2024
4dbd1cd
fix(builtins): fix plugins to get 3 arguments
manushak Aug 2, 2024
9f6f8d2
docs(builtins): update readme files
manushak Aug 2, 2024
83bbe68
test(builtins): update tests according to PRs
manushak Aug 2, 2024
b8bc3c4
Merge branch 'main' into mapping-feature
manushak Aug 5, 2024
fb44137
Merge branch 'main' into mapping-feature
manushak Aug 8, 2024
c102ad7
Merge branch 'main' into mapping-feature
manushak Aug 9, 2024
fa379a5
fix(util): remove `mapOutput` function and add `mapConfigIfNeeded` an…
manushak Aug 12, 2024
b4e62c2
fix(builtins): update plugins to map config or inputs if the mapping …
manushak Aug 12, 2024
fd73d1e
fix(manifests): remove dublicated interpolation manifest
manushak Aug 12, 2024
783e966
docs(builtins): update docs
manushak Aug 12, 2024
e3bf7c6
test(util): add unit tests for `mapConfigIfNeeded` and `mapInputIfNee…
manushak Aug 12, 2024
8dc3c76
test(builtins): update test accorgind to changes
manushak Aug 12, 2024
ee0806c
Merge branch 'main' into mapping-feature
manushak Aug 12, 2024
c064981
Merge branch 'main' into mapping-feature
manushak Aug 19, 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
24 changes: 0 additions & 24 deletions manifests/examples/builtins/interpolation/interpolation.yml

This file was deleted.

103 changes: 101 additions & 2 deletions src/__tests__/common/util/helpers.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ jest.mock('node:readline/promises', () =>
require('../../../__mocks__/readline')
);

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

describe('common/util/helpers: ', () => {
describe('parseManifestFromStdin(): ', () => {
Expand Down Expand Up @@ -37,8 +41,103 @@ describe('common/util/helpers: ', () => {
const response = await parseManifestFromStdin();
const expectedMessage =
'\nname: mock-name\ndescription: mock-description\n';

expect.assertions(1);
expect(response).toEqual(expectedMessage);
});
});

describe('mapInputIfNeeded(): ', () => {
it('returns a new object with no changes when mapping is empty.', () => {
const input = {
timestamp: '2021-01-01T00:00:00Z',
duration: 60 * 60 * 24 * 30,
'device/carbon-footprint': 200,
'device/expected-lifespan': 60 * 60 * 24 * 365 * 4,
'resources-reserved': 1,
'resources-total': 1,
};
const mapping = {};

const result = mapInputIfNeeded(input, mapping);

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

it('returns a new object with keys remapped according to the mapping.', () => {
const input = {
timestamp: '2021-01-01T00:00:00Z',
duration: 60 * 60 * 24 * 30,
'device/carbon-footprint': 200,
'device/expected-lifespan': 60 * 60 * 24 * 365 * 4,
'resources-reserved': 1,
'resources-total': 1,
};
const mapping = {'device/emissions-embodied': 'device/carbon-footprint'};

const expectedOutput = {
timestamp: '2021-01-01T00:00:00Z',
duration: 60 * 60 * 24 * 30,
'device/emissions-embodied': 200,
'device/expected-lifespan': 60 * 60 * 24 * 365 * 4,
'resources-reserved': 1,
'resources-total': 1,
};

const result = mapInputIfNeeded(input, mapping);

expect(result).toEqual(expectedOutput);
expect(result).not.toHaveProperty('device/carbon-footprint');
});
});

describe('mapConfigIfNeeded', () => {
it('returns the config as is if no mapping is provided.', () => {
const config = {
filepath: './file.csv',
query: {
'cpu-cores-available': 'cpu/available',
'cpu-cores-utilized': 'cpu/utilized',
'cpu-manufacturer': 'cpu/manufacturer',
},
output: ['cpu-tdp', 'tdp'],
};

const nullMapping = null;
expect(mapConfigIfNeeded(config, nullMapping!)).toEqual(config);

const undefinedMapping = undefined;
expect(mapConfigIfNeeded(config, undefinedMapping!)).toEqual(config);
});

it('recursively maps config keys and values according to the mapping.', () => {
const config = {
filepath: './file.csv',
query: {
'cpu-cores-available': 'cpu/available',
'cpu-cores-utilized': 'cpu/utilized',
'cpu-manufacturer': 'cpu/manufacturer',
},
output: ['cpu-tdp', 'tdp'],
};
const mapping = {
'cpu/utilized': 'cpu/util',
};

const expected = {
filepath: './file.csv',
query: {
'cpu-cores-available': 'cpu/available',
'cpu-cores-utilized': 'cpu/util',
'cpu-manufacturer': 'cpu/manufacturer',
},
output: ['cpu-tdp', 'tdp'],
};
expect(mapConfigIfNeeded(config, mapping)).toEqual(expected);
});

it('returns an empty object or array when config is an empty object or array.', () => {
expect(mapConfigIfNeeded({}, {})).toEqual({});
expect(mapConfigIfNeeded([], {})).toEqual([]);
});
});
});
40 changes: 35 additions & 5 deletions src/__tests__/if-run/builtins/coefficient.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe('builtins/coefficient: ', () => {
inputs: {},
outputs: {},
};
const coefficient = Coefficient(config, parametersMetadata);
const coefficient = Coefficient(config, parametersMetadata, {});

describe('init: ', () => {
it('successfully initalized.', () => {
Expand Down Expand Up @@ -53,9 +53,39 @@ describe('builtins/coefficient: ', () => {
expect(result).toStrictEqual(expectedResult);
});

it('throws an error when config is not provided.', () => {
it('succcessfully executes when the mapping has data.', () => {
const mapping = {
carbon: 'carbon-for-production',
};

const coefficient = Coefficient(config, parametersMetadata, mapping);
expect.assertions(1);

const expectedResult = [
{
duration: 3600,
'carbon-for-production': 3,
'carbon-product': 9,
timestamp: '2021-01-01T00:00:00Z',
},
];

const result = coefficient.execute([
{
duration: 3600,
'carbon-for-production': 3,
timestamp: '2021-01-01T00:00:00Z',
},
]);

expect.assertions(1);

expect(result).toStrictEqual(expectedResult);
});

it('throws an error when global config is not provided.', () => {
const config = undefined;
const coefficient = Coefficient(config!, parametersMetadata);
const coefficient = Coefficient(config!, parametersMetadata, {});

expect.assertions(1);

Expand All @@ -78,7 +108,7 @@ describe('builtins/coefficient: ', () => {
coefficient: 3,
'output-parameter': 'carbon-product',
};
const coefficient = Coefficient(invalidConfig, parametersMetadata);
const coefficient = Coefficient(invalidConfig, parametersMetadata, {});
const expectedMessage =
'"input-parameter" parameter is string must contain at least 1 character(s). Error code: too_small.';

Expand All @@ -105,7 +135,7 @@ describe('builtins/coefficient: ', () => {
coefficient: 10,
'output-parameter': '',
};
const coefficient = Coefficient(invalidConfig, parametersMetadata);
const coefficient = Coefficient(invalidConfig, parametersMetadata, {});
const expectedMessage =
'"output-parameter" parameter is string must contain at least 1 character(s). Error code: too_small.';

Expand Down
36 changes: 32 additions & 4 deletions src/__tests__/if-run/builtins/copy-param.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ describe('builtins/copy: ', () => {
inputs: {},
outputs: {},
};
const copy = Copy(config, parametersMetadata);
const copy = Copy(config, parametersMetadata, {});

describe('init: ', () => {
it('successfully initalized.', () => {
Expand Down Expand Up @@ -51,9 +51,37 @@ describe('builtins/copy: ', () => {
expect(result).toStrictEqual(expectedResult);
});

it('successfully executed when `mapping` has valid data.', () => {
expect.assertions(1);

const mapping = {
original: 'from',
};

const copy = Copy(config, parametersMetadata, mapping);
const expectedResult = [
{
duration: 3600,
from: 'hello',
copy: 'hello',
timestamp: '2021-01-01T00:00:00Z',
},
];

const result = copy.execute([
{
timestamp: '2021-01-01T00:00:00Z',
duration: 3600,
from: 'hello',
},
]);

expect(result).toStrictEqual(expectedResult);
});

it('throws an error when config is not provided.', () => {
const config = undefined;
const copy = Copy(config!, parametersMetadata);
const copy = Copy(config!, parametersMetadata, {});

expect.assertions(1);

Expand All @@ -76,7 +104,7 @@ describe('builtins/copy: ', () => {
from: 'original',
to: 'copy',
};
const copy = Copy(config, parametersMetadata);
const copy = Copy(config, parametersMetadata, {});
expect.assertions(1);

try {
Expand All @@ -101,8 +129,8 @@ describe('builtins/copy: ', () => {
from: 'original',
to: 'copy',
};
const copy = Copy(config, parametersMetadata);

const copy = Copy(config, parametersMetadata, {});
const expectedResult = [
{
duration: 3600,
Expand Down
Loading