1
0
mirror of https://github.com/kremalicious/metamask-extension.git synced 2024-10-22 11:22:43 +02:00
metamask-extension/development/build/transforms/remove-fenced-code.test.js
Olaf Tomalka 95c37e1ba3
feat: add yaml feature management (#18125)
* feat: add yaml feature management

Add yaml feature file per build type.
Also add method to parse yaml and set
enabled features env to true. The build
process will then replace any process.env[feature]
that exists on the config by its value

* chore: add example for desktop

* Added initial draft of build features

* [TMP] Sync between computers

* Is able to succesfully build stable extension with snaps feature

* Removing var context from builds.yml

* Add asssets to builds.yml

* Minor bug fixes and removing debug logs

* [WIP] Test changes

* Removed TODOs

* Fix regession bug

Also
* remove debug logs
* merge Variables.set and Variables.setMany with an overload

* Fix build, lint and a bunch of issues

* Update LavaMoat policies

* Re-add desktop build type

* Fix some tests

* Fix desktop build

* Define some env variables used by MV3

* Fix lint

* Fix remove-fenced-code tests

* Fix README typo

* Move new code

* Fix missing asset copy

* Move Jest env setup

* Fix path for test after rebase

* Fix code fences

* Fix fencing and LavaMoat policies

* Fix MMI code-fencing after rebase

* Fix MMI code fencing after merge

* Fix more MMI code fencing

---------

Co-authored-by: cryptotavares <joao.tavares@consensys.net>
Co-authored-by: Frederik Bolding <frederik.bolding@gmail.com>
Co-authored-by: Brad Decker <bhdecker84@gmail.com>
2023-04-25 16:32:51 +02:00

1062 lines
28 KiB
JavaScript

const deepFreeze = require('deep-freeze-strict');
const { loadBuildTypesConfig } = require('../../lib/build-type');
const {
createRemoveFencedCodeTransform,
removeFencedCode,
} = require('./remove-fenced-code');
const transformUtils = require('./utils');
jest.mock('./utils', () => ({
lintTransformedFile: jest.fn(),
}));
// The test data is just strings. We get it from a function at the end of this
// file because it takes up a lot of lines and is very distracting.
const testData = getTestData();
const MAIN_BUILD = 'build-main';
const FLASK_BUILD = 'build-flask';
const getMinimalFencedCode = (params = FLASK_BUILD) =>
`///: BEGIN:ONLY_INCLUDE_IN(${params})
Conditionally_Included
///: END:ONLY_INCLUDE_IN
`;
const getFeatures = ({ all, active }) => ({
all: new Set(all),
active: new Set(active),
});
const buildTypesConfig = loadBuildTypesConfig();
describe('build/transforms/remove-fenced-code', () => {
describe('createRemoveFencedCodeTransform', () => {
const { lintTransformedFile: lintTransformedFileMock } = transformUtils;
const mockJsFileName = 'file.js';
beforeEach(() => {
lintTransformedFileMock.mockImplementation(() => Promise.resolve());
});
it('returns a PassThrough stream for files with ignored extensions', async () => {
const fileContent = '"Valid JSON content"\n';
const stream = createRemoveFencedCodeTransform(
getFeatures({
active: [MAIN_BUILD],
all: [MAIN_BUILD],
}),
)('file.json');
let streamOutput = '';
await new Promise((resolve) => {
stream.on('data', (data) => {
streamOutput = streamOutput.concat(data.toString('utf8'));
});
stream.on('end', () => {
expect(streamOutput).toStrictEqual(fileContent);
expect(lintTransformedFileMock).not.toHaveBeenCalled();
resolve();
});
stream.write(Buffer.from(fileContent));
setTimeout(() => stream.end());
});
});
it('transforms a file read as a single chunk', async () => {
const filePrefix = '// A comment\n';
const fileContent = filePrefix.concat(getMinimalFencedCode());
const stream = createRemoveFencedCodeTransform(
getFeatures({
active: [MAIN_BUILD],
all: [MAIN_BUILD, FLASK_BUILD],
}),
)(mockJsFileName);
let streamOutput = '';
await new Promise((resolve) => {
stream.on('data', (data) => {
streamOutput = streamOutput.concat(data.toString('utf8'));
});
stream.on('end', () => {
expect(streamOutput).toStrictEqual(filePrefix);
expect(lintTransformedFileMock).toHaveBeenCalledTimes(1);
expect(lintTransformedFileMock).toHaveBeenCalledWith(
filePrefix,
mockJsFileName,
);
resolve();
});
stream.end(fileContent);
});
});
it('transforms a file read as multiple chunks', async () => {
const filePrefix = '// A comment\n';
const chunks = filePrefix
.concat(getMinimalFencedCode())
.split('\n')
// The final element in the split array is the empty string, which is
// useful for calling .join, but undesirable here.
.filter((line) => line !== '')
.map((line) => `${line}\n`);
const stream = createRemoveFencedCodeTransform(
getFeatures({
active: [MAIN_BUILD],
all: [MAIN_BUILD, FLASK_BUILD],
}),
)(mockJsFileName);
let streamOutput = '';
await new Promise((resolve) => {
stream.on('data', (data) => {
streamOutput = streamOutput.concat(data.toString('utf8'));
});
stream.on('end', () => {
expect(streamOutput).toStrictEqual(filePrefix);
expect(lintTransformedFileMock).toHaveBeenCalledTimes(1);
expect(lintTransformedFileMock).toHaveBeenCalledWith(
filePrefix,
mockJsFileName,
);
resolve();
});
chunks.forEach((chunk) => stream.write(chunk));
setTimeout(() => stream.end());
});
});
it('handles file with fences that is unmodified by the transform', async () => {
const fileContent = getMinimalFencedCode(MAIN_BUILD);
const stream = createRemoveFencedCodeTransform(
getFeatures({
active: [MAIN_BUILD],
all: [MAIN_BUILD],
}),
)(mockJsFileName);
let streamOutput = '';
await new Promise((resolve) => {
stream.on('data', (data) => {
streamOutput = streamOutput.concat(data.toString('utf8'));
});
stream.on('end', () => {
expect(streamOutput).toStrictEqual(fileContent);
expect(lintTransformedFileMock).not.toHaveBeenCalled();
resolve();
});
stream.end(fileContent);
});
});
it('skips linting for transformed file if shouldLintTransformedFiles is false', async () => {
const filePrefix = '// A comment\n';
const fileContent = filePrefix.concat(getMinimalFencedCode());
const stream = createRemoveFencedCodeTransform(
getFeatures({ all: [MAIN_BUILD, FLASK_BUILD], active: [MAIN_BUILD] }),
false,
)(mockJsFileName);
let streamOutput = '';
await new Promise((resolve) => {
stream.on('data', (data) => {
streamOutput = streamOutput.concat(data.toString('utf8'));
});
stream.on('end', () => {
expect(streamOutput).toStrictEqual(filePrefix);
expect(lintTransformedFileMock).not.toHaveBeenCalled();
resolve();
});
stream.end(fileContent);
});
});
it('handles error during code fence removal or parsing', async () => {
const fileContent = getMinimalFencedCode().concat(
'///: END:ONLY_INCLUDE_IN',
);
const stream = createRemoveFencedCodeTransform(
getFeatures({ all: [MAIN_BUILD, FLASK_BUILD], active: [MAIN_BUILD] }),
)(mockJsFileName);
await new Promise((resolve) => {
stream.on('error', (error) => {
expect(error.message).toStrictEqual(
expect.stringContaining(
'A valid fence consists of two fence lines, but the file contains an uneven number, "3", of fence lines.',
),
);
expect(lintTransformedFileMock).toHaveBeenCalledTimes(0);
resolve();
});
stream.end(fileContent);
});
});
it('handles transformed file lint failure', async () => {
lintTransformedFileMock.mockImplementationOnce(() =>
Promise.reject(new Error('lint failure')),
);
const filePrefix = '// A comment\n';
const fileContent = filePrefix.concat(getMinimalFencedCode());
const stream = createRemoveFencedCodeTransform(
getFeatures({ all: [FLASK_BUILD], active: [] }),
)(mockJsFileName);
await new Promise((resolve) => {
stream.on('error', (error) => {
expect(error).toStrictEqual(new Error('lint failure'));
expect(lintTransformedFileMock).toHaveBeenCalledTimes(1);
expect(lintTransformedFileMock).toHaveBeenCalledWith(
filePrefix,
mockJsFileName,
);
resolve();
});
stream.end(fileContent);
});
});
});
describe('removeFencedCode', () => {
const mockFileName = 'file.js';
// Valid inputs
['main', 'flask', 'beta'].forEach((buildType) => {
const active = buildTypesConfig.buildTypes[buildType].features;
const all = Object.keys(buildTypesConfig.features);
const features = getFeatures({ all, active });
it(`transforms file with fences for build type "${buildType}"`, () => {
expect(
removeFencedCode(
mockFileName,
features,
testData.validInputs.withFences,
),
).toStrictEqual(testData.validOutputs[buildType]);
expect(
removeFencedCode(
mockFileName,
features,
testData.validInputs.extraContentWithFences,
),
).toStrictEqual(testData.validOutputsWithExtraContent[buildType]);
// Ensure that the minimal input template is in fact valid
const minimalInput = getMinimalFencedCode(`build-${buildType}`);
expect(
removeFencedCode(mockFileName, features, minimalInput),
).toStrictEqual([minimalInput, false]);
});
it(`does not modify file without fences for build type "${buildType}"`, () => {
expect(
removeFencedCode(
mockFileName,
features,
testData.validInputs.withoutFences,
),
).toStrictEqual([testData.validInputs.withoutFences, false]);
expect(
removeFencedCode(
mockFileName,
features,
testData.validInputs.extraContentWithoutFences,
),
).toStrictEqual([
testData.validInputs.extraContentWithoutFences,
false,
]);
});
});
// This is an edge case for the splicing function
it('transforms file with two fence lines', () => {
expect(
removeFencedCode(
mockFileName,
getFeatures({
active: [FLASK_BUILD],
all: [FLASK_BUILD, MAIN_BUILD],
}),
getMinimalFencedCode(MAIN_BUILD),
),
).toStrictEqual(['', true]);
});
it('ignores sentinels preceded by non-whitespace', () => {
const validBeginDirective = '///: BEGIN:ONLY_INCLUDE_IN(build-flask)\n';
const ignoredLines = [
`a ${validBeginDirective}`,
`2 ${validBeginDirective}`,
`@ ${validBeginDirective}`,
];
ignoredLines.forEach((ignoredLine) => {
// These inputs will be transformed
expect(
removeFencedCode(
mockFileName,
getFeatures({
active: [FLASK_BUILD],
all: [FLASK_BUILD, MAIN_BUILD],
}),
getMinimalFencedCode(MAIN_BUILD).concat(ignoredLine),
),
).toStrictEqual([ignoredLine, true]);
const modifiedInputWithoutFences =
testData.validInputs.withoutFences.concat(ignoredLine);
// These inputs will not be transformed
expect(
removeFencedCode(
mockFileName,
getFeatures({ active: [FLASK_BUILD], all: [FLASK_BUILD] }),
modifiedInputWithoutFences,
),
).toStrictEqual([modifiedInputWithoutFences, false]);
});
});
// Invalid inputs
it('rejects empty fences', () => {
const jsComment = '// A comment\n';
const emptyFence = getMinimalFencedCode()
.split('\n')
.filter((line) => line.startsWith('///:'))
.map((line) => `${line}\n`)
.join('');
const emptyFenceWithPrefix = jsComment.concat(emptyFence);
const emptyFenceWithSuffix = emptyFence.concat(jsComment);
const emptyFenceSurrounded = emptyFenceWithPrefix.concat(jsComment);
const inputs = [
emptyFence,
emptyFenceWithPrefix,
emptyFenceWithSuffix,
emptyFenceSurrounded,
];
inputs.forEach((input) => {
expect(() =>
removeFencedCode(
mockFileName,
getFeatures({ active: [FLASK_BUILD], all: [FLASK_BUILD] }),
input,
),
).toThrow(
`Empty fence found in file "${mockFileName}":\n${emptyFence}`,
);
});
});
it('rejects sentinels not followed by a single space and a multi-character alphabetical string', () => {
// Matches the sentinel and terminus component of the first line
// beginning with "///: TERMINUS"
const fenceSentinelAndTerminusRegex = /^\/\/\/: \w+/mu;
const replacements = [
'///:BEGIN',
'///:XBEGIN',
'///:_BEGIN',
'///:B',
'///:_',
'///: ',
'///: B',
'///:',
];
replacements.forEach((replacement) => {
expect(() =>
removeFencedCode(
mockFileName,
getFeatures({ active: [FLASK_BUILD], all: [FLASK_BUILD] }),
getMinimalFencedCode().replace(
fenceSentinelAndTerminusRegex,
replacement,
),
),
).toThrow(
/Fence sentinel must be followed by a single space and an alphabetical string of two or more characters.$/u,
);
});
});
it('rejects malformed BEGIN directives', () => {
// This is the first line of the minimal input template
const directiveString = '///: BEGIN:ONLY_INCLUDE_IN(build-flask)';
const replacements = [
// Invalid terminus
'///: BE_GIN:BEGIN:ONLY_INCLUDE_IN(build-flask)',
'///: BE6IN:BEGIN:ONLY_INCLUDE_IN(build-flask)',
'///: BEGIN7:BEGIN:ONLY_INCLUDE_IN(build-flask)',
'///: BeGIN:ONLY_INCLUDE_IN(build-flask)',
'///: BE3:BEGIN:ONLY_INCLUDE_IN(build-flask)',
'///: BEG-IN:BEGIN:ONLY_INCLUDE_IN(build-flask)',
'///: BEG N:BEGIN:ONLY_INCLUDE_IN(build-flask)',
// Invalid commands
'///: BEGIN:ONLY-INCLUDE_IN(flask)',
'///: BEGIN:ONLY_INCLUDE:IN(flask)',
'///: BEGIN:ONL6_INCLUDE_IN(flask)',
'///: BEGIN:ONLY_IN@LUDE_IN(flask)',
'///: BEGIN:ONLy_INCLUDE_IN(build-flask)',
'///: BEGIN:ONLY INCLUDE_IN(flask)',
// Invalid parameters
'///: BEGIN:ONLY_INCLUDE_IN(,flask)',
'///: BEGIN:ONLY_INCLUDE_IN(build-flask,)',
'///: BEGIN:ONLY_INCLUDE_IN(build-flask,,main)',
'///: BEGIN:ONLY_INCLUDE_IN(,)',
'///: BEGIN:ONLY_INCLUDE_IN()',
'///: BEGIN:ONLY_INCLUDE_IN( )',
'///: BEGIN:ONLY_INCLUDE_IN(build-flask]',
'///: BEGIN:ONLY_INCLUDE_IN[flask)',
'///: BEGIN:ONLY_INCLUDE_IN(build-flask.main)',
'///: BEGIN:ONLY_INCLUDE_IN(build-flask,@)',
'///: BEGIN:ONLY_INCLUDE_IN(fla k)',
// Stuff after the directive
'///: BEGIN:ONLY_INCLUDE_IN(build-flask) A',
'///: BEGIN:ONLY_INCLUDE_IN(build-flask) 9',
'///: BEGIN:ONLY_INCLUDE_IN(build-flask)A',
'///: BEGIN:ONLY_INCLUDE_IN(build-flask)9',
'///: BEGIN:ONLY_INCLUDE_IN(build-flask)_',
'///: BEGIN:ONLY_INCLUDE_IN(build-flask))',
];
replacements.forEach((replacement) => {
expect(() =>
removeFencedCode(
mockFileName,
getFeatures({ active: [FLASK_BUILD], all: [FLASK_BUILD] }),
getMinimalFencedCode().replace(directiveString, replacement),
),
).toThrow(
new RegExp(
`${replacement.replace(
/([()[\]])/gu,
'\\$1',
)}":\nFailed to parse fence directive.$`,
'u',
),
);
});
});
it('rejects malformed END directives', () => {
// This is the last line of the minimal input template
const directiveString = '///: END:ONLY_INCLUDE_IN';
const replacements = [
// Invalid terminus
'///: ENx:ONLY_INCLUDE_IN',
'///: EN3:ONLY_INCLUDE_IN',
'///: EN_:ONLY_INCLUDE_IN',
'///: EN :ONLY_INCLUDE_IN',
'///: EN::ONLY_INCLUDE_IN',
// Invalid commands
'///: END:ONLY-INCLUDE_IN',
'///: END::ONLY_INCLUDE_IN',
'///: END:ONLY_INCLUDE:IN',
'///: END:ONL6_INCLUDE_IN',
'///: END:ONLY_IN@LUDE_IN',
'///: END:ONLy_INCLUDE_IN',
'///: END:ONLY INCLUDE_IN',
// Stuff after the directive
'///: END:ONLY_INCLUDE_IN A',
'///: END:ONLY_INCLUDE_IN 9',
'///: END:ONLY_INCLUDE_IN _',
];
replacements.forEach((replacement) => {
expect(() =>
removeFencedCode(
mockFileName,
getFeatures({ active: [FLASK_BUILD], all: [FLASK_BUILD] }),
getMinimalFencedCode().replace(directiveString, replacement),
),
).toThrow(
new RegExp(
`${replacement}":\nFailed to parse fence directive.$`,
'u',
),
);
});
});
it('rejects files with uneven number of fence lines', () => {
const additions = [
'///: BEGIN:ONLY_INCLUDE_IN(build-flask)',
'///: END:ONLY_INCLUDE_IN',
];
additions.forEach((addition) => {
expect(() =>
removeFencedCode(
mockFileName,
getFeatures({ active: [FLASK_BUILD], all: [FLASK_BUILD] }),
getMinimalFencedCode().concat(addition),
),
).toThrow(
/A valid fence consists of two fence lines, but the file contains an uneven number, "3", of fence lines.$/u,
);
});
});
it('rejects invalid terminuses', () => {
const testCases = [
['BEGIN', ['KAPLAR', 'FLASK', 'FOO']],
['END', ['KAPLAR', 'FOO', 'BAR']],
];
testCases.forEach(([validTerminus, replacements]) => {
replacements.forEach((replacement) => {
expect(() =>
removeFencedCode(
mockFileName,
getFeatures({ active: [FLASK_BUILD], all: [FLASK_BUILD] }),
getMinimalFencedCode().replace(validTerminus, replacement),
),
).toThrow(
new RegExp(
`Line contains invalid directive terminus "${replacement}".$`,
'u',
),
);
});
});
});
it('rejects invalid commands', () => {
const testCases = [
[/ONLY_INCLUDE_IN\(/mu, ['ONLY_KEEP_IN(', 'FLASK(', 'FOO(']],
[/ONLY_INCLUDE_IN$/mu, ['ONLY_KEEP_IN', 'FLASK', 'FOO']],
];
testCases.forEach(([validCommand, replacements]) => {
replacements.forEach((replacement) => {
expect(() =>
removeFencedCode(
mockFileName,
getFeatures({ active: [FLASK_BUILD], all: [FLASK_BUILD] }),
getMinimalFencedCode().replace(validCommand, replacement),
),
).toThrow(
new RegExp(
`Line contains invalid directive command "${replacement.replace(
'(',
'',
)}".$`,
'u',
),
);
});
});
});
it('rejects invalid command parameters', () => {
const testCases = [
[
'bar',
['bar', 'build-flask,bar', 'build-flask,build-beta,build-main,bar'],
],
[
'Foo',
['Foo', 'build-flask,Foo', 'build-flask,build-beta,build-main,Foo'],
],
[
'b3ta',
[
'b3ta',
'build-flask,b3ta',
'build-flask,build-beta,build-main,b3ta',
],
],
[
'bEta',
[
'bEta',
'build-flask,bEta',
'build-flask,build-beta,build-main,bEta',
],
],
];
testCases.forEach(([invalidParam, replacements]) => {
replacements.forEach((replacement) => {
expect(() =>
removeFencedCode(
mockFileName,
getFeatures({
active: [FLASK_BUILD],
all: [FLASK_BUILD, MAIN_BUILD, 'build-beta'],
}),
getMinimalFencedCode(replacement),
),
).toThrow(
new RegExp(
`"${invalidParam}" is not a declared build feature.$`,
'u',
),
);
});
});
// Should fail for empty params
expect(() =>
removeFencedCode(
mockFileName,
getFeatures({ active: [FLASK_BUILD], all: [FLASK_BUILD] }),
getMinimalFencedCode('').replace('()', ''),
),
).toThrow(/No params specified.$/u);
});
it('rejects directive pairs with wrong terminus order', () => {
// We need more than one directive pair for this test
const input = getMinimalFencedCode().concat(
getMinimalFencedCode('build-beta'),
);
const expectedBeginError =
'The first directive of a pair must be a "BEGIN" directive.';
const expectedEndError =
'The second directive of a pair must be an "END" directive.';
const testCases = [
[
'BEGIN:ONLY_INCLUDE_IN(build-flask)',
'END:ONLY_INCLUDE_IN',
expectedBeginError,
],
[
/END:ONLY_INCLUDE_IN/mu,
'BEGIN:ONLY_INCLUDE_IN(build-main)',
expectedEndError,
],
[
'BEGIN:ONLY_INCLUDE_IN(build-beta)',
'END:ONLY_INCLUDE_IN',
expectedBeginError,
],
];
testCases.forEach(([target, replacement, expectedError]) => {
expect(() =>
removeFencedCode(
mockFileName,
getFeatures({ active: [FLASK_BUILD], all: [FLASK_BUILD] }),
input.replace(target, replacement),
),
).toThrow(expectedError);
});
});
it('ignores files with inline source maps', () => {
// This is so that there isn't an unnecessary second execution of
// removeFencedCode with a transpiled version of the same file
const input = getTestData().validInputs.extraContentWithFences.concat(
'\n//# sourceMappingURL=as32e32wcwc2234f2ew32cnin4243f4nv9nsdoivnxzoivnd',
);
expect(
removeFencedCode(
mockFileName,
getFeatures({ active: [FLASK_BUILD], all: [FLASK_BUILD] }),
input,
),
).toStrictEqual([input, false]);
});
// We can't do this until there's more than one command
it.todo('rejects directive pairs with mismatched commands');
});
});
function getTestData() {
const data = {
validInputs: {
withFences: `
///: BEGIN:ONLY_INCLUDE_IN(build-flask,build-beta,desktop)
Conditionally_Included
///: END:ONLY_INCLUDE_IN
Always_Included
Always_Included
Always_Included
Always_Included
///: BEGIN:ONLY_INCLUDE_IN(build-flask,build-beta,desktop)
Conditionally_Included
Conditionally_Included
Conditionally_Included
///: END:ONLY_INCLUDE_IN
Always_Included
Always_Included
Always_Included
///: BEGIN:ONLY_INCLUDE_IN(build-flask)
Conditionally_Included
Conditionally_Included
///: END:ONLY_INCLUDE_IN
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
///: BEGIN:ONLY_INCLUDE_IN(desktop)
Conditionally_Included
Conditionally_Included
///: END:ONLY_INCLUDE_IN
Always_Included
Always_Included
Always_Included
///: BEGIN:ONLY_INCLUDE_IN(build-flask)
Conditionally_Included
Conditionally_Included
///: END:ONLY_INCLUDE_IN
///: BEGIN:ONLY_INCLUDE_IN(desktop)
Conditionally_Included
Conditionally_Included
///: END:ONLY_INCLUDE_IN
`,
extraContentWithFences: `
///: BEGIN:ONLY_INCLUDE_IN(build-flask,build-beta,desktop)
Conditionally_Included
///: END:ONLY_INCLUDE_IN
Always_Included
Always_Included
Always_Included
Always_Included
///: BEGIN:ONLY_INCLUDE_IN(build-flask,build-beta,desktop)
Conditionally_Included
Conditionally_Included
Conditionally_Included
///: END:ONLY_INCLUDE_IN
Always_Included
Always_Included
Always_Included
///: BEGIN:ONLY_INCLUDE_IN(build-flask)
Conditionally_Included
Conditionally_Included
///: END:ONLY_INCLUDE_IN
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
///: BEGIN:ONLY_INCLUDE_IN(desktop)
Conditionally_Included
Conditionally_Included
///: END:ONLY_INCLUDE_IN
Always_Included
Always_Included
Always_Included
///: BEGIN:ONLY_INCLUDE_IN(build-flask)
Conditionally_Included
Conditionally_Included
///: END:ONLY_INCLUDE_IN
///: BEGIN:ONLY_INCLUDE_IN(desktop)
Conditionally_Included
Conditionally_Included
///: END:ONLY_INCLUDE_IN
Always_Included
Always_Included
Always_Included
`,
withoutFences: `
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
`,
extraContentWithoutFences: `
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
`,
},
validOutputs: {
beta: [
`
///: BEGIN:ONLY_INCLUDE_IN(build-flask,build-beta,desktop)
Conditionally_Included
///: END:ONLY_INCLUDE_IN
Always_Included
Always_Included
Always_Included
Always_Included
///: BEGIN:ONLY_INCLUDE_IN(build-flask,build-beta,desktop)
Conditionally_Included
Conditionally_Included
Conditionally_Included
///: END:ONLY_INCLUDE_IN
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
`,
true,
],
flask: [
`
///: BEGIN:ONLY_INCLUDE_IN(build-flask,build-beta,desktop)
Conditionally_Included
///: END:ONLY_INCLUDE_IN
Always_Included
Always_Included
Always_Included
Always_Included
///: BEGIN:ONLY_INCLUDE_IN(build-flask,build-beta,desktop)
Conditionally_Included
Conditionally_Included
Conditionally_Included
///: END:ONLY_INCLUDE_IN
Always_Included
Always_Included
Always_Included
///: BEGIN:ONLY_INCLUDE_IN(build-flask)
Conditionally_Included
Conditionally_Included
///: END:ONLY_INCLUDE_IN
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
///: BEGIN:ONLY_INCLUDE_IN(desktop)
Conditionally_Included
Conditionally_Included
///: END:ONLY_INCLUDE_IN
Always_Included
Always_Included
Always_Included
///: BEGIN:ONLY_INCLUDE_IN(build-flask)
Conditionally_Included
Conditionally_Included
///: END:ONLY_INCLUDE_IN
///: BEGIN:ONLY_INCLUDE_IN(desktop)
Conditionally_Included
Conditionally_Included
///: END:ONLY_INCLUDE_IN
`,
false,
],
mmi: [
`
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
`,
true,
],
},
validOutputsWithExtraContent: {
beta: [
`
///: BEGIN:ONLY_INCLUDE_IN(build-flask,build-beta,desktop)
Conditionally_Included
///: END:ONLY_INCLUDE_IN
Always_Included
Always_Included
Always_Included
Always_Included
///: BEGIN:ONLY_INCLUDE_IN(build-flask,build-beta,desktop)
Conditionally_Included
Conditionally_Included
Conditionally_Included
///: END:ONLY_INCLUDE_IN
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
`,
true,
],
flask: [
`
///: BEGIN:ONLY_INCLUDE_IN(build-flask,build-beta,desktop)
Conditionally_Included
///: END:ONLY_INCLUDE_IN
Always_Included
Always_Included
Always_Included
Always_Included
///: BEGIN:ONLY_INCLUDE_IN(build-flask,build-beta,desktop)
Conditionally_Included
Conditionally_Included
Conditionally_Included
///: END:ONLY_INCLUDE_IN
Always_Included
Always_Included
Always_Included
///: BEGIN:ONLY_INCLUDE_IN(build-flask)
Conditionally_Included
Conditionally_Included
///: END:ONLY_INCLUDE_IN
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
///: BEGIN:ONLY_INCLUDE_IN(desktop)
Conditionally_Included
Conditionally_Included
///: END:ONLY_INCLUDE_IN
Always_Included
Always_Included
Always_Included
///: BEGIN:ONLY_INCLUDE_IN(build-flask)
Conditionally_Included
Conditionally_Included
///: END:ONLY_INCLUDE_IN
///: BEGIN:ONLY_INCLUDE_IN(desktop)
Conditionally_Included
Conditionally_Included
///: END:ONLY_INCLUDE_IN
Always_Included
Always_Included
Always_Included
`,
false,
],
mmi: [
`
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
Always_Included
`,
true,
],
},
};
data.validOutputs.desktop = [data.validInputs.withFences, false];
data.validOutputs.main = [data.validInputs.withoutFences, true];
data.validOutputsWithExtraContent.desktop = [
data.validInputs.extraContentWithFences,
false,
];
data.validOutputsWithExtraContent.main = [
data.validInputs.extraContentWithoutFences,
true,
];
return deepFreeze(data);
}