Commit 2a99b84b authored by Sean Hammond's avatar Sean Hammond Committed by GitHub

Merge pull request #424 from hypothesis/extract-configFuncSettingsFrom

Extract a new configFuncSettingsFrom() function
parents a7454216 5bce43e6
......@@ -3,8 +3,6 @@
var settings = require('./settings');
var sharedSettings = require('../../shared/settings');
var docs = 'https://h.readthedocs.io/en/latest/embedding.html';
/**
* Reads the Hypothesis configuration from the environment.
*
......@@ -53,14 +51,7 @@ function configFrom(window_) {
err);
}
// Parse config from `window.hypothesisConfig` function
if (window_.hasOwnProperty('hypothesisConfig')) {
if (typeof window_.hypothesisConfig === 'function') {
Object.assign(config, window_.hypothesisConfig());
} else {
throw new TypeError('hypothesisConfig must be a function, see: ' + docs);
}
}
Object.assign(config, settings.configFuncSettingsFrom(window_));
// Convert legacy keys/values in config to corresponding current
// configuration.
......
......@@ -70,8 +70,45 @@ function query(url) {
return null;
}
/**
* Return an object containing config settings from window.hypothesisConfig().
*
* Return an object containing config settings returned by the
* window.hypothesisConfig() function provided by the host page:
*
* {
* fooSetting: 'fooValue',
* barSetting: 'barValue',
* ...
* }
*
* If there's no window.hypothesisConfig() function then return {}.
*
* If there is a window.hypothesisConfig but it isn't a function then throw an
* error.
*
* @param {Window} window_ - The window to search for a hypothesisConfig() function
* @return {Object} - Any config settings returned by hypothesisConfig()
*
* @throws {TypeError} - If window.hypothesisConfig() isn't a function
*
*/
function configFuncSettingsFrom(window_) {
if (!window_.hasOwnProperty('hypothesisConfig')) {
return {};
}
if (typeof window_.hypothesisConfig !== 'function') {
var docs = 'https://h.readthedocs.io/projects/client/en/latest/publishers/config/#window.hypothesisConfig';
throw new TypeError('hypothesisConfig must be a function, see: ' + docs);
}
return window_.hypothesisConfig();
}
module.exports = {
app: app,
annotations: annotations,
query: query,
configFuncSettingsFrom: configFuncSettingsFrom,
};
......@@ -32,6 +32,7 @@ describe('annotator.config', function() {
fakeSettings.app = sinon.stub().returns('IFRAME_URL');
fakeSettings.annotations = sinon.stub();
fakeSettings.query = sinon.stub();
fakeSettings.configFuncSettingsFrom = sinon.stub().returns({});
});
afterEach('reset the sandbox', function() {
......@@ -104,51 +105,42 @@ describe('annotator.config', function() {
});
});
context("when there's a window.hypothesisConfig() function", function() {
it('reads arbitrary settings from hypothesisConfig() into config', function() {
var window_ = fakeWindow();
window_.hypothesisConfig = sinon.stub().returns({foo: 'bar'});
it('gets config settings from window.hypothesisConfig()', function() {
var window_ = fakeWindow();
configFrom(window_);
assert.calledOnce(fakeSettings.configFuncSettingsFrom);
assert.calledWithExactly(fakeSettings.configFuncSettingsFrom, window_);
});
context('when configFuncSettingsFrom() returns an object', function() {
it('reads arbitrary settings from configFuncSettingsFrom() into config', function() {
fakeSettings.configFuncSettingsFrom.returns({foo: 'bar'});
var config = configFrom(window_);
var config = configFrom(fakeWindow());
assert.equal(config.foo, 'bar');
});
specify('hypothesisConfig() settings override js-hypothesis-config ones', function() {
var window_ = fakeWindow();
window_.hypothesisConfig = sinon.stub().returns({
fakeSettings.configFuncSettingsFrom.returns({
foo: 'fooFromHypothesisConfigFunc'});
fakeSharedSettings.jsonConfigsFrom.returns({
foo: 'fooFromJSHypothesisConfigObj',
});
var config = configFrom(window_);
var config = configFrom(fakeWindow());
assert.equal(config.foo, 'fooFromHypothesisConfigFunc');
});
context('if hypothesisConfig() returns a non-object value', function() {
it("doesn't add anything into the config", function() {
var window_ = fakeWindow();
window_.hypothesisConfig = sinon.stub().returns(42);
var config = configFrom(window_);
delete config.app; // We don't care about config.app for this test.
assert.deepEqual({}, config);
});
});
});
context("when window.hypothesisConfig() isn't a function", function() {
it('throws a TypeError', function() {
var window_ = fakeWindow();
window_.hypothesisConfig = 'notAFunction';
context('when configFuncSettingsFrom() throws an error', function() {
it('throws the same error', function() {
fakeSettings.configFuncSettingsFrom.throws(new TypeError());
assert.throws(
function() { configFrom(window_); }, TypeError,
'hypothesisConfig must be a function, see: https://h.readthedocs.io/en/latest/embedding.html'
);
assert.throws(function() { configFrom(fakeWindow()); }, TypeError);
});
});
......
......@@ -186,4 +186,35 @@ describe('annotation.config.settings', function() {
});
});
});
describe('#configFuncSettingsFrom', function() {
context("when there's no window.hypothesisConfig() function", function() {
it('returns {}', function() {
var fakeWindow = {};
assert.deepEqual(settings.configFuncSettingsFrom(fakeWindow), {});
});
});
context("when window.hypothesisConfig() isn't a function", function() {
it('throws an error', function() {
var fakeWindow = { hypothesisConfig: 42 };
assert.throws(
function() { settings.configFuncSettingsFrom(fakeWindow); },
TypeError
);
});
});
context('when window.hypothesisConfig() is a function', function() {
it('returns whatever window.hypothesisConfig() returns', function () {
// It just blindly returns whatever hypothesisConfig() returns
// (even if it's not an object).
var fakeWindow = { hypothesisConfig: sinon.stub().returns(42) };
assert.equal(settings.configFuncSettingsFrom(fakeWindow), 42);
});
});
});
});
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment