From dc0011de67520c977729e61d2b5eff3d9d6f9595 Mon Sep 17 00:00:00 2001 From: Doug Miller Date: Wed, 11 Oct 2017 21:43:21 -0400 Subject: [PATCH] Throw appropriate errors for invalid instantiation. Throw appropriate errors if a Style Interface has not been registered or an invalid Style Interface has been registered. Throw an appropriate error if a Theme has not been registered. Resolves: #102 --- src/ThemedStyleSheet.js | 45 +++++++++++++++++++++++++++ test/ThemedStyleSheet_tests.js | 57 ++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 test/ThemedStyleSheet_tests.js diff --git a/src/ThemedStyleSheet.js b/src/ThemedStyleSheet.js index df239aea..be132e8c 100644 --- a/src/ThemedStyleSheet.js +++ b/src/ThemedStyleSheet.js @@ -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; @@ -34,6 +76,9 @@ function get() { } function resolve(...styles) { + if (process.env.NODE_ENV !== 'production') { + validateStyleInterface(); + } return styleInterface.resolve(styles); } diff --git a/test/ThemedStyleSheet_tests.js b/test/ThemedStyleSheet_tests.js new file mode 100644 index 00000000..213b6605 --- /dev/null +++ b/test/ThemedStyleSheet_tests.js @@ -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); + }); + }); + }); +});