diff --git a/test/test-hash.html b/test/test-hash.html
new file mode 100644
index 00000000..e0197ba3
--- /dev/null
+++ b/test/test-hash.html
@@ -0,0 +1,78 @@
+
+
+
+
+ TableFilter hash persistence
+
+
+
+
+
+
+
+
+ From |
+ Destination |
+ Road Distance (km) |
+ By Air (hrs) |
+ By Rail (hrs) |
+
+
+ Sydney |
+ Adelaide |
+ 1412 |
+ 1.4 |
+ 25.3 |
+
+
+ Sydney |
+ Brisbane |
+ 982 |
+ 1.5 |
+ 16 |
+
+
+ Sydney |
+ Canberra |
+ 286 |
+ .6 |
+ 4.3 |
+
+
+ Sydney |
+ Melbourne |
+ 872 |
+ 1.1 |
+ 10.5 |
+
+
+ Adelaide |
+ Perth |
+ 2781 |
+ 3.1 |
+ 38 |
+
+
+ Adelaide |
+ Alice Springs |
+ 1533 |
+ 2 |
+ 20.25 |
+
+
+ Adelaide |
+ Brisbane |
+ 2045 |
+ 2.15 |
+ 40 |
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/test-hash.js b/test/test-hash.js
new file mode 100644
index 00000000..54c72b0e
--- /dev/null
+++ b/test/test-hash.js
@@ -0,0 +1,84 @@
+
+var tf = new TableFilter('demo', {
+ base_path: '../dist/tablefilter/',
+ state: {
+ type: ['hash'],
+ filters: true,
+ page_number: true,
+ page_length: true
+ },
+ paging: true,
+ results_per_page: ['Records: ', [2, 4, 6]],
+});
+tf.init();
+var state = tf.feature('state');
+var hash = state.hash;
+
+module('Sanity checks');
+test('State instance', function() {
+ deepEqual(typeof hash, 'object', 'Hash is instantiated');
+ deepEqual(hash.lastHash, '', 'Last store hash');
+ deepEqual(hash.state, state, 'State instance');
+ deepEqual(hash.emitter, state.emitter, 'Emitter instance');
+});
+
+module('Behaviour');
+test('Can update URL hash', function() {
+ // setup
+ var stateObj = {
+ 'page': 2,
+ 'page_length': 4,
+ 'col_2': {'flt': '>500'}
+ };
+
+ // act
+ state.emitter.emit('state-changed', tf, stateObj);
+
+ // assert
+ deepEqual(location.hash,
+ '#{"page":2,"page_length":4,"col_2":{"flt":">500"}}',
+ 'URL hash updated');
+});
+
+test('Can parse a URL hash', function() {
+ // setup
+ var hashStr = '#{"page":2,"page_length":4,"col_2":{"flt":">500"}}';
+
+ // act
+ var result = hash.parse(hashStr);
+
+ // assert
+ deepEqual(result,
+ {
+ 'page': 2,
+ 'page_length': 4,
+ 'col_2': {'flt': '>500'}
+ },
+ 'Parsed hash'
+ );
+});
+
+test('Can sync state', function() {
+ // setup
+ location.hash = '#{"page":2,"page_length":4,"col_2":{"flt":">500"}}';
+
+ // act
+ hash.sync();
+
+ // assert
+ deepEqual(tf.getValidRows(), [2,3,5,6,7,8], 'Table filters are synced');
+});
+
+module('Tear-down');
+test('Can destroy', function() {
+ // setup
+ location.hash = '';
+
+ // act
+ hash.destroy();
+
+ // assert
+ deepEqual(hash.state, null, 'State instance is null');
+ deepEqual(hash.lastHash, null, 'Last hash reference is null');
+ deepEqual(hash.emitter, null, 'Emitter instance is null');
+});