UNPKG

15.2 kBJavaScriptView Raw
1var should = require('./init.js');
2var assert = require('assert');
3var Schema = require('jugglingdb').Schema;
4
5var db, UserData, StringData, NumberData, DateData;
6
7describe('migrations', function() {
8
9 before(setup);
10
11 it('should run migration', function(done) {
12 db.automigrate(function(){
13 done();
14 });
15 });
16
17 it('UserData should have correct columns', function(done) {
18 getFields('UserData', function(err, fields) {
19 assert.deepEqual(fields, {
20 id: {
21 Field: 'id',
22 Type: 'int(11)',
23 Null: 'NO',
24 Key: 'PRI',
25 Default: null,
26 Extra: 'auto_increment' },
27 email: {
28 Field: 'email',
29 Type: 'varchar(30)',
30 Null: 'NO',
31 Key: 'MUL',
32 Default: null,
33 Extra: '' },
34 name: {
35 Field: 'name',
36 Type: 'varchar(255)',
37 Null: 'YES',
38 Key: '',
39 Default: null,
40 Extra: '' },
41 bio: {
42 Field: 'bio',
43 Type: 'text',
44 Null: 'YES',
45 Key: '',
46 Default: null,
47 Extra: '' },
48 birthDate: {
49 Field: 'birthDate',
50 Type: 'datetime',
51 Null: 'YES',
52 Key: '',
53 Default: null,
54 Extra: '' },
55 pendingPeriod: {
56 Field: 'pendingPeriod',
57 Type: 'int(11)',
58 Null: 'YES',
59 Key: '',
60 Default: null,
61 Extra: '' },
62 createdByAdmin: {
63 Field: 'createdByAdmin',
64 Type: 'tinyint(1)',
65 Null: 'YES',
66 Key: '',
67 Default: null,
68 Extra: '' }
69 });
70 done();
71 });
72 });
73
74 it('UserData should have correct indexes', function(done) {
75 // Note: getIdexes truncates multi-key indexes to the first member. Hence index1 is correct.
76 getIndexes('UserData', function(err, fields) {
77 assert.deepEqual(fields, { PRIMARY:
78 { Table: 'UserData',
79 Non_unique: 0,
80 Key_name: 'PRIMARY',
81 Seq_in_index: 1,
82 Column_name: 'id',
83 Collation: 'A',
84 Cardinality: 0,
85 Sub_part: null,
86 Packed: null,
87 Null: '',
88 Index_type: 'BTREE',
89 Comment: '',
90 Index_comment: '' },
91 email:
92 { Table: 'UserData',
93 Non_unique: 1,
94 Key_name: 'email',
95 Seq_in_index: 1,
96 Column_name: 'email',
97 Collation: 'A',
98 Cardinality: 0,
99 Sub_part: null,
100 Packed: null,
101 Null: '',
102 Index_type: 'BTREE',
103 Comment: '',
104 Index_comment: '' },
105 index0:
106 { Table: 'UserData',
107 Non_unique: 1,
108 Key_name: 'index0',
109 Seq_in_index: 1,
110 Column_name: 'email',
111 Collation: 'A',
112 Cardinality: 0,
113 Sub_part: null,
114 Packed: null,
115 Null: '',
116 Index_type: 'BTREE',
117 Comment: '',
118 Index_comment: '' }
119 });
120 done();
121 });
122 });
123
124 it('StringData should have correct columns', function(done) {
125 getFields('StringData', function(err, fields) {
126 assert.deepEqual(fields, { id:
127 { Field: 'id',
128 Type: 'int(11)',
129 Null: 'NO',
130 Key: 'PRI',
131 Default: null,
132 Extra: 'auto_increment' },
133 smallString:
134 { Field: 'smallString',
135 Type: 'char(127)',
136 Null: 'NO',
137 Key: 'MUL',
138 Default: null,
139 Extra: '' },
140 mediumString:
141 { Field: 'mediumString',
142 Type: 'varchar(255)',
143 Null: 'NO',
144 Key: '',
145 Default: null,
146 Extra: '' },
147 tinyText:
148 { Field: 'tinyText',
149 Type: 'tinytext',
150 Null: 'YES',
151 Key: '',
152 Default: null,
153 Extra: '' },
154 giantJSON:
155 { Field: 'giantJSON',
156 Type: 'longtext',
157 Null: 'YES',
158 Key: '',
159 Default: null,
160 Extra: '' },
161 text:
162 { Field: 'text',
163 Type: 'varchar(1024)',
164 Null: 'YES',
165 Key: '',
166 Default: null,
167 Extra: '' }
168 });
169 done();
170 });
171 });
172
173 it('NumberData should have correct columns', function(done) {
174 getFields('NumberData', function(err, fields) {
175 assert.deepEqual(fields, {
176 id:
177 { Field: 'id',
178 Type: 'int(11)',
179 Null: 'NO',
180 Key: 'PRI',
181 Default: null,
182 Extra: 'auto_increment' },
183 number:
184 { Field: 'number',
185 Type: 'decimal(10,3) unsigned',
186 Null: 'NO',
187 Key: 'MUL',
188 Default: null,
189 Extra: '' },
190 tinyInt:
191 { Field: 'tinyInt',
192 Type: 'tinyint(2)',
193 Null: 'YES',
194 Key: '',
195 Default: null,
196 Extra: '' },
197 mediumInt:
198 { Field: 'mediumInt',
199 Type: 'mediumint(8) unsigned',
200 Null: 'YES',
201 Key: '',
202 Default: null,
203 Extra: '' },
204 floater:
205 { Field: 'floater',
206 Type: 'double(14,6)',
207 Null: 'YES',
208 Key: '',
209 Default: null,
210 Extra: '' }
211 });
212 done();
213 });
214 });
215
216 it('DateData should have correct columns', function(done) {
217 getFields('DateData', function(err, fields) {
218 assert.deepEqual(fields, {
219 id:
220 { Field: 'id',
221 Type: 'int(11)',
222 Null: 'NO',
223 Key: 'PRI',
224 Default: null,
225 Extra: 'auto_increment' },
226 dateTime:
227 { Field: 'dateTime',
228 Type: 'datetime',
229 Null: 'YES',
230 Key: '',
231 Default: null,
232 Extra: '' },
233 timestamp:
234 { Field: 'timestamp',
235 Type: 'timestamp',
236 Null: 'YES',
237 Key: '',
238 Default: null,
239 Extra: '' }
240 });
241 done();
242 });
243 });
244
245 it('should autoupgrade', function(done) {
246 var userExists = function(cb) {
247 query('SELECT * FROM UserData', function(err, res) {
248 cb(!err && res[0].email == 'test@example.com');
249 });
250 }
251
252 UserData.create({email: 'test@example.com'}, function(err, user) {
253 assert.ok(!err, 'Could not create user');
254 userExists(function(yep) {
255 assert.ok(yep, 'User does not exist');
256 });
257 UserData.defineProperty('email', { type: String, limit: 20 });
258 UserData.defineProperty('name', {type: String, dataType: 'char', limit: 50});
259 UserData.defineProperty('newProperty', {type: Number, unsigned: true, dataType: 'bigInt'});
260 // UserData.defineProperty('pendingPeriod', false); This will not work as expected.
261 db.autoupdate( function(err) {
262 getFields('UserData', function(err, fields) {
263 // change nullable for email
264 assert.equal(fields.email.Null, 'YES', 'Email does not allow null');
265 // change type of name
266 assert.equal(fields.name.Type, 'char(50)', 'Name is not char(50)');
267 // add new column
268 assert.ok(fields.newProperty, 'New column was not added');
269 if (fields.newProperty) {
270 assert.equal(fields.newProperty.Type, 'bigint(20) unsigned', 'New column type is not bigint(20) unsigned');
271 }
272 // drop column - will not happen.
273 // assert.ok(!fields.pendingPeriod, 'Did not drop column pendingPeriod');
274 // user still exists
275 userExists(function(yep) {
276 assert.ok(yep, 'User does not exist');
277 done();
278 });
279 });
280 });
281 });
282 });
283
284 it('record should be updated', function(done) {
285 var userExists = function(cb) {
286 query('SELECT * FROM UserData', function(err, res) {
287 cb(!err && res[0].email == 'yourname@newname.com');
288 });
289 }
290 UserData.update({ where:{id:'1'}, update:{ email:'yourname@newname.com' }}, function(err, o) {
291 assert.equal(err, null);
292 userExists(function(yep) {
293 assert.ok(yep, 'Email has changed');
294 });
295
296 // err when where missing
297 UserData.update( { update:{ email:'yourname@newname.com' } }, function(err, o) {
298 assert.equal(err, "Where or Update fields are missing", " no error when where field is missing ");
299 });
300
301 // err when where update
302 UserData.update( { where:{id:'1'} }, function(err, o) {
303 assert.equal(err, "Where or Update fields are missing", " no error when update field is missing ");
304 done();
305 });
306
307 });
308 });
309
310 it('should check actuality of schema', function(done) {
311 // 'drop column'
312 UserData.schema.isActual(function(err, ok) {
313 assert.ok(ok, 'schema is not actual (should be)');
314 UserData.defineProperty('essay', {type: Schema.Text});
315 // UserData.defineProperty('email', false); Can't undefine currently.
316 UserData.schema.isActual(function(err, ok) {
317 assert.ok(!ok, 'schema is actual (shouldn\t be)');
318 done()
319 });
320 });
321 });
322
323 it('should allow numbers with decimals', function(done) {
324 NumberData.create({number: 1.1234567, tinyInt: 127, mediumInt: 0, floater: 99.99 }, function(err, obj) {
325 assert.ok(!err);
326 assert.ok(obj);
327 NumberData.find(obj.id, function(err, found) {
328 assert.equal(found.number, 1.123);
329 assert.equal(found.tinyInt, 127);
330 assert.equal(found.mediumInt, 0);
331 assert.equal(found.floater, 99.99);
332 done();
333 });
334 });
335 });
336
337 it('should allow both kinds of date columns', function(done) {
338 DateData.create({
339 dateTime: new Date('Aug 9 1996 07:47:33 GMT'),
340 timestamp: new Date('Sep 22 2007 17:12:22 GMT')
341 }, function(err, obj){
342 assert.ok(!err);
343 assert.ok(obj);
344 DateData.find(obj.id, function(err, found){
345 assert.equal(found.dateTime.toGMTString(), 'Fri, 09 Aug 1996 07:47:33 GMT');
346 assert.equal(found.timestamp.toGMTString(), 'Sat, 22 Sep 2007 17:12:22 GMT');
347 done();
348 });
349 });
350 });
351
352 it('should disconnect when done', function(done) {
353 db.disconnect();
354 done()
355 });
356
357});
358
359function setup(done) {
360
361 require('./init.js');
362
363 db = getSchema();
364
365 UserData = db.define('UserData', {
366 email: { type: String, null: false, index: true, limit: 30 },
367 name: String,
368 bio: Schema.Text,
369 birthDate: Date,
370 pendingPeriod: Number,
371 createdByAdmin: Boolean,
372 } , { indexes: {
373 index0: {
374 columns: 'email, createdByAdmin'
375 }
376 }
377 });
378
379 StringData = db.define('StringData', {
380 smallString: {type: String, null: false, index: true, dataType: 'char', limit: 127},
381 mediumString: {type: String, null: false, dataType: 'varchar', limit: 255},
382 tinyText: {type: String, dataType: 'tinyText'},
383 giantJSON: {type: Schema.JSON, dataType: 'longText'},
384 text: {type: Schema.Text, dataType: 'varchar', limit: 1024}
385 });
386
387 NumberData = db.define('NumberData', {
388 number: {type: Number, null: false, index: true, unsigned: true, dataType: 'decimal', precision: 10, scale: 3},
389 tinyInt: {type: Number, dataType: 'tinyInt', display: 2},
390 mediumInt: {type: Number, dataType: 'mediumInt', unsigned: true},
391 floater: {type: Number, dataType: 'double', precision: 14, scale: 6}
392 });
393
394 DateData = db.define('DateData', {
395 dateTime: {type: Date, dataType: 'datetime'},
396 timestamp: {type: Date, dataType: 'timestamp'}
397 });
398
399 blankDatabase(db, done);
400
401}
402
403var query = function (sql, cb) {
404 db.adapter.query(sql, cb);
405};
406
407var blankDatabase = function (db, cb) {
408 var dbn = db.settings.database;
409 var cs = db.settings.charset;
410 var co = db.settings.collation;
411 query('DROP DATABASE IF EXISTS ' + dbn, function(err) {
412 var q = 'CREATE DATABASE ' + dbn;
413 if(cs){
414 q += ' CHARACTER SET ' + cs;
415 }
416 if(co){
417 q += ' COLLATE ' + co;
418 }
419 query(q, function(err) {
420 query('USE '+ dbn, cb);
421 });
422 });
423};
424
425getFields = function (model, cb) {
426 query('SHOW FIELDS FROM ' + model, function(err, res) {
427 if (err) {
428 cb(err);
429 } else {
430 var fields = {};
431 res.forEach(function(field){
432 fields[field.Field] = field;
433 });
434 cb(err, fields);
435 }
436 });
437}
438
439getIndexes = function (model, cb) {
440 query('SHOW INDEXES FROM ' + model, function(err, res) {
441 if (err) {
442 console.log(err);
443 cb(err);
444 } else {
445 var indexes = {};
446 // Note: this will only show the first key of compound keys
447 res.forEach(function(index) {
448 if (parseInt(index.Seq_in_index, 10) == 1) {
449 indexes[index.Key_name] = index
450 }
451 });
452 cb(err, indexes);
453 }
454 });
455};
456
457
458
459
460
461