Skip to content

Commit 28c9d7a

Browse files
committed
Added dependencies
Upcase incode and outcodes Moved dependency Full list of Ordnance Survey postcodes Exhaustive tests
1 parent f820968 commit 28c9d7a

5 files changed

Lines changed: 129 additions & 9 deletions

File tree

README.md

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,11 @@
11
[![Build Status](https://travis-ci.org/cblanc/postcode.js.png)](https://travis-ci.org/cblanc/postcode.js)
2+
[![Dependency Status](https://gemnasium.com/cblanc/postcode.js.png)](https://gemnasium.com/cblanc/postcode.js)
23

34
# Postcodes
45

5-
Utility methods for UK Postcodes
6+
Utility methods for UK Postcodes.
7+
8+
Included is a test suite that tests against all postcodes listed in the Ordnance Survey's postcode dataset as of January 2014.
69

710
## Getting Started
811

@@ -35,4 +38,6 @@ Postcodes cannot be validated just with a regular expression. Proper postcode va
3538

3639
## License
3740

38-
MIT
41+
MIT
42+
43+
Contains Ordnance Survey Data © Crown Copyright & Database Right 2014

index.js

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
"use strict";
22

3-
var validationRegex = /^[a-z0-9]{1,4}\s?\d[a-z]{2}$/i,
3+
var validationRegex = /^[a-z0-9]{1,4}\s*?\d[a-z]{2}$/i,
44
outcodeRegex = /\d[a-z]{2}$/i;
55

66
function isValidPostcode (postcode) {
77
return !!postcode.match(validationRegex);
88
}
99

1010
function parseIncode (postcode) {
11-
return postcode.replace(outcodeRegex, "").replace(/\s/, "");
11+
return postcode.replace(outcodeRegex, "").replace(/\s+/, "");
1212
}
1313

1414
function parseOutcode (postcode) {
@@ -31,21 +31,21 @@ Postcode.prototype.valid = function () {
3131
Postcode.prototype.incode = function () {
3232
if (!this._valid) return null;
3333
if (this._incode) return this._incode;
34-
this._incode = parseIncode(this._raw);
34+
this._incode = parseIncode(this._raw).toUpperCase();
3535
return this._incode;
3636
}
3737

3838
Postcode.prototype.outcode = function () {
3939
if (!this._valid) return null;
4040
if (this._outcode) return this._outcode;
41-
this._outcode = parseOutcode(this._raw);
41+
this._outcode = parseOutcode(this._raw).toUpperCase();
4242
return this._outcode;
4343
}
4444

4545
Postcode.prototype.normalise = function () {
4646
if (!this._valid) return null;
4747
if (this.postcode) return this.postcode;
48-
return [this.incode().toUpperCase()," ", this.outcode().toUpperCase()].join("");
48+
return [this.incode()," ", this.outcode()].join("");
4949
}
5050

5151
module.exports = Postcode;

package.json

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,11 @@
77
"test": "tests"
88
},
99
"dependencies": {
10-
"chai": "~1.8.1"
1110
},
1211
"devDependencies": {
13-
"mocha": "~1.17.0"
12+
"mocha": "~1.17.0",
13+
"csv": "~0.3.6",
14+
"chai": "~1.8.1"
1415
},
1516
"scripts": {
1617
"test": "mocha tests/"

tests/data/postcodes.csv.gz

3.79 MB
Binary file not shown.

tests/exhaustive_unit.js

Lines changed: 114 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,114 @@
1+
var assert = require("chai").assert,
2+
fs = require("fs"),
3+
csv = require("csv"),
4+
path = require("path"),
5+
zlib = require("zlib"),
6+
dataDir = path.join(__dirname, "./data"),
7+
Postcode = require(path.join(__dirname, "../index"));
8+
9+
describe("Exhaustive postcode test", function () {
10+
var gunzip, input, output, testData, testResult,
11+
inputFile = path.join(dataDir, "postcodes.csv.gz"),
12+
outputFile = path.join(dataDir, "postcodes.csv");
13+
14+
before(function (done) {
15+
this.timeout(60000);
16+
gunzip = zlib.createGunzip();
17+
input = fs.createReadStream(inputFile);
18+
output = fs.createWriteStream(outputFile);
19+
input.pipe(gunzip).pipe(output);
20+
input.on("end", function () {
21+
console.log("Loading in complete array of postcodes (this might take a while)...");
22+
csv().from.path(outputFile).to.array(function (data, count) {
23+
testData = data;
24+
done();
25+
});
26+
});
27+
});
28+
29+
after(function (done) {
30+
fs.unlink(outputFile, done);
31+
});
32+
33+
describe("Postcode#Valid", function () {
34+
it ("should all be valid", function (done) {
35+
this.timeout(60000);
36+
testData.forEach(function (testPostcode) {
37+
var pc = testPostcode[0],
38+
postcode = new Postcode(testPostcode[0]);
39+
assert.isTrue(postcode.valid(), "Expected " + testPostcode[0] +" to be valid");
40+
});
41+
done();
42+
});
43+
});
44+
describe("Postcode normalisation", function () {
45+
it ("should not throw and provide consistant normalised postcode", function (done) {
46+
this.timeout(60000);
47+
testData.forEach(function (testPostcode) {
48+
var pc = testPostcode[0],
49+
postcode = new Postcode(pc),
50+
downcasePostcode = new Postcode(pc.toLowerCase()),
51+
unspacedPostcode = new Postcode(pc.replace(/\s/, ""));
52+
if (pc.length === 7) {
53+
// Since this isn't normalised in dataset, best we can do is see if normalised data matches
54+
assert.equal(postcode.normalise(), downcasePostcode.normalise());
55+
assert.equal(postcode.normalise(), unspacedPostcode.normalise());
56+
} else {
57+
// Any space indicates incode/outcode
58+
assert.equal(postcode.normalise(), pc.replace(/\s*/, " "));
59+
assert.equal(downcasePostcode.normalise(), pc.replace(/\s*/, " "));
60+
assert.equal(unspacedPostcode.normalise(), pc.replace(/\s*/, " "));
61+
}
62+
});
63+
done();
64+
});
65+
});
66+
describe("Incode parsing", function () {
67+
it("should return the correct incode", function (done) {
68+
this.timeout(60000);
69+
testData.forEach(function (testPostcode) {
70+
var pc = testPostcode[0],
71+
postcode = new Postcode(pc),
72+
downcasePostcode = new Postcode(pc.toLowerCase()),
73+
unspacedPostcode = new Postcode(pc.replace(/\s/, "")),
74+
testIncode;
75+
if (pc.length === 7) {
76+
// Since this isn't normalised in dataset, best we can do is see if normalised data matches
77+
assert.equal(postcode.incode(), downcasePostcode.incode());
78+
assert.equal(postcode.incode(), unspacedPostcode.incode());
79+
} else {
80+
// Any space indicates incode/outcode
81+
testIncode = pc.match(/.*\s/)[0].replace(/\s/, "");
82+
assert.equal(postcode.incode(), testIncode);
83+
assert.equal(downcasePostcode.incode(), testIncode);
84+
assert.equal(unspacedPostcode.incode(), testIncode);
85+
}
86+
});
87+
done();
88+
});
89+
});
90+
describe("Outcode parsing", function () {
91+
it("should return the correct outcode", function (done) {
92+
this.timeout(60000);
93+
testData.forEach(function (testPostcode) {
94+
var pc = testPostcode[0],
95+
postcode = new Postcode(pc),
96+
downcasePostcode = new Postcode(pc.toLowerCase()),
97+
unspacedPostcode = new Postcode(pc.replace(/\s/, "")),
98+
testIncode;
99+
if (pc.length === 7) {
100+
// Since this isn't normalised in dataset, best we can do is see if normalised data matches
101+
assert.equal(postcode.outcode(), downcasePostcode.outcode());
102+
assert.equal(postcode.outcode(), unspacedPostcode.outcode());
103+
} else {
104+
// Any space indicates incode/outcode
105+
testIncode = pc.match(/\s.*/)[0].replace(/\s/, "");
106+
assert.equal(postcode.outcode(), testIncode);
107+
assert.equal(downcasePostcode.outcode(), testIncode);
108+
assert.equal(unspacedPostcode.outcode(), testIncode);
109+
}
110+
});
111+
done();
112+
});
113+
});
114+
});

0 commit comments

Comments
 (0)