Skip to content
This repository has been archived by the owner on Dec 16, 2022. It is now read-only.

refactor(index): rewrite answer parsing #541

Merged
merged 20 commits into from
Dec 2, 2021
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
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
40 changes: 33 additions & 7 deletions e2e/installs.test.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
const fs = require('fs');
const { execSync } = require('child_process');
const { getEarliestLibraryVersion } = require('../src/utils');

describe('Installation', () => {
let temporaryDirectory;
let appPath;
let configFilePath;
const appName = 'test-app';

beforeAll(() => {
Expand All @@ -18,21 +20,45 @@ describe('Installation', () => {
execSync(`rm -rf "${temporaryDirectory}"`);
});

beforeEach(() => {
beforeEach(async () => {
appPath = `${temporaryDirectory}/${appName}`;
execSync(`mkdir ${appPath}`);

const templateConfig = require('../src/templates/InstantSearch.js/.template.js');

const config = {
template: 'InstantSearch.js',
// We fetch the earliest supported version in order to not change
// the test output every time we release a new version of a library.
libraryVersion: await getEarliestLibraryVersion({
libraryName: templateConfig.libraryName,
supportedVersion: templateConfig.supportedVersion,
}),
appId: 'appId',
apiKey: 'apiKey',
indexName: 'indexName',
searchPlaceholder: 'Search placeholder',
attributesToDisplay: ['attribute1', 'attribute2'],
attributesForFaceting: ['facet1', 'facet2'],
organization: 'algolia',
};

configFilePath = `${temporaryDirectory}/config.json`;

fs.writeFileSync(configFilePath, JSON.stringify(config));
});

afterEach(() => {
execSync(`rm -rf "${appPath}"`);
execSync(`rm -f "${configFilePath}"`);
});

describe('Dependencies', () => {
test('get skipped with the `no-installation` flag', () => {
execSync(
`yarn start ${appPath} \
--name ${appName} \
--template "InstantSearch.js" \
--config ${configFilePath} \
Haroenv marked this conversation as resolved.
Show resolved Hide resolved
--no-installation`,
{ stdio: 'ignore' }
);
Expand All @@ -46,9 +72,9 @@ describe('Installation', () => {
execSync(
`yarn start ${appPath} \
--name ${appName} \
--template "InstantSearch.js" \
--no-installation`,
{ stdio: 'ignore' }
--config ${configFilePath} \
--no-installation`
// {stdio: 'ignore'}
Haroenv marked this conversation as resolved.
Show resolved Hide resolved
);

expect(fs.existsSync(`${appPath}/package.json`)).toBe(true);
Expand All @@ -61,7 +87,7 @@ describe('Installation', () => {
execSync(
`yarn start ${appPath} \
--name ${appName} \
--template "InstantSearch.js" \
--config ${configFilePath} \
--no-installation`,
{ stdio: 'ignore' }
);
Expand All @@ -81,7 +107,7 @@ describe('Installation', () => {
execSync(
`yarn start ${appPath}/file \
--name ${appName} \
--template "InstantSearch.js" \
--config ${configFilePath} \
--no-installation`,
{ stdio: 'ignore' }
);
Expand Down
18 changes: 17 additions & 1 deletion scripts/build-app.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const path = require('path');
const fs = require('fs');
const { execSync } = require('child_process');

const usage = `
Expand All @@ -20,10 +21,25 @@ if (!templateName) {

const appName = path.basename(appPath);

const config = {
template: templateName,
appId: 'appId',
apiKey: 'apiKey',
indexName: 'indexName',
searchPlaceholder: 'Search placeholder',
attributesToDisplay: ['attribute1', 'attribute2'],
attributesForFaceting: ['facet1', 'facet2'],
organization: 'algolia',
};

const configFilePath = `cisa.config.json`;

fs.writeFileSync(configFilePath, JSON.stringify(config));

execSync(
`yarn start ${appPath} \
--name "${appName}" \
--template "${templateName}"`,
--config "${configFilePath}"`,
{ stdio: 'inherit' }
);

Expand Down
23 changes: 1 addition & 22 deletions src/cli/__tests__/getConfiguration.test.js
Original file line number Diff line number Diff line change
@@ -1,14 +1,8 @@
const loadJsonFile = require('load-json-file');
const utils = require('../../utils');
const { getConfiguration, getLibraryVersion } = require('../getConfiguration');
const getConfiguration = require('../getConfiguration');

jest.mock('load-json-file');

jest.mock('../../utils', () => ({
...require.requireActual('../../utils'),
fetchLibraryVersions: jest.fn(() => Promise.resolve(['1.0.0'])),
}));

test('without template throws', async () => {
expect.assertions(1);

Expand Down Expand Up @@ -36,21 +30,6 @@ test('with options from arguments and prompt merge', async () => {
);
});

test('without stable version available', async () => {
Haroenv marked this conversation as resolved.
Show resolved Hide resolved
utils.fetchLibraryVersions.mockImplementationOnce(() =>
Promise.resolve(['1.0.0-beta.0'])
);

const libraryVersion = await getLibraryVersion(
{
template: 'InstantSearch.js',
},
utils.getAppTemplateConfig(utils.getTemplatePath('InstantSearch.js'))
);

expect(libraryVersion).toBe('1.0.0-beta.0');
});

test('with config file overrides all options', async () => {
loadJsonFile.mockImplementationOnce(x => Promise.resolve(x));
const ignoredOptions = {
Expand Down
72 changes: 0 additions & 72 deletions src/cli/__tests__/getOptionsFromArguments.test.js

This file was deleted.

8 changes: 4 additions & 4 deletions src/cli/__tests__/isQuestionAsked.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ test('with appId undefined should ask', () => {
question: { name: 'appId', validate: input => Boolean(input) },
args: { appId: undefined },
})
).toBe(true);
).toBe(false);
});

test('with appId defined should not ask', () => {
Expand All @@ -15,7 +15,7 @@ test('with appId defined should not ask', () => {
question: { name: 'appId', validate: input => Boolean(input) },
args: { appId: 'APP_ID' },
})
).toBe(false);
).toBe(true);
});

test('with unvalid template should ask', () => {
Expand All @@ -27,7 +27,7 @@ test('with unvalid template should ask', () => {
},
args: { template: 'Unvalid' },
})
).toBe(true);
).toBe(false);
});

test('with valid template should not ask', () => {
Expand All @@ -39,7 +39,7 @@ test('with valid template should not ask', () => {
},
args: { template: 'InstantSearch.js' },
})
).toBe(false);
).toBe(true);
});

test('with indexName should ask attributesToDisplay', () => {
Expand Down
81 changes: 81 additions & 0 deletions src/cli/__tests__/postProcessAnswers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
const postProcessAnswers = require('../postProcessAnswers');
const utils = require('../../utils');

jest.mock('../../utils', () => ({
...require.requireActual('../../utils'),
fetchLibraryVersions: jest.fn(() => Promise.resolve(['1.0.0'])),
}));

test('merges configuration and answers', async () => {
expect(
await postProcessAnswers({
configuration: { attributesForFaceting: ['test'], b: 1 },
answers: { attributesForFaceting: [] },
templateConfig: {},
optionsFromArguments: {},
})
).toEqual(expect.objectContaining({ attributesForFaceting: [], b: 1 }));
});

describe('libraryVersion', () => {
test('library version from answers is used', async () => {
const { libraryVersion } = await postProcessAnswers({
configuration: {},
answers: {
template: 'InstantSearch.js',
attributesForFaceting: [],
libraryVersion: '0.1.2',
},
optionsFromArguments: {},
templateConfig: utils.getAppTemplateConfig(
utils.getTemplatePath('InstantSearch.js')
),
});

expect(libraryVersion).toBe('0.1.2');
});

test('library version falls back to beta if it is the only available', async () => {
utils.fetchLibraryVersions.mockImplementationOnce(() =>
Promise.resolve(['1.0.0-beta.0'])
);

const { libraryVersion } = await postProcessAnswers({
configuration: {},
answers: {
template: 'InstantSearch.js',
attributesForFaceting: [],
},
optionsFromArguments: {},
templateConfig: utils.getAppTemplateConfig(
utils.getTemplatePath('InstantSearch.js')
),
});

expect(libraryVersion).toBe('1.0.0-beta.0');
});
});

test('creates alternative names', async () => {
expect(
await postProcessAnswers({
configuration: {},
answers: {
attributesForFaceting: [],
organization: 'algolia',
name: 'date-range',
},
templateConfig: {
packageNamePrefix: 'instantsearch-widget-',
},
optionsFromArguments: {},
})
).toEqual(
expect.objectContaining({
packageName: '@algolia/instantsearch-widget-date-range',
widgetType: 'algolia.date-range',
camelCaseName: 'dateRange',
pascalCaseName: 'DateRange',
})
);
});
8 changes: 3 additions & 5 deletions src/cli/getAnswersDefaultValues.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,10 @@ module.exports = function getAnswersDefaultValues(
template
) {
return {
...configuration,
...optionsFromArguments,
template,
attributesToDisplay:
configuration.attributesToDisplay &&
configuration.attributesToDisplay.length > 0
? configuration.attributesToDisplay
: undefined,
// name has a default of '', as it's a special case in Commander
name: optionsFromArguments.name || configuration.name,
};
};
Loading