angularjs-rails-resource 1.0.0.pre.2 → 1.0.0.pre.3

Sign up to get free protection for your applications and to get access to all the features.
data/bower.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "angularjs-rails-resource",
3
- "version": "1.0.0-pre.2",
3
+ "version": "1.0.0-pre.3",
4
4
  "main": "angularjs-rails-resource.js",
5
5
  "description": "A resource factory inspired by $resource from AngularJS",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "https://github.com/FineLinePrototyping/angularjs-rails-resource.git"
8
+ "url": "https://github.com/FineLinePrototyping/dist-angularjs-rails-resource.git"
9
9
  },
10
10
  "dependencies": {
11
11
  "angular": "*"
data/changelog.js ADDED
@@ -0,0 +1,206 @@
1
+ #!/usr/bin/env node
2
+
3
+ // Copied from angular.js and modified to suit our needs
4
+
5
+ var child = require('child_process');
6
+ var fs = require('fs');
7
+ var util = require('util');
8
+ var q = require('qq');
9
+
10
+ var GIT_LOG_CMD = 'git log --grep="%s" -E -i --format=%s %s..HEAD';
11
+ var GIT_TAG_CMD = 'git describe --tags --abbrev=0';
12
+
13
+ var HEADER_TPL = '<a name="%s"></a>\n# %s (%s)\n\n';
14
+ var LINK_ISSUE = '[#%s](https://github.com/FineLinePrototyping/angularjs-rails-resource/issues/%s)';
15
+ var LINK_COMMIT = '[%s](https://github.com/FineLinePrototyping/angularjs-rails-resource/commit/%s)';
16
+
17
+ var EMPTY_COMPONENT = '$$';
18
+
19
+
20
+ var warn = function() {
21
+ console.log('WARNING:', util.format.apply(null, arguments));
22
+ };
23
+
24
+
25
+ var parseRawCommit = function(raw) {
26
+ if (!raw) return null;
27
+
28
+ var lines = raw.split('\n');
29
+ var msg = {}, match;
30
+
31
+ msg.hash = lines.shift();
32
+ msg.subject = lines.shift();
33
+ msg.closes = [];
34
+ msg.deprecates = [];
35
+ msg.breaks = [];
36
+
37
+ lines.forEach(function(line) {
38
+ match = line.match(/(?:Closes|Fixes)\s#(\d+)/);
39
+ if (match) msg.closes.push(parseInt(match[1]));
40
+ match = line.match(/^Deprecates:\s(.*)$/);
41
+ if (match) msg.deprecates.push(match[1]);
42
+ });
43
+
44
+ match = raw.match(/BREAKING CHANGE:([\s\S]*)/);
45
+ if (match) {
46
+ msg.breaking = match[1];
47
+ }
48
+
49
+
50
+ msg.body = lines.join('\n');
51
+ match = msg.subject.match(/^(.*)\(?(.*)\)?\:\s(.*)$/);
52
+
53
+ if (!match || !match[1] || !match[3]) {
54
+ warn('Incorrect message: %s %s', msg.hash, msg.subject);
55
+ return null;
56
+ }
57
+
58
+ msg.type = match[1].toLowerCase();
59
+ msg.component = match[2];
60
+ msg.subject = match[3];
61
+ return msg;
62
+ };
63
+
64
+
65
+ var linkToIssue = function(issue) {
66
+ return util.format(LINK_ISSUE, issue, issue);
67
+ };
68
+
69
+
70
+ var linkToCommit = function(hash) {
71
+ return util.format(LINK_COMMIT, hash.substr(0, 8), hash);
72
+ };
73
+
74
+
75
+ var currentDate = function() {
76
+ var now = new Date();
77
+ var pad = function(i) {
78
+ return ('0' + i).substr(-2);
79
+ };
80
+
81
+ return util.format('%d-%s-%s', now.getFullYear(), pad(now.getMonth() + 1), pad(now.getDate()));
82
+ };
83
+
84
+
85
+ var printSection = function(stream, title, section, printCommitLinks) {
86
+ printCommitLinks = printCommitLinks === undefined ? true : printCommitLinks;
87
+ var components = Object.getOwnPropertyNames(section).sort();
88
+
89
+ if (!components.length) return;
90
+
91
+ stream.write(util.format('\n## %s\n\n', title));
92
+
93
+ components.forEach(function(name) {
94
+ var prefix = '-';
95
+ var nested = section[name].length > 1;
96
+
97
+ if (name !== EMPTY_COMPONENT) {
98
+ if (nested) {
99
+ stream.write(util.format('- **%s:**\n', name));
100
+ prefix = ' -';
101
+ } else {
102
+ prefix = util.format('- **%s:**', name);
103
+ }
104
+ }
105
+
106
+ section[name].forEach(function(commit) {
107
+ if (printCommitLinks) {
108
+ stream.write(util.format('%s %s\n (%s', prefix, commit.subject, linkToCommit(commit.hash)));
109
+ if (commit.closes.length) {
110
+ stream.write(',\n ' + commit.closes.map(linkToIssue).join(', '));
111
+ }
112
+ stream.write(')\n');
113
+ } else {
114
+ stream.write(util.format('%s %s', prefix, commit.subject));
115
+ }
116
+ });
117
+ });
118
+
119
+ stream.write('\n');
120
+ };
121
+
122
+
123
+ var readGitLog = function(grep, from) {
124
+ var deferred = q.defer();
125
+ child.exec(util.format(GIT_LOG_CMD, grep, '%H%n%s%n%b%n==END==', from), function(code, stdout, stderr) {
126
+ var commits = [];
127
+
128
+ stdout.split('\n==END==\n').forEach(function(rawCommit) {
129
+ var commit = parseRawCommit(rawCommit);
130
+ if (commit) commits.push(commit);
131
+ });
132
+
133
+ deferred.resolve(commits);
134
+ });
135
+
136
+ return deferred.promise;
137
+ };
138
+
139
+
140
+ var writeChangelog = function(stream, commits, version) {
141
+ var sections = {
142
+ fix: {},
143
+ feat: {},
144
+ perf: {},
145
+ deprecate: {},
146
+ breaks: {}
147
+ };
148
+
149
+ sections.breaks[EMPTY_COMPONENT] = [];
150
+
151
+ commits.forEach(function(commit) {
152
+ var section = sections[commit.type];
153
+ var component = commit.component || EMPTY_COMPONENT;
154
+
155
+ if (section) {
156
+ section[component] = section[component] || [];
157
+ section[component].push(commit);
158
+ }
159
+
160
+ if (commit.breaking) {
161
+ sections.breaks[component] = sections.breaks[component] || [];
162
+ sections.breaks[component].push({
163
+ subject: util.format("due to %s,\n %s", linkToCommit(commit.hash), commit.breaking),
164
+ hash: commit.hash,
165
+ closes: []
166
+ });
167
+ }
168
+ });
169
+
170
+ stream.write(util.format(HEADER_TPL, version, version, currentDate()));
171
+ printSection(stream, 'Bug Fixes', sections.fix);
172
+ printSection(stream, 'Features', sections.feat);
173
+ printSection(stream, 'Deprecations', sections.deprecates);
174
+ printSection(stream, 'Breaking Changes', sections.breaks, false);
175
+ }
176
+
177
+
178
+ var getPreviousTag = function() {
179
+ var deferred = q.defer();
180
+ child.exec(GIT_TAG_CMD, function(code, stdout, stderr) {
181
+ if (code) deferred.reject('Cannot get the previous tag.');
182
+ else deferred.resolve(stdout.replace('\n', ''));
183
+ });
184
+ return deferred.promise;
185
+ };
186
+
187
+
188
+ var generate = function(version, file) {
189
+ getPreviousTag().then(function(tag) {
190
+ console.log('Reading git log since', tag);
191
+ readGitLog('^fix|^feat|^perf|^deprecate|BREAKING', tag).then(function(commits) {
192
+ console.log('Parsed', commits.length, 'commits');
193
+ console.log('Generating changelog to', file || 'stdout', '(', version, ')');
194
+ writeChangelog(file ? fs.createWriteStream(file) : process.stdout, commits, version);
195
+ });
196
+ });
197
+ };
198
+
199
+
200
+ // publish for testing
201
+ exports.parseRawCommit = parseRawCommit;
202
+
203
+ // hacky start if not run by jasmine :-D
204
+ if (process.argv.join('').indexOf('jasmine-node') === -1) {
205
+ generate(process.argv[2], process.argv[3]);
206
+ }
data/karma.conf.js CHANGED
@@ -11,7 +11,8 @@ module.exports = function(config) {
11
11
  'test/lib/angular/angular-loader.js',
12
12
  'test/lib/angular/angular-sanitize.js',
13
13
  'test/lib/angular/angular-mocks.js',
14
- 'vendor/assets/javascripts/**/*.js',
14
+ 'vendor/assets/javascripts/angularjs/rails/resource/index.js',
15
+ 'vendor/assets/javascripts/angularjs/rails/resource/**/*.js',
15
16
  'test/unit/**/*.js'
16
17
  ],
17
18
  junitReporter: {
@@ -1,7 +1,7 @@
1
1
  module Angularjs
2
2
  module Rails
3
3
  module Resource
4
- VERSION = '1.0.0.pre.2'
4
+ VERSION = '1.0.0.pre.3'
5
5
  end
6
6
  end
7
7
  end
data/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "angularjs-rails-resource",
3
3
  "description" : "A resource factory inspired by $resource from AngularJS",
4
- "version": "1.0.0-pre.2",
4
+ "version": "1.0.0-pre.3",
5
5
  "main" : "dist/angularjs-rails-resource.min.js",
6
6
  "homepage" : "https://github.com/FineLinePrototyping/angularjs-rails-resource.git",
7
7
  "author" : "",
@@ -19,13 +19,19 @@
19
19
  "grunt-contrib-jshint": "~0.6.0",
20
20
  "grunt-contrib-uglify": "~0.2.2",
21
21
  "grunt-contrib-concat": "~0.3.0",
22
+ "grunt-contrib-copy": "~0.4.1",
23
+ "grunt-contrib-clean": "~0.5.0",
22
24
  "grunt-contrib-watch": "~0.5.1",
23
- "grunt-zip": "~0.9.2",
25
+ "grunt-contrib-compress": "~0.5.2",
26
+ "grunt-bump": "~0.0.13",
24
27
  "karma": "~0.10",
25
28
  "karma-jasmine": "~0.1",
26
29
  "karma-chrome-launcher": "~0.1",
27
30
  "karma-phantomjs-launcher": "~0.1",
28
- "karma-junit-reporter": "~0.1"
31
+ "karma-junit-reporter": "~0.1",
32
+ "q": "~0.9.2",
33
+ "q-io": "~1.10.6",
34
+ "qq": "~0.3.5"
29
35
  },
30
36
  "scripts": {
31
37
  "test": "./node_modules/.bin/karma start --single-run --browsers PhantomJS"
@@ -0,0 +1,428 @@
1
+ describe('RailsResource.snapshots', function () {
2
+ 'use strict';
3
+ var Book, $httpBackend, railsResourceFactory, railsSerializer;
4
+
5
+ beforeEach(function () {
6
+ module('rails')
7
+ });
8
+
9
+ beforeEach(inject(function (_$httpBackend_, _railsResourceFactory_, _railsSerializer_) {
10
+ $httpBackend = _$httpBackend_;
11
+ railsResourceFactory = _railsResourceFactory_;
12
+ railsSerializer = _railsSerializer_;
13
+ Book = railsResourceFactory({
14
+ url: '/books',
15
+ name: 'book',
16
+ extensions: ['snapshots']
17
+ });
18
+ }));
19
+
20
+ afterEach(function() {
21
+ $httpBackend.verifyNoOutstandingExpectation();
22
+ $httpBackend.verifyNoOutstandingRequest();
23
+ });
24
+
25
+ it('should store all keys', function () {
26
+ var book, data = {id: 1, $key: '1234', name: 'The Winds of Winter'};
27
+ book = new Book(data);
28
+ expect(book.snapshot()).toBe(0);
29
+
30
+ expect(book.$snapshots).toBeDefined();
31
+ expect(book.$snapshots.length).toBe(1);
32
+ expect(book.$snapshots[0].$snapshots).toBeUndefined();
33
+ expect(book).toEqualData(data);
34
+ expect(book.$snapshots[0].$key).toBe('1234');
35
+ expect(book.$snapshots[0]).toEqualData(data);
36
+ });
37
+
38
+ it('should store deep copy', function () {
39
+ var book, data = {
40
+ id: 1,
41
+ $key: '1234',
42
+ name: 'The Winds of Winter',
43
+ author: {
44
+ id: 1,
45
+ name: 'George R. R. Martin'
46
+ }
47
+ };
48
+
49
+ book = new Book(data);
50
+ book.snapshot();
51
+
52
+ expect(book.$snapshots[0].author).toBeDefined();
53
+ expect(book.$snapshots[0].author.id).toBe(1);
54
+ expect(book.$snapshots[0]).toEqualData(data);
55
+ });
56
+
57
+ it('should store multiple snapshots', function () {
58
+ var book, data = {id: 1, $key: '1234', name: 'The Winds of Winter'};
59
+ book = new Book(data);
60
+ expect(book.snapshot()).toBe(0);
61
+ book.$key = '1235';
62
+ expect(book.snapshot()).toBe(1);
63
+ book.$key = '1236';
64
+ expect(book.snapshot()).toBe(2);
65
+
66
+ expect(book.$snapshots).toBeDefined();
67
+ expect(book.$snapshots.length).toBe(3);
68
+ expect(book.$snapshots[0].$key).toBe('1234');
69
+ expect(book.$snapshots[1].$key).toBe('1235');
70
+ expect(book.$snapshots[2].$key).toBe('1236');
71
+ });
72
+
73
+ it('should rollback single version', function () {
74
+ var book, data = {id: 1, $key: '1234', name: 'The Winds of Winter'};
75
+ book = new Book(data);
76
+ book.snapshot();
77
+ book.$key = '1235';
78
+ book.snapshot();
79
+ book.$key = '1236';
80
+ book.rollback();
81
+
82
+ expect(book.$key).toBe('1235');
83
+ expect(book.$snapshots).toBeDefined();
84
+ expect(book.$snapshots.length).toBe(1);
85
+ });
86
+
87
+ it('should rollback deep copy', function () {
88
+ var book, data = {
89
+ id: 1,
90
+ $key: '1234',
91
+ name: 'The Winds of Winter',
92
+ author: {
93
+ id: 1,
94
+ name: 'George R. R. Martin'
95
+ }
96
+ };
97
+
98
+ book = new Book(data);
99
+ book.snapshot();
100
+ book.author = {id: 2, name: 'Hugh Howey'};
101
+ book.rollback();
102
+
103
+ expect(book.author).toBeDefined();
104
+ expect(book).toEqualData(data);
105
+
106
+ book.snapshot();
107
+ book.author.name = 'Hugh Howey';
108
+ book.rollback();
109
+
110
+ expect(book.author).toBeDefined();
111
+ expect(book).toEqualData(data);
112
+ });
113
+
114
+ it('should not modify source nested object on rollback', function () {
115
+ var book, hughHoweyAuthor = {id: 2, name: 'Hugh Howey'},
116
+ data = {
117
+ id: 1,
118
+ $key: '1234',
119
+ name: 'The Winds of Winter',
120
+ author: {
121
+ id: 1,
122
+ name: 'George R. R. Martin'
123
+ }
124
+ };
125
+
126
+ book = new Book(data);
127
+ book.snapshot();
128
+ book.author = hughHoweyAuthor;
129
+ book.rollback();
130
+
131
+ expect(hughHoweyAuthor).toEqualData({id: 2, name: 'Hugh Howey'});
132
+ });
133
+
134
+
135
+ it('should allow multiple rollbacks', function () {
136
+ var book, data = {id: 1, $key: '1234', name: 'The Winds of Winter'};
137
+ book = new Book(data);
138
+ book.snapshot();
139
+ book.$key = '1235';
140
+ book.snapshot();
141
+ book.$key = '1236';
142
+ book.rollback();
143
+
144
+ expect(book.$key).toBe('1235');
145
+ expect(book.$snapshots).toBeDefined();
146
+ expect(book.$snapshots.length).toBe(1);
147
+ book.rollback();
148
+
149
+ expect(book.$key).toBe('1234');
150
+ expect(book.$snapshots).toBeDefined();
151
+ expect(book.$snapshots.length).toBe(0);
152
+ });
153
+
154
+
155
+ it('should rollback specified number of versions', function () {
156
+ var book, data = {id: 1, $key: '1234', name: 'The Winds of Winter'};
157
+ book = new Book(data);
158
+ book.snapshot();
159
+ book.$key = '1235';
160
+ book.snapshot();
161
+ book.$key = '1236';
162
+ book.snapshot();
163
+ book.$key = '1237';
164
+ book.rollback(2);
165
+
166
+ expect(book.$key).toBe('1235');
167
+ expect(book.$snapshots).toBeDefined();
168
+ expect(book.$snapshots.length).toBe(1);
169
+ });
170
+
171
+ it('should not change resource on rollback if no snapshots saved', function () {
172
+ var book, data = {id: 1, $key: '1234', name: 'The Winds of Winter'};
173
+ book = new Book(data);
174
+ book.$key = '1235';
175
+ book.rollback();
176
+
177
+ expect(book.$key).toBe('1235');
178
+ expect(book.$snapshots).toBeDefined();
179
+ expect(book.$snapshots.length).toBe(0);
180
+ });
181
+
182
+ it('should roll back to the first snapshot for -1', function () {
183
+ var book, data = {id: 1, $key: '1234', name: 'The Winds of Winter'};
184
+ book = new Book(data);
185
+ book.snapshot();
186
+ book.$key = '1235';
187
+ book.snapshot();
188
+ book.$key = '1236';
189
+ book.snapshot();
190
+ book.rollback(-1);
191
+
192
+ expect(book.$key).toBe('1234');
193
+ expect(book.$snapshots).toBeDefined();
194
+ expect(book.$snapshots.length).toBe(0);
195
+ });
196
+
197
+ it('should roll back to the first snapshot when versions exceeds available snapshots', function () {
198
+ var book, data = {id: 1, $key: '1234', name: 'The Winds of Winter'};
199
+ book = new Book(data);
200
+ book.snapshot();
201
+ book.$key = '1235';
202
+ book.snapshot();
203
+ book.$key = '1236';
204
+ book.snapshot();
205
+ book.rollback(1000);
206
+
207
+ expect(book.$key).toBe('1234');
208
+ expect(book.$snapshots).toBeDefined();
209
+ expect(book.$snapshots.length).toBe(0);
210
+ });
211
+
212
+ it('should roll back to version in middle', function () {
213
+ var book, data = {id: 1, $key: '1234', name: 'The Winds of Winter'};
214
+ book = new Book(data);
215
+ book.snapshot();
216
+ book.$key = '1235';
217
+ book.snapshot();
218
+ book.$key = '1236';
219
+ book.snapshot();
220
+ book.rollbackTo(1);
221
+
222
+ expect(book.$key).toBe('1235');
223
+ expect(book.$snapshots).toBeDefined();
224
+ expect(book.$snapshots.length).toBe(1);
225
+ });
226
+
227
+ it('should roll back to first version', function () {
228
+ var book, data = {id: 1, $key: '1234', name: 'The Winds of Winter'};
229
+ book = new Book(data);
230
+ book.snapshot();
231
+ book.$key = '1235';
232
+ book.snapshot();
233
+ book.$key = '1236';
234
+ book.snapshot();
235
+ book.rollbackTo(0);
236
+
237
+ expect(book.$key).toBe('1234');
238
+ expect(book.$snapshots).toBeDefined();
239
+ expect(book.$snapshots.length).toBe(0);
240
+ });
241
+
242
+ it('should roll back to last version when version exceeds available versions', function () {
243
+ var book, data = {id: 1, $key: '1234', name: 'The Winds of Winter'};
244
+ book = new Book(data);
245
+ book.snapshot();
246
+ book.$key = '1235';
247
+ book.snapshot();
248
+ book.$key = '1236';
249
+ book.snapshot();
250
+ book.$key = '1237';
251
+ book.rollbackTo(100);
252
+
253
+ expect(book.$key).toBe('1236');
254
+ expect(book.$snapshots).toBeDefined();
255
+ expect(book.$snapshots.length).toBe(2);
256
+ });
257
+
258
+ it('should reset snapshots on create', function () {
259
+ var book, data = {$key: '1234', name: 'The Winds of Winter'};
260
+ book = new Book(data);
261
+ book.snapshot();
262
+ book.$key = '1235';
263
+
264
+ $httpBackend.expectPOST('/books').respond(200, {book: {id: 1}});
265
+ book.save();
266
+ $httpBackend.flush();
267
+
268
+ expect(book.$key).toBe('1235');
269
+ expect(book.$snapshots).toBeDefined();
270
+ expect(book.$snapshots.length).toBe(0);
271
+ });
272
+
273
+ it('should be able to save after rollback', function () {
274
+ var book, data = {$key: '1234', name: 'The Winds of Winter'};
275
+ book = new Book(data);
276
+ book.snapshot();
277
+ book.$key = '1235';
278
+ book.rollback();
279
+
280
+ $httpBackend.expectPOST('/books').respond(200, {book: {id: 1}});
281
+ book.save();
282
+ $httpBackend.flush();
283
+
284
+ expect(book.$key).toBe('1234');
285
+ expect(book.$snapshots).toBeDefined();
286
+ expect(book.$snapshots.length).toBe(0);
287
+ });
288
+
289
+ it('should reset snapshots on update', function () {
290
+ var book, data = {id: 1, $key: '1234', name: 'The Winds of Winter'};
291
+ book = new Book(data);
292
+ book.snapshot();
293
+ book.$key = '1235';
294
+
295
+ $httpBackend.expectPUT('/books/1').respond(200, {book: {id: 1}});
296
+ book.save();
297
+ $httpBackend.flush();
298
+
299
+ expect(book.$key).toBe('1235');
300
+ expect(book.$snapshots).toBeDefined();
301
+ expect(book.$snapshots.length).toBe(0);
302
+ });
303
+
304
+ it('should reset snapshots on delete', function () {
305
+ var book, data = {id: 1, $key: '1234', name: 'The Winds of Winter'};
306
+ book = new Book(data);
307
+ book.snapshot();
308
+ book.$key = '1235';
309
+
310
+ $httpBackend.expectDELETE('/books/1').respond(200, {book: {id: 1}});
311
+ book.delete();
312
+ $httpBackend.flush();
313
+
314
+ expect(book.$key).toBe('1235');
315
+ expect(book.$snapshots).toBeDefined();
316
+ expect(book.$snapshots.length).toBe(0);
317
+ });
318
+
319
+ it('should call rollback callback on rollback', function () {
320
+ var book, callbackCalled = false, data = {id: 1, $key: '1234', name: 'The Winds of Winter'};
321
+ book = new Book(data);
322
+ book.snapshot(function () {
323
+ callbackCalled = true;
324
+ });
325
+ book.rollback();
326
+ expect(callbackCalled).toBe(true);
327
+ });
328
+
329
+ it('should call correct rollback callback on each rollback', function () {
330
+ var book, firstCallbackCalled = false, secondCallbackCalled = false,
331
+ data = {id: 1, $key: '1234', name: 'The Winds of Winter'};
332
+ book = new Book(data);
333
+ book.snapshot(function () {
334
+ firstCallbackCalled = true;
335
+ });
336
+ book.$key = '1235';
337
+ book.snapshot(function () {
338
+ secondCallbackCalled = true;
339
+ });
340
+ book.$key = '1236';
341
+
342
+ book.rollback();
343
+ expect(book.$key).toBe('1235');
344
+ expect(firstCallbackCalled).toBe(false);
345
+ expect(secondCallbackCalled).toBe(true);
346
+
347
+ book.rollback();
348
+ expect(book.$key).toBe('1234');
349
+ expect(firstCallbackCalled).toBe(true);
350
+ expect(secondCallbackCalled).toBe(true);
351
+ });
352
+
353
+ describe('serializer', function () {
354
+ beforeEach(function () {
355
+ Book.configure({
356
+ serializer: railsSerializer(function () {
357
+ this.exclude('author');
358
+ })
359
+ });
360
+ });
361
+
362
+ it('should exclude author from snapshot and rollback', function () {
363
+ var book, data = {
364
+ id: 1,
365
+ $key: '1234',
366
+ name: 'The Winds of Winter',
367
+ author: {
368
+ id: 1,
369
+ name: 'George R. R. Martin'
370
+ }
371
+ };
372
+
373
+ book = new Book(data);
374
+ book.snapshot();
375
+ book.author.name = 'George Orwell';
376
+
377
+ expect(book.$snapshots[0].author).not.toBeDefined();
378
+ expect(book.author).toEqualData({id: 1, name: 'George Orwell'});
379
+
380
+ book.rollback();
381
+ // should still be George Orwell since it wasn't snapshotted
382
+ expect(book.author).toEqualData({id: 1, name: 'George Orwell'});
383
+ });
384
+
385
+ });
386
+
387
+ describe('snapshotSerializer', function () {
388
+ beforeEach(function () {
389
+ Book.configure({
390
+ serializer: railsSerializer(function () {
391
+ this.exclude('author');
392
+ }),
393
+ snapshotSerializer: railsSerializer(function () {
394
+ this.exclude('$key');
395
+ })
396
+ });
397
+ });
398
+
399
+ it('should include author and exclude $key from snapshot and rollback', function () {
400
+ var book, data = {
401
+ id: 1,
402
+ $key: '1234',
403
+ name: 'The Winds of Winter',
404
+ author: {
405
+ id: 1,
406
+ name: 'George R. R. Martin'
407
+ }
408
+ };
409
+
410
+ book = new Book(data);
411
+ book.snapshot();
412
+ book.$key = '1235';
413
+ book.author.name = 'George Orwell';
414
+
415
+ expect(book.$snapshots[0].author).toBeDefined();
416
+ expect(book.$snapshots[0].$key).not.toBeDefined();
417
+ expect(book.$key).toBe('1235');
418
+ expect(book.author).toEqualData({id: 1, name: 'George Orwell'});
419
+
420
+ book.rollback();
421
+ // should be 1235 since it wasn't snapshotted
422
+ expect(book.$key).toBe('1235');
423
+ // should be George R. R. Martin since it was snapshotted
424
+ expect(book.author).toEqualData({id: 1, name: 'George R. R. Martin'});
425
+ });
426
+
427
+ });
428
+ });