1 | <!DOCTYPE html>
|
2 | <head>
|
3 | <title>store.js test</title>
|
4 | <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
5 | <style type="text/css">
|
6 | body { margin: 50px; font-family: helvetica; color: #333; }
|
7 | div { color: green; }
|
8 | #errorOutput div { color: red; }
|
9 | </style>
|
10 | <script src="https://raw.github.com/marcuswestin/store.js/master/json.js"></script>
|
11 | <script src="https://raw.github.com/marcuswestin/store.js/master/store.js"></script>
|
12 | </head>
|
13 | <body>
|
14 | tests for <a href="http://github.com/marcuswestin/store.js">store.js</a>
|
15 | <div id="errorOutput"></div>
|
16 |
|
17 | <script>
|
18 | (function() {
|
19 | var doc = document,
|
20 | errorOutput = doc.getElementById('errorOutput'),
|
21 | testFailed = false,
|
22 | isSecondPass = (doc.location.hash == '#secondPass')
|
23 |
|
24 | function outputError(msg) { errorOutput.appendChild(doc.createElement('div')).innerHTML = msg }
|
25 | function assert(truthy, msg) {
|
26 | if (!truthy) {
|
27 | outputError((isSecondPass ? 'second' : 'first') + ' pass bad assert: ' + msg);
|
28 | if (store.disabled) { outputError('<br>Note that store.disabled == true') }
|
29 | testFailed = true
|
30 | }
|
31 | }
|
32 |
|
33 | function doFirstPass() {
|
34 | store.clear()
|
35 |
|
36 | store.get('unsetValue')
|
37 |
|
38 | store.set('foo', 'bar')
|
39 | assert(store.get('foo') == 'bar', "stored key 'foo' not equal to stored value 'bar'")
|
40 |
|
41 | store.remove('foo')
|
42 | assert(store.get('foo') == null, "removed key 'foo' not null")
|
43 |
|
44 | assert(store.set('foo','value') == 'value', "store#set returns the stored value")
|
45 |
|
46 | store.set('foo', 'bar1')
|
47 | store.set('foo', 'bar2')
|
48 | assert(store.get('foo') == 'bar2', "key 'foo' is not equal to second value set 'bar2'")
|
49 |
|
50 | store.set('foo', 'bar')
|
51 | store.set('bar', 'foo')
|
52 | store.remove('foo')
|
53 | assert(store.get('bar') == 'foo', "removing key 'foo' also removed key 'bar'")
|
54 |
|
55 | store.set('foo', 'bar')
|
56 | store.set('bar', 'foo')
|
57 | store.clear()
|
58 | assert(store.get('foo') == null && store.get('bar') == null, "keys foo and bar not cleared after store cleared")
|
59 |
|
60 | store.transact('foosact', function(val) {
|
61 | assert(typeof val == 'object', "new key is not an object at beginning of transaction")
|
62 | val.foo = 'foo'
|
63 | })
|
64 | store.transact('foosact', function(val) {
|
65 | assert(val.foo == 'foo', "first transaction did not register")
|
66 | val.bar = 'bar'
|
67 | })
|
68 | assert(store.get('foosact').bar == 'bar', "second transaction did not register")
|
69 |
|
70 | store.set('foo', { name: 'marcus', arr: [1,2,3] })
|
71 | assert(typeof store.get('foo') == 'object', "type of stored object 'foo' is not 'object'")
|
72 | assert(store.get('foo') instanceof Object, "stored object 'foo' is not an instance of Object")
|
73 | assert(store.get('foo').name == 'marcus', "property 'name' of stored object 'foo' is not 'marcus'")
|
74 | assert(store.get('foo').arr instanceof Array, "Array property 'arr' of stored object 'foo' is not an instance of Array")
|
75 | assert(store.get('foo').arr.length == 3, "The length of Array property 'arr' stored on object 'foo' is not 3")
|
76 |
|
77 | assert(store.enabled = !store.disabled, "Store.enabled is not the reverse of .disabled");
|
78 |
|
79 | store.remove('circularReference')
|
80 | var circularOne = {}
|
81 | var circularTwo = { one:circularOne }
|
82 | circularOne.two = circularTwo
|
83 | var threw = false
|
84 | try { store.set('circularReference', circularOne) }
|
85 | catch(e) { threw = true }
|
86 | assert(threw, "storing object with circular reference did not throw")
|
87 | assert(!store.get('circularReference'), "attempting to store object with circular reference which should have faile affected store state")
|
88 |
|
89 |
|
90 |
|
91 | if (window.localStorage) {
|
92 | var promoteValues = {
|
93 | 'int' : 42,
|
94 | 'bool' : true,
|
95 | 'float' : 3.141592653,
|
96 | 'string' : "Don't Panic",
|
97 | 'odd_string' : "{ZYX'} abc:;::)))"
|
98 | }
|
99 | for (key in promoteValues) {
|
100 | window.localStorage[key] = promoteValues[key]
|
101 | }
|
102 | for (key in promoteValues) {
|
103 | assert(store.get(key) == promoteValues[key], key+" was not correctly promoted to valid JSON")
|
104 | store.remove(key)
|
105 | }
|
106 | }
|
107 |
|
108 |
|
109 | store.set('firstPassFoo', 'bar')
|
110 | store.set('firstPassObj', { woot: true })
|
111 |
|
112 | var all = store.getAll()
|
113 | assert(all.firstPassFoo == 'bar', 'getAll gets firstPassFoo')
|
114 | assert(countProperties(all) == 4, 'getAll gets all 4 values')
|
115 | }
|
116 |
|
117 | function doSecondPass() {
|
118 | assert(store.get('firstPassFoo') == 'bar', "first pass key 'firstPassFoo' not equal to stored value 'bar'")
|
119 |
|
120 | var all = store.getAll()
|
121 | assert(all.firstPassFoo == 'bar', "getAll still gets firstPassFoo on second pass")
|
122 | assert(countProperties(all) == 4, "getAll gets all 4 values")
|
123 |
|
124 | store.clear()
|
125 | assert(store.get('firstPassFoo') == null, "first pass key 'firstPassFoo' not null after store cleared")
|
126 |
|
127 | var all = store.getAll()
|
128 | assert(countProperties(all) == 0, "getAll returns 0 properties after store.clear() has been called")
|
129 | }
|
130 |
|
131 | function countProperties(obj) {
|
132 | var count = 0
|
133 | for (var key in obj) {
|
134 | if (obj.hasOwnProperty(key)) { count++ }
|
135 | }
|
136 | return count
|
137 | }
|
138 |
|
139 | try {
|
140 | if (isSecondPass) { doSecondPass() }
|
141 | else { doFirstPass() }
|
142 | } catch(e) {
|
143 | assert(false, 'Tests should not throw: "' + JSON.stringify(e) + '"')
|
144 | }
|
145 |
|
146 | if (!testFailed) {
|
147 | if (!isSecondPass) {
|
148 | doc.location.hash = '#secondPass'
|
149 | doc.location.reload()
|
150 | } else {
|
151 | doc.location.hash = '#'
|
152 | doc.body.appendChild(doc.createElement('div')).innerHTML = 'Tests passed'
|
153 | }
|
154 | }
|
155 | })()
|
156 | </script>
|
157 | </body>
|
158 | </html>
|