Skip to content

Commit 9b9a81c

Browse files
committed
Merge pull request #5 from yahoo/extend
Create `extend()` API so any Express module instance can be extended
2 parents 13500d5 + 6f71f76 commit 9b9a81c

File tree

6 files changed

+153
-24
lines changed

6 files changed

+153
-24
lines changed

HISTORY.md

+16-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,18 @@
11
Express State Change History
22
============================
33

4+
NEXT
5+
----
6+
7+
* Added `extend()` function which takes an `express` module instance and adds
8+
the `expose()` method to its application and response prototype, if it does
9+
not already exist.
10+
11+
* Added `augment()` function which takes an Express app instance and adds the
12+
`expose()` method to it application and its response prototype, if it does not
13+
already exist.
14+
15+
416
0.0.3 (2013-06-08)
517
------------------
618

@@ -16,7 +28,10 @@ Express State Change History
1628
* Added Travis CI integration.
1729

1830
* Improved namespace rendering by removing the initialization of leaf namespaces
19-
since exposed values will be assigned to them. (Issue #1)
31+
since exposed values will be assigned to them. ([#1][])
32+
33+
34+
[#1]: https://github.com/yahoo/express-state/issues/1
2035

2136

2237
0.0.1 (2013-05-02)

index.js

+40-13
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,52 @@
11
'use strict';
22

33
var express = require('express'),
4-
Exposed = require('./lib/exposed'),
5-
6-
appProto = express.application,
7-
resProto = express.response;
4+
Exposed = require('./lib/exposed');
85

96
exports.local = 'state';
107
exports.namespace = null;
118

12-
// Protect against multiple copies of this module augmenting the Express
13-
// `application` and `response` prototypes.
14-
if (typeof appProto.expose === 'function' &&
15-
typeof resProto.expose === 'function') {
9+
exports.augment = augment;
10+
exports.extend = extend;
11+
12+
extend(express);
13+
14+
function extend(express) {
15+
var appProto = express.application,
16+
resProto = express.response;
17+
18+
// Protect against multiple express-state module instances augmenting the
19+
// Express `application` and `response` prototypes.
20+
if (typeof appProto.expose === 'function' &&
21+
typeof resProto.expose === 'function') {
22+
23+
return;
24+
}
25+
26+
// Modifies Express' `application` and `response` prototypes by adding the
27+
// `expose()` method.
28+
resProto.expose = appProto.expose = expose;
29+
}
30+
31+
function augment(app) {
32+
var resProto = app.response;
33+
34+
// Protect against multiple express-state module instances augmenting the
35+
// Express `app` and its `response` prototypes.
36+
if (typeof app.expose === 'function' &&
37+
typeof resProto.expose === 'function') {
38+
39+
return;
40+
}
1641

17-
return;
42+
// Modifies the Express `app` and its `response` prototype by adding the
43+
// `expose()` method.
44+
resProto.expose = app.expose = expose;
1845
}
1946

20-
// Modifies Express' `application` and `response` prototypes by adding the
21-
// `expose()` method.
22-
resProto.expose = appProto.expose = function (obj, namespace, local) {
47+
function expose(obj, namespace, local) {
48+
/* jshint validthis:true */
49+
2350
var app = this.app || this,
2451
appLocals = this.app && this.app.locals,
2552
locals = this.locals,
@@ -64,4 +91,4 @@ resProto.expose = appProto.expose = function (obj, namespace, local) {
6491
}
6592

6693
exposed.add(namespace, obj);
67-
};
94+
}

test/exports.js

+22-2
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ var state = require('../'),
66

77
describe('exports', function () {
88
describe('.local', function () {
9-
it('should have a .local', function () {
9+
it('should have a .local property', function () {
1010
expect(state).to.have.property('local');
1111
});
1212

@@ -16,12 +16,32 @@ describe('exports', function () {
1616
});
1717

1818
describe('.namespace', function () {
19-
it('should have a .namespace', function () {
19+
it('should have a .namespace property', function () {
2020
expect(state).to.have.property('namespace');
2121
});
2222

2323
it('should be null', function () {
2424
expect(state.namespace).to.equal(null);
2525
});
2626
});
27+
28+
describe('.augment', function () {
29+
it('should have a .augment property', function () {
30+
expect(state).to.have.property('augment');
31+
});
32+
33+
it('should respond to .augment()', function () {
34+
expect(state).itself.to.respondTo('augment');
35+
});
36+
});
37+
38+
describe('.extend', function () {
39+
it('should have a .extend property', function () {
40+
expect(state).to.have.property('extend');
41+
});
42+
43+
it('should respond to .extend()', function () {
44+
expect(state).itself.to.respondTo('extend');
45+
});
46+
});
2747
});

test/exposed.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ describe('Exposed', function () {
99
expect(Exposed).to.be.a('function');
1010
});
1111

12-
describe('.create([exposed])', function () {
12+
describe('.create( [exposed] )', function () {
1313
it('should respond to .create()', function () {
1414
expect(Exposed).itself.to.respondTo('create');
1515
});
@@ -60,7 +60,7 @@ describe('Exposed', function () {
6060
});
6161
});
6262

63-
describe('.isExposed([obj])', function () {
63+
describe('.isExposed( [obj] )', function () {
6464
it('should respond to .isExposed()', function () {
6565
expect(Exposed).itself.to.respondTo('isExposed');
6666
});
@@ -94,7 +94,7 @@ describe('Exposed', function () {
9494
});
9595
});
9696

97-
describe('#add(namespace, value)', function () {
97+
describe('#add( namespace, value )', function () {
9898
var exposed;
9999

100100
beforeEach(function () {

test/multiple.js

+71-4
Original file line numberDiff line numberDiff line change
@@ -5,17 +5,21 @@ var expect = require('chai').expect,
55
mockery = require('mockery');
66

77
describe('multiple', function () {
8+
function createExpressMock() {
9+
return {
10+
application: {},
11+
response : {}
12+
};
13+
}
14+
815
beforeEach(function () {
916
mockery.enable({
1017
useCleanCache : true,
1118
warnOnReplace : false,
1219
warnOnUnregistered: false
1320
});
1421

15-
mockery.registerMock('express', {
16-
application: {},
17-
response : {}
18-
});
22+
mockery.registerMock('express', createExpressMock());
1923
});
2024

2125
afterEach(function () {
@@ -33,4 +37,67 @@ describe('multiple', function () {
3337
expect(express.application.expose).to.equal(expose);
3438
expect(express.response.expose).to.equal(expose);
3539
});
40+
41+
describe('.extend( express )', function () {
42+
it('should add `expose()`', function () {
43+
var express = require('express'),
44+
state = require('../');
45+
46+
mockery.registerMock('express', createExpressMock());
47+
express = require('express');
48+
49+
expect(express.application.expose).to.be.undefined;
50+
expect(express.response.expose).to.be.undefined;
51+
52+
state.extend(express);
53+
54+
expect(express.application).itself.to.respondTo('expose');
55+
expect(express.response).itself.to.respondTo('expose');
56+
});
57+
58+
it('should not override `expose()` if it exists', function () {
59+
var expose = function () {},
60+
express, state;
61+
62+
express = require('express');
63+
state = require('../');
64+
65+
express.application.expose = express.response.expose = expose;
66+
state.extend(express);
67+
68+
expect(express.application.expose).to.equal(expose);
69+
expect(express.response.expose).to.equal(expose);
70+
});
71+
});
72+
73+
describe('.augment( app )', function () {
74+
it('should add `expose()`', function () {
75+
var express = require('express'),
76+
state = require('../'),
77+
app = {response: {}};
78+
79+
state.augment(app);
80+
81+
expect(app).itself.to.respondTo('expose');
82+
expect(app.response).itself.to.respondTo('expose');
83+
});
84+
85+
it('should not override `expose()` if it exists', function () {
86+
var expose = function () {},
87+
express, state, app;
88+
89+
express = require('express');
90+
state = require('../');
91+
92+
app = {
93+
expose : expose,
94+
response: {expose: expose}
95+
};
96+
97+
state.augment(app);
98+
99+
expect(app.expose).to.equal(expose);
100+
expect(app.response.expose).to.equal(expose);
101+
});
102+
});
36103
});

test/state.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ describe('state', function () {
1414
app = express();
1515
});
1616

17-
describe('expose()', function () {
17+
describe('expose( obj, [namespace], [local] )', function () {
1818
var expose, locals;
1919

2020
beforeEach(function () {

0 commit comments

Comments
 (0)