Skip to content
Open
Show file tree
Hide file tree
Changes from all 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
45 changes: 45 additions & 0 deletions src/ThemedStyleSheet.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,53 @@ function registerTheme(theme) {
};
}

function invalidMethodError(invalidMethodName) {
return new TypeError(`
react-with-styles internal error: An invalid Style Interface has been registered.
typeof interface.${invalidMethodName} must be a function.
`);
}

function validateStyleInterfaceShape(interfaceToValidate) {
if (!(typeof interfaceToValidate.create === 'function')) {
throw invalidMethodError('create');
}

if (!(typeof interfaceToValidate.resolve === 'function')) {
throw invalidMethodError('resolve');
}
}

function registerInterface(interfaceToRegister) {
if (process.env.NODE_ENV !== 'production') {
validateStyleInterfaceShape(interfaceToRegister);
}
styleInterface = interfaceToRegister;
}

function validateStyleInterface() {
if (!styleInterface) {
throw new ReferenceError(`
react-with-styles internal error: A Style Interface has not been registered.
You must register a valid Style Interface using ThemedStyleSheet.registerInterface.
`);
}
}

function validateStyleTheme() {
if (!styleTheme) {
throw new ReferenceError(`
react-with-styles internal error: A Theme has not been registered.
You must register a theme using ThemedStyleSheet.registerTheme.
`);
}
}

function create(makeFromTheme) {
if (process.env.NODE_ENV !== 'production') {
validateStyleInterface();
validateStyleTheme();
}
// Get an id to associate with this stylesheet
const id = internalId;
internalId += 1;
Expand All @@ -34,6 +76,9 @@ function get() {
}

function resolve(...styles) {
if (process.env.NODE_ENV !== 'production') {
validateStyleInterface();
}
return styleInterface.resolve(styles);
}

Expand Down
57 changes: 57 additions & 0 deletions test/ThemedStyleSheet_tests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import { expect } from 'chai';
import globalCache from 'global-cache';

let ThemedStyleSheet;

describe('ThemedStyleSheet', () => {
beforeEach(() => {
ThemedStyleSheet = require('../src/ThemedStyleSheet').default; // eslint-disable-line global-require
});

afterEach(() => {
delete require.cache[require.resolve('../src/ThemedStyleSheet')];
globalCache.clear();
});

describe('errors', () => {
it('throws a Reference Error if a theme has not been registered and create is called', () => {
ThemedStyleSheet.registerInterface({
create() {},
resolve() {},
});
expect(ThemedStyleSheet.create).to.throw(ReferenceError);
});

describe('Style Interface', () => {
beforeEach(() => {
ThemedStyleSheet.registerTheme({});
});

it('throws a ReferenceError if an interface has not be registered and create is called', () => {
expect(ThemedStyleSheet.create).to.throw(ReferenceError);
});

it('throws a ReferenceError if an interface has not be registered and resolve is called', () => {
expect(ThemedStyleSheet.resolve).to.throw(ReferenceError);
});

it('throws a TypeError if create is not a function when the interface is registered', () => {
const mockInterface = {
create: {},
resolve() {},
};
const register = () => ThemedStyleSheet.registerInterface(mockInterface);
expect(register).to.throw(TypeError);
});

it('throws a TypeError if resolve is not a function when the interface is registered', () => {
const mockInterface = {
create() {},
resolve: {},
};
const register = () => ThemedStyleSheet.registerInterface(mockInterface);
expect(register).to.throw(TypeError);
});
});
});
});