mirror of
https://github.com/kremalicious/metamask-extension.git
synced 2024-12-03 14:44:27 +01:00
2e8752183f
The code fence transform was including contents after the final END directive twice. That was not covered by the tests, because none of the examples contained any content after the final END directive, and concatenating the empty string twice does not produce an observable difference in the test results. This bug was due to an off-by-one error in the loop of the multiSplice function. The error has been fixed, and more test cases have been added.
779 lines
21 KiB
JavaScript
779 lines
21 KiB
JavaScript
const deepFreeze = require('deep-freeze-strict');
|
|
const { BuildType } = require('../utils');
|
|
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 getMinimalFencedCode = (params = 'flask') =>
|
|
`///: BEGIN:ONLY_INCLUDE_IN(${params})
|
|
Conditionally_Included
|
|
///: END:ONLY_INCLUDE_IN
|
|
`;
|
|
|
|
describe('build/transforms/remove-fenced-code', () => {
|
|
describe('createRemoveFencedCodeTransform', () => {
|
|
const { lintTransformedFile: lintTransformedFileMock } = transformUtils;
|
|
const mockJsFileName = 'file.js';
|
|
|
|
beforeEach(() => {
|
|
lintTransformedFileMock.mockImplementation(() => Promise.resolve());
|
|
});
|
|
|
|
it('rejects invalid build types', () => {
|
|
expect(() => createRemoveFencedCodeTransform('foobar')).toThrow(
|
|
/received unrecognized build type "foobar".$/u,
|
|
);
|
|
});
|
|
|
|
it('returns a PassThrough stream for files with ignored extensions', async () => {
|
|
const fileContent = '"Valid JSON content"\n';
|
|
const stream = createRemoveFencedCodeTransform('main')('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('main')(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('main')(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');
|
|
|
|
const stream = createRemoveFencedCodeTransform('main')(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(
|
|
'main',
|
|
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 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('main')(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
|
|
Object.keys(BuildType).forEach((buildType) => {
|
|
it(`transforms file with fences for build type "${buildType}"`, () => {
|
|
expect(
|
|
removeFencedCode(
|
|
mockFileName,
|
|
buildType,
|
|
testData.validInputs.withFences,
|
|
),
|
|
).toStrictEqual(testData.validOutputs[buildType]);
|
|
|
|
expect(
|
|
removeFencedCode(
|
|
mockFileName,
|
|
buildType,
|
|
testData.validInputs.extraContentWithFences,
|
|
),
|
|
).toStrictEqual(testData.validOutputsWithExtraContent[buildType]);
|
|
|
|
// Ensure that the minimal input template is in fact valid
|
|
const minimalInput = getMinimalFencedCode(buildType);
|
|
expect(
|
|
removeFencedCode(mockFileName, buildType, minimalInput),
|
|
).toStrictEqual([minimalInput, false]);
|
|
});
|
|
|
|
it(`does not modify file without fences for build type "${buildType}"`, () => {
|
|
expect(
|
|
removeFencedCode(
|
|
mockFileName,
|
|
buildType,
|
|
testData.validInputs.withoutFences,
|
|
),
|
|
).toStrictEqual([testData.validInputs.withoutFences, false]);
|
|
|
|
expect(
|
|
removeFencedCode(
|
|
mockFileName,
|
|
buildType,
|
|
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,
|
|
BuildType.flask,
|
|
getMinimalFencedCode('main'),
|
|
),
|
|
).toStrictEqual(['', true]);
|
|
});
|
|
|
|
it('ignores sentinels preceded by non-whitespace', () => {
|
|
const validBeginDirective = '///: BEGIN:ONLY_INCLUDE_IN(flask)\n';
|
|
const ignoredLines = [
|
|
`a ${validBeginDirective}`,
|
|
`2 ${validBeginDirective}`,
|
|
`@ ${validBeginDirective}`,
|
|
];
|
|
|
|
ignoredLines.forEach((ignoredLine) => {
|
|
// These inputs will be transformed
|
|
expect(
|
|
removeFencedCode(
|
|
mockFileName,
|
|
BuildType.flask,
|
|
getMinimalFencedCode('main').concat(ignoredLine),
|
|
),
|
|
).toStrictEqual([ignoredLine, true]);
|
|
|
|
const modifiedInputWithoutFences = testData.validInputs.withoutFences.concat(
|
|
ignoredLine,
|
|
);
|
|
|
|
// These inputs will not be transformed
|
|
expect(
|
|
removeFencedCode(
|
|
mockFileName,
|
|
BuildType.flask,
|
|
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, BuildType.flask, 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,
|
|
BuildType.flask,
|
|
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(flask)';
|
|
|
|
const replacements = [
|
|
// Invalid terminus
|
|
'///: BE_GIN:ONLY_INCLUDE_IN(flask)',
|
|
'///: BE6IN:ONLY_INCLUDE_IN(flask)',
|
|
'///: BEGIN7:ONLY_INCLUDE_IN(flask)',
|
|
'///: BeGIN:ONLY_INCLUDE_IN(flask)',
|
|
'///: BE3:ONLY_INCLUDE_IN(flask)',
|
|
'///: BEG-IN:ONLY_INCLUDE_IN(flask)',
|
|
'///: BEG N:ONLY_INCLUDE_IN(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(flask)',
|
|
'///: BEGIN:ONLY INCLUDE_IN(flask)',
|
|
|
|
// Invalid parameters
|
|
'///: BEGIN:ONLY_INCLUDE_IN(,flask)',
|
|
'///: BEGIN:ONLY_INCLUDE_IN(flask,)',
|
|
'///: BEGIN:ONLY_INCLUDE_IN(flask,,main)',
|
|
'///: BEGIN:ONLY_INCLUDE_IN(,)',
|
|
'///: BEGIN:ONLY_INCLUDE_IN()',
|
|
'///: BEGIN:ONLY_INCLUDE_IN( )',
|
|
'///: BEGIN:ONLY_INCLUDE_IN(flask]',
|
|
'///: BEGIN:ONLY_INCLUDE_IN[flask)',
|
|
'///: BEGIN:ONLY_INCLUDE_IN(flask.main)',
|
|
'///: BEGIN:ONLY_INCLUDE_IN(flask,@)',
|
|
'///: BEGIN:ONLY_INCLUDE_IN(fla k)',
|
|
|
|
// Stuff after the directive
|
|
'///: BEGIN:ONLY_INCLUDE_IN(flask) A',
|
|
'///: BEGIN:ONLY_INCLUDE_IN(flask) 9',
|
|
'///: BEGIN:ONLY_INCLUDE_IN(flask)A',
|
|
'///: BEGIN:ONLY_INCLUDE_IN(flask)9',
|
|
'///: BEGIN:ONLY_INCLUDE_IN(flask)_',
|
|
'///: BEGIN:ONLY_INCLUDE_IN(flask))',
|
|
];
|
|
|
|
replacements.forEach((replacement) => {
|
|
expect(() =>
|
|
removeFencedCode(
|
|
mockFileName,
|
|
BuildType.flask,
|
|
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,
|
|
BuildType.flask,
|
|
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(flask)',
|
|
'///: END:ONLY_INCLUDE_IN',
|
|
];
|
|
additions.forEach((addition) => {
|
|
expect(() =>
|
|
removeFencedCode(
|
|
mockFileName,
|
|
BuildType.flask,
|
|
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,
|
|
BuildType.flask,
|
|
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,
|
|
BuildType.flask,
|
|
getMinimalFencedCode().replace(validCommand, replacement),
|
|
),
|
|
).toThrow(
|
|
new RegExp(
|
|
`Line contains invalid directive command "${replacement.replace(
|
|
'(',
|
|
'',
|
|
)}".$`,
|
|
'u',
|
|
),
|
|
);
|
|
});
|
|
});
|
|
});
|
|
|
|
it('rejects invalid command parameters', () => {
|
|
const testCases = [
|
|
['bar', ['bar', 'flask,bar', 'flask,beta,main,bar']],
|
|
['Foo', ['Foo', 'flask,Foo', 'flask,beta,main,Foo']],
|
|
['b3ta', ['b3ta', 'flask,b3ta', 'flask,beta,main,b3ta']],
|
|
['bEta', ['bEta', 'flask,bEta', 'flask,beta,main,bEta']],
|
|
];
|
|
|
|
testCases.forEach(([invalidParam, replacements]) => {
|
|
replacements.forEach((replacement) => {
|
|
expect(() =>
|
|
removeFencedCode(
|
|
mockFileName,
|
|
BuildType.flask,
|
|
getMinimalFencedCode(replacement),
|
|
),
|
|
).toThrow(
|
|
new RegExp(`"${invalidParam}" is not a valid build type.$`, 'u'),
|
|
);
|
|
});
|
|
});
|
|
|
|
// Should fail for empty params
|
|
expect(() =>
|
|
removeFencedCode(
|
|
mockFileName,
|
|
BuildType.flask,
|
|
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('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(flask)',
|
|
'END:ONLY_INCLUDE_IN',
|
|
expectedBeginError,
|
|
],
|
|
[
|
|
/END:ONLY_INCLUDE_IN/mu,
|
|
'BEGIN:ONLY_INCLUDE_IN(main)',
|
|
expectedEndError,
|
|
],
|
|
[
|
|
'BEGIN:ONLY_INCLUDE_IN(beta)',
|
|
'END:ONLY_INCLUDE_IN',
|
|
expectedBeginError,
|
|
],
|
|
];
|
|
|
|
testCases.forEach(([target, replacement, expectedError]) => {
|
|
expect(() =>
|
|
removeFencedCode(
|
|
mockFileName,
|
|
BuildType.flask,
|
|
input.replace(target, replacement),
|
|
),
|
|
).toThrow(expectedError);
|
|
});
|
|
});
|
|
|
|
// 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(flask,beta)
|
|
Conditionally_Included
|
|
///: END:ONLY_INCLUDE_IN
|
|
Always_Included
|
|
Always_Included
|
|
Always_Included
|
|
Always_Included
|
|
///: BEGIN:ONLY_INCLUDE_IN(flask,beta)
|
|
Conditionally_Included
|
|
|
|
Conditionally_Included
|
|
Conditionally_Included
|
|
///: END:ONLY_INCLUDE_IN
|
|
Always_Included
|
|
|
|
Always_Included
|
|
Always_Included
|
|
///: BEGIN:ONLY_INCLUDE_IN(flask)
|
|
|
|
Conditionally_Included
|
|
Conditionally_Included
|
|
///: END:ONLY_INCLUDE_IN
|
|
Always_Included
|
|
Always_Included
|
|
Always_Included
|
|
|
|
///: BEGIN:ONLY_INCLUDE_IN(flask)
|
|
Conditionally_Included
|
|
Conditionally_Included
|
|
|
|
///: END:ONLY_INCLUDE_IN
|
|
`,
|
|
|
|
extraContentWithFences: `
|
|
///: BEGIN:ONLY_INCLUDE_IN(flask,beta)
|
|
Conditionally_Included
|
|
///: END:ONLY_INCLUDE_IN
|
|
Always_Included
|
|
Always_Included
|
|
Always_Included
|
|
Always_Included
|
|
///: BEGIN:ONLY_INCLUDE_IN(flask,beta)
|
|
Conditionally_Included
|
|
|
|
Conditionally_Included
|
|
Conditionally_Included
|
|
///: END:ONLY_INCLUDE_IN
|
|
Always_Included
|
|
|
|
Always_Included
|
|
Always_Included
|
|
///: BEGIN:ONLY_INCLUDE_IN(flask)
|
|
|
|
Conditionally_Included
|
|
Conditionally_Included
|
|
///: END:ONLY_INCLUDE_IN
|
|
Always_Included
|
|
Always_Included
|
|
Always_Included
|
|
|
|
///: BEGIN:ONLY_INCLUDE_IN(flask)
|
|
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
|
|
|
|
`,
|
|
|
|
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
|
|
`,
|
|
},
|
|
|
|
validOutputs: {
|
|
beta: [
|
|
`
|
|
///: BEGIN:ONLY_INCLUDE_IN(flask,beta)
|
|
Conditionally_Included
|
|
///: END:ONLY_INCLUDE_IN
|
|
Always_Included
|
|
Always_Included
|
|
Always_Included
|
|
Always_Included
|
|
///: BEGIN:ONLY_INCLUDE_IN(flask,beta)
|
|
Conditionally_Included
|
|
|
|
Conditionally_Included
|
|
Conditionally_Included
|
|
///: END:ONLY_INCLUDE_IN
|
|
Always_Included
|
|
|
|
Always_Included
|
|
Always_Included
|
|
Always_Included
|
|
Always_Included
|
|
Always_Included
|
|
|
|
`,
|
|
true,
|
|
],
|
|
},
|
|
|
|
validOutputsWithExtraContent: {
|
|
beta: [
|
|
`
|
|
///: BEGIN:ONLY_INCLUDE_IN(flask,beta)
|
|
Conditionally_Included
|
|
///: END:ONLY_INCLUDE_IN
|
|
Always_Included
|
|
Always_Included
|
|
Always_Included
|
|
Always_Included
|
|
///: BEGIN:ONLY_INCLUDE_IN(flask,beta)
|
|
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
|
|
`,
|
|
true,
|
|
],
|
|
},
|
|
};
|
|
|
|
data.validOutputs.flask = [data.validInputs.withFences, false];
|
|
data.validOutputs.main = [data.validInputs.withoutFences, true];
|
|
|
|
data.validOutputsWithExtraContent.flask = [
|
|
data.validInputs.extraContentWithFences,
|
|
false,
|
|
];
|
|
data.validOutputsWithExtraContent.main = [
|
|
data.validInputs.extraContentWithoutFences,
|
|
true,
|
|
];
|
|
return deepFreeze(data);
|
|
}
|