Skip to content

Commit

Permalink
[Theme/Warning] Allow optional callback argument to setEuiDevProvider…
Browse files Browse the repository at this point in the history
…Warning
  • Loading branch information
tsullivan committed Jun 7, 2024
1 parent 1cabbd2 commit 211b1f7
Show file tree
Hide file tree
Showing 4 changed files with 97 additions and 27 deletions.
2 changes: 2 additions & 0 deletions packages/eui/changelogs/CHANGELOG_2024.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
## [`v94.6.0`](https://github.com/elastic/eui/releases/v94.6.0)

- Updated `setEuiDevProviderWarning` to support an optional callback function as the 2nd argument.

- Updated `EuiComboBox` to support rendering `option.append` and `option.prepend` in group labels ([#7800](https://github.com/elastic/eui/pull/7800))

**Accessibility**
Expand Down
19 changes: 19 additions & 0 deletions packages/eui/src-docs/src/views/provider/provider_example.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,25 @@ export const ProviderExample = {
exception
</li>
</ul>

<p>
Developers can provide an optional callback function which will
receive the log message or Error object.
</p>
<ul>
<li>
<EuiCode>setEuiDevProviderWarning('log', callbackFn)</EuiCode>:
callbackFn will be called with a <EuiCode>string</EuiCode>
</li>
<li>
<EuiCode>setEuiDevProviderWarning('warn', callbackFn)</EuiCode>:
callbackFn will be called with a <EuiCode>string</EuiCode>
</li>
<li>
<EuiCode>setEuiDevProviderWarning('error', callbackFn)</EuiCode>:
callbackFn will be called with an <EuiCode>Error</EuiCode> object
</li>
</ul>
</EuiText>
),
},
Expand Down
86 changes: 62 additions & 24 deletions packages/eui/src/services/theme/warning.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,42 +43,80 @@ describe('EUI provider dev warnings', () => {
consoleWarnSpy.mockRestore();
});

const providerMessage = 'hello world';
describe('emits log or throws', () => {
const providerMessage = 'hello world';

it('does nothing if the warning level is undefined', () => {
emitEuiProviderWarning(providerMessage);
it('does nothing if the warning level is undefined', () => {
emitEuiProviderWarning(providerMessage);

expect(consoleLogSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).not.toHaveBeenCalled();
});
expect(consoleLogSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).not.toHaveBeenCalled();
});

it('emits a console log when level is log', () => {
setEuiDevProviderWarning('log');
it('emits a console log when level is log', () => {
setEuiDevProviderWarning('log');

emitEuiProviderWarning(providerMessage);
emitEuiProviderWarning(providerMessage);

expect(consoleLogSpy).toHaveBeenCalledWith('hello world');
expect(consoleWarnSpy).not.toHaveBeenCalled();
});
expect(consoleLogSpy).toHaveBeenCalledWith('hello world');
expect(consoleWarnSpy).not.toHaveBeenCalled();
});

it('emits a console warning when level is warn', () => {
setEuiDevProviderWarning('warn');
it('emits a console warning when level is warn', () => {
setEuiDevProviderWarning('warn');

emitEuiProviderWarning(providerMessage);
emitEuiProviderWarning(providerMessage);

expect(consoleLogSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).toHaveBeenCalledWith('hello world');
expect(consoleLogSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).toHaveBeenCalledWith('hello world');
});

it('throws an error when level is error', () => {
setEuiDevProviderWarning('error');

expect(() => emitEuiProviderWarning(providerMessage)).toThrowError(
'hello world'
);

expect(consoleLogSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).not.toHaveBeenCalled();
});
});

it('throws an error when level is error', () => {
setEuiDevProviderWarning('error');
describe('calls optional callback function', () => {
const providerMessage = 'hello callback';
const devCallback = jest.fn();

afterEach(() => {
devCallback.mockReset();
});

it('when level is log', () => {
setEuiDevProviderWarning('log', devCallback);

emitEuiProviderWarning(providerMessage);

expect(devCallback).toHaveBeenCalledWith('hello callback');
expect(devCallback).toHaveBeenCalledTimes(1);
});

it('when level is warn', () => {
setEuiDevProviderWarning('warn', devCallback);

expect(() => emitEuiProviderWarning(providerMessage)).toThrowError(
'hello world'
);
emitEuiProviderWarning(providerMessage);

expect(consoleLogSpy).not.toHaveBeenCalled();
expect(consoleWarnSpy).not.toHaveBeenCalled();
expect(devCallback).toHaveBeenCalledWith('hello callback');
expect(devCallback).toHaveBeenCalledTimes(1);
});

it('when level is error', () => {
setEuiDevProviderWarning('error', devCallback);

expect(() => emitEuiProviderWarning(providerMessage)).toThrow();

expect(devCallback).toHaveBeenCalledWith(new Error('hello callback'));
expect(devCallback).toHaveBeenCalledTimes(1);
});
});
});
});
17 changes: 14 additions & 3 deletions packages/eui/src/services/theme/warning.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,18 @@
*/

type LEVELS = 'log' | 'warn' | 'error';
type ProviderCallback = (message: string | Error) => void;

let providerWarning: LEVELS | undefined = undefined;
let providerCallback: ProviderCallback | undefined;

export const setEuiDevProviderWarning = (level: LEVELS | undefined) =>
(providerWarning = level);
export const setEuiDevProviderWarning = (
level: LEVELS | undefined,
cb?: ProviderCallback
) => {
providerWarning = level;
providerCallback = cb;
};

export const getEuiDevProviderWarning = () => providerWarning;

Expand All @@ -20,12 +27,16 @@ export const emitEuiProviderWarning = (providerMessage: string) => {
switch (providerWarning) {
case 'log':
console.log(providerMessage);
providerCallback?.(providerMessage);
break;
case 'warn':
console.warn(providerMessage);
providerCallback?.(providerMessage);
break;
case 'error':
throw new Error(providerMessage);
const providerError = new Error(providerMessage);
providerCallback?.(providerError);
throw providerError;
case undefined:
default:
break;
Expand Down

0 comments on commit 211b1f7

Please sign in to comment.