Skip to content

Commit

Permalink
Merge branch 'next' into tom/sb-415-return-cleanup-function-from-rend…
Browse files Browse the repository at this point in the history
…ertodom
  • Loading branch information
shilman committed Jun 20, 2022
2 parents f0169ca + e5c2bb6 commit 661011f
Show file tree
Hide file tree
Showing 5 changed files with 127 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,12 @@ export const Demo: CSF2Story = (args) => (
Demo.play = async ({ args, canvasElement }) => {
await userEvent.click(within(canvasElement).getByRole('button'));
await expect(args.onSubmit).toHaveBeenCalledWith(expect.stringMatching(/([A-Z])\w+/gi));
await expect([{ name: 'John', age: 42 }]).toEqual(
expect.arrayContaining([
expect.objectContaining({ name: 'John' }),
expect.objectContaining({ age: 42 }),
])
);
};

export const FindBy: CSF2Story = (args) => {
Expand Down
16 changes: 13 additions & 3 deletions addons/interactions/src/components/MethodCall.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ export const Node = ({
case value === undefined:
return <UndefinedNode {...props} />;
case Array.isArray(value):
return <ArrayNode {...props} value={value} />;
return <ArrayNode {...props} value={value} callsById={callsById} />;
case typeof value === 'string':
return <StringNode {...props} value={value} />;
case typeof value === 'number':
Expand Down Expand Up @@ -191,12 +191,22 @@ export const BooleanNode = ({ value, ...props }: { value: boolean }) => {
);
};

export const ArrayNode = ({ value, nested = false }: { value: any[]; nested?: boolean }) => {
export const ArrayNode = ({
value,
nested = false,
callsById,
}: {
value: any[];
nested?: boolean;
callsById?: Map<Call['id'], Call>;
}) => {
const colors = useThemeColors();
if (nested) {
return <span style={{ color: colors.base }}>[…]</span>;
}
const nodes = value.slice(0, 3).map((v) => <Node key={v} value={v} nested />);
const nodes = value
.slice(0, 3)
.map((v) => <Node key={JSON.stringify(v)} value={v} nested callsById={callsById} />);
const nodelist = interleave(nodes, <span>, </span>);
if (value.length <= 3) {
return <span style={{ color: colors.base }}>[{nodelist}]</span>;
Expand Down
47 changes: 47 additions & 0 deletions lib/cli/src/automigrate/fixes/npm7.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { NPMProxy } from '../../js-package-manager/NPMProxy';
import { npm7 } from './npm7';

const mockExecuteCommand = jest.fn();
class MockedNPMProxy extends NPMProxy {
executeCommand(...args) {
return mockExecuteCommand(...args);
}
}

function mockExecuteResults(map: Record<string, string>) {
mockExecuteCommand.mockImplementation((command, args) => {
const commandString = `${command} ${args.join(' ')}`;
if (map[commandString]) return map[commandString];

throw new Error(`Unexpected execution of '${commandString}'`);
});
}

describe('npm7 fix', () => {
describe('npm < 7', () => {
it('does not match', async () => {
mockExecuteResults({ 'npm --version': '6.0.0' });
expect(await npm7.check({ packageManager: new MockedNPMProxy() })).toEqual(null);
});
});

describe('npm 7+', () => {
it('matches if config is not installed', async () => {
mockExecuteResults({
'npm --version': '7.0.0',
'npm config get legacy-peer-deps --location=project': 'false',
});
expect(await npm7.check({ packageManager: new MockedNPMProxy() })).toEqual({
npmVersion: '7.0.0',
});
});

it('does not match if config is installed', async () => {
mockExecuteResults({
'npm --version': '7.0.0',
'npm config get legacy-peer-deps --location=project': 'true',
});
expect(await npm7.check({ packageManager: new MockedNPMProxy() })).toEqual(null);
});
});
});
41 changes: 41 additions & 0 deletions lib/cli/src/automigrate/fixes/npm7.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import chalk from 'chalk';
import dedent from 'ts-dedent';
import { Fix } from '../types';
import { NPMProxy } from '../../js-package-manager/NPMProxy';

interface Npm7RunOptions {
npmVersion: string;
}

/**
* Is the user using npm7+? If so create a .npmrc with legacy-peer-deps=true
*/
export const npm7: Fix<Npm7RunOptions> = {
id: 'npm7',

async check({ packageManager }) {
if (packageManager.type !== 'npm') return null;

const npmVersion = (packageManager as NPMProxy).getNpmVersion();
if ((packageManager as NPMProxy).needsLegacyPeerDeps(npmVersion)) {
return { npmVersion };
}
return null;
},

prompt({ npmVersion }) {
const npmFormatted = chalk.cyan(`npm ${npmVersion}`);
return dedent`
We've detected you are running ${npmFormatted} which has peer dependency semantics which Storybook is incompatible with.
In order to work with Storybook's package structure, you'll need to run \`npm\` with the
\`--legacy-peer-deps=true\` flag. We can generate an \`.npmrc\` which will do that automatically.
More info: ${chalk.yellow('https://github.com/storybookjs/storybook/issues/18298')}
`;
},

async run({ packageManager }) {
(packageManager as NPMProxy).setLegacyPeerDeps();
},
};
22 changes: 20 additions & 2 deletions lib/cli/src/js-package-manager/NPMProxy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,28 @@ export class NPMProxy extends JsPackageManager {
return `npm run ${command}`;
}

getNpmVersion(): string {
return this.executeCommand('npm', ['--version']);
}

hasLegacyPeerDeps() {
return (
this.executeCommand('npm', ['config', 'get', 'legacy-peer-deps', '--location=project']) ===
'true'
);
}

setLegacyPeerDeps() {
this.executeCommand('npm', ['config', 'set', 'legacy-peer-deps=true', '--location=project']);
}

needsLegacyPeerDeps(version: string) {
return semver.gte(version, '7.0.0') && !this.hasLegacyPeerDeps();
}

getInstallArgs(): string[] {
if (!this.installArgs) {
const version = this.executeCommand('npm', ['--version']);
this.installArgs = semver.gte(version, '7.0.0')
this.installArgs = this.needsLegacyPeerDeps(this.getNpmVersion())
? ['install', '--legacy-peer-deps']
: ['install'];
}
Expand Down

0 comments on commit 661011f

Please sign in to comment.