Skip to content

Commit

Permalink
Merge pull request #4 from yahoo/multi-protect
Browse files Browse the repository at this point in the history
Prevent multiple copies of express-state from overwriting `expose()`
  • Loading branch information
ericf committed Jun 3, 2013
2 parents 4a989e0 + 14b81db commit 8de02e4
Show file tree
Hide file tree
Showing 5 changed files with 113 additions and 10 deletions.
18 changes: 18 additions & 0 deletions HISTORY.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,24 @@
Express State Change History
============================

NEXT
----

* Prevented multiple copies of express-state from overwriting `expose()` when it
already has been plugged into a copy of express.

* Added Screwdriver CI integration.


0.0.2 (2013-05-03)
------------------

* Added Travis CI integration.

* Improved namespace rendering by removing the initialization of leaf namespaces
since exposed values will be assigned to them. (Issue #1)


0.0.1 (2013-05-02)
------------------

Expand Down
8 changes: 8 additions & 0 deletions index.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,14 @@ var express = require('express'),
exports.local = 'state';
exports.namespace = null;

// Protect against multiple copies of this module augmenting the Express
// `application` and `response` prototypes.
if (typeof appProto.expose === 'function' &&
typeof resProto.expose === 'function') {

return;
}

// Modifies Express' `application` and `response` prototypes by adding the
// `expose()` method.
resProto.expose = appProto.expose = function (obj, namespace, local) {
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
"express3-handlebars": "*",
"istanbul" : "*",
"mocha" : "*",
"mockery" : "*",
"xunit-file" : "*"
},

Expand Down
36 changes: 36 additions & 0 deletions test/multiple.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/* global describe, it, beforeEach, afterEach */
'use strict';

var expect = require('chai').expect,
mockery = require('mockery');

describe('multiple', function () {
beforeEach(function () {
mockery.enable({
useCleanCache : true,
warnOnReplace : false,
warnOnUnregistered: false
});

mockery.registerMock('express', {
application: {},
response : {}
});
});

afterEach(function () {
mockery.disable();
});

it('should not override `expose()` if it exists', function () {
var expose = function () {},
express, state;

express = require('express');
express.application.expose = express.response.expose = expose;
state = require('../');

expect(express.application.expose).to.equal(expose);
expect(express.response.expose).to.equal(expose);
});
});
60 changes: 50 additions & 10 deletions test/state.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,11 @@
/* global describe, it, beforeEach, afterEach */
'use strict';

var state = require('../'),
express = require('express'),
expressUtils = require('express/lib/utils'),
var expressUtils = require('express/lib/utils'),
expect = require('chai').expect,
express = require('express'),

origLocal = state.local,
origNamespace = state.namespace;
state = require('../');

describe('state', function () {
var app;
Expand All @@ -16,11 +14,6 @@ describe('state', function () {
app = express();
});

afterEach(function () {
state.local = origLocal;
state.namespace = origNamespace;
});

describe('expose()', function () {
var expose, locals;

Expand Down Expand Up @@ -49,6 +42,16 @@ describe('state', function () {
});

describe('global .local', function () {
var origLocal;

beforeEach(function () {
origLocal = state.local;
});

afterEach(function () {
state.local = origLocal;
});

it('should create the exposed object at the specified `local`', function () {
state.local = 'javascript';
expose();
Expand All @@ -63,6 +66,16 @@ describe('state', function () {
});

describe('global .namespace', function () {
var origNamespace;

beforeEach(function () {
origNamespace = state.namespace;
});

afterEach(function () {
state.namespace = origNamespace;
});

it('should be used when no namespace is provided', function () {
state.namespace = 'App';
expose('foo');
Expand Down Expand Up @@ -98,6 +111,16 @@ describe('state', function () {
});

describe('setting: "state local"', function () {
var origLocal;

beforeEach(function () {
origLocal = state.local;
});

afterEach(function () {
state.local = origLocal;
});

it('should use app setting', function () {
app.set('state local', 'javascript');
app.expose();
Expand All @@ -119,12 +142,29 @@ describe('state', function () {
});

describe('setting: "state namespace"', function () {
var origNamespace;

beforeEach(function () {
origNamespace = state.namespace;
});

afterEach(function () {
state.namespace = origNamespace;
});

it('should use app setting', function () {
app.set('state namespace', 'App');
app.expose('foo');
expect(app.locals.state.App).to.equal('foo');
});

it('should be preferred over the global .namespace', function () {
state.namespace = 'App';
app.set('state namespace', 'Data');
app.expose('foo');
expect(app.locals.state.Data).to.equal('foo');
});

it('should be used as a prefix to the `namespace` provided', function () {
app.set('state namespace', 'App');
app.expose({foo: 'foo'}, 'data');
Expand Down

0 comments on commit 8de02e4

Please sign in to comment.