angularjs-rails-resource 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  !binary "U0hBMQ==":
3
3
  metadata.gz: !binary |-
4
- ZjM2MTM3OTRmYjQzZDE1ZGNhZjk1YTM2MDk4ZmUxNTJjMzBmYzBmOA==
4
+ ZGU4OWY0N2I0MGNjN2U0OGQ1OGZmZWE2ODgwYTlhZWIwZGMxOTdjZg==
5
5
  data.tar.gz: !binary |-
6
- NjAyYWZmZGEwNzQ2MjhmODk1OWIyMTRiMWY1NDBmOWQxN2VkMGQ3Ng==
6
+ NmNkNDkxOWRhMzJkNGU0MTVhODFmN2FlZmI1ZmM4NzgxM2NhYmM3Zg==
7
7
  !binary "U0hBNTEy":
8
8
  metadata.gz: !binary |-
9
- MWU4ZDAzMjZhMGM5NTIyZmZlMzY4YjQ3M2I3MzJmMmI1MDI4ZWI2ZjE5NmZh
10
- Njc5NzU0YzNkNjFlYjI2OGM1NzJlNDczOTQxOGU4ZDgwNDgzYzVjZjE2Yzgy
11
- ODQyYWI4NTM3NGYyMWY0MDlmNjkyM2M0ZGQyOWY0NTEwM2E2Njc=
9
+ OGJiNjBiOGYzMjczNTcyZmE2NGZjZDQ5NjJjYjI0Nzk3MTA5YmNiOTk5OGU0
10
+ YmNjYTMzY2RjNzExNzA2YjlmMmYwNGQ3YzgyZmVhYjBkMGEwZGJiOTIwOGE0
11
+ NmY1MzY0MGMyOWZkYTIwNDQyY2RiNmY3NmY1YjBlYzZmNTkzN2Y=
12
12
  data.tar.gz: !binary |-
13
- ODkyMTcyNmZhYjVjYmNlZWM3NTAzNjY4ZDYzYmU0Yjk3NGQxYjQyNzAxMWQy
14
- ODE5NjQ4YmNiMmNhOTRjZGQyOGZjNjZkOTUyYzg3NWI5MmRiYjQ5ZDZjM2Fk
15
- MGY5ZDM2YzZiNGZiZDNlYTdhMjA4M2UyNTZhMTYyMmQ4ODEwM2Q=
13
+ Yzg0YjlhMjJlZDc3ZTdjMmY0NWQxZWUyZTBhMGFmODM5M2Q0ZmRjY2VhNjlk
14
+ ZWEwNWNlN2M3ZWQzOTg4NTQwN2EzZmEzMzc1YWUxY2I1ZGQ4YTQxYjg2ZjE1
15
+ MTMzNDk3MmRhNmRjZTg2MTllNjhhYTg5YjAyMDM4MGFlMjlmOTE=
data/README.md CHANGED
@@ -132,6 +132,7 @@ The following options are available for the config object passed to the factory
132
132
  * **Accept** - application/json
133
133
  * **Content-Type** - application/json
134
134
  * **defaultParams** *(optional)* - If the resource expects a default set of query params on every call you can specify them here.
135
+ * **updateMethod** *(optional)* - Allows overriding the default HTTP method (PUT) used for update. Valid values are "post", "put", or "patch".
135
136
  * **requestTransformers** *(optional) - See [Transformers / Interceptors](#transformers--interceptors)
136
137
  * **responseInterceptors** *(optional)* - See [Transformers / Interceptors](#transformers--interceptors)
137
138
  * **afterResponseInterceptors** *(optional)* - See [Transformers / Interceptors](#transformers--interceptors)
@@ -139,6 +140,24 @@ The following options are available for the config object passed to the factory
139
140
  **NOTE:** The names should be specified using camel case when using the key transformations because that happens before the root wrapping by default.
140
141
  For example, you should specify "publishingCompany" and "publishingCompanies" instead of "publishing_company" and "publishing_companies".
141
142
 
143
+ ### Provider Configuration
144
+ <code>railsResourceFactory</code> can be injected as <code>railsResourceFactoryProvider</code> into your app's config method to configure defaults for all the resources application-wide.
145
+ The individual resource configuration takes precedence over application-wide default configuration values.
146
+ Each configuration option listed is exposed as a method on the provider that takes the configuration value as the parameter and returns the provider to allow method chaining.
147
+
148
+ * enableRootWrapping - {function(boolean):railsSerializerProvider}
149
+ * httpConfig - {function(object):railsSerializerProvider}
150
+ * defaultParams - {function(object):railsSerializerProvider}
151
+ * updateMethod - {function(boolean):railsSerializerProvider}
152
+
153
+ For example, to turn off the root wrapping application-wide and set the update method to PATCH:
154
+
155
+ ````javascript
156
+ app.config(function (railsResourceFactoryProvider) {
157
+ railsResourceFactoryProvider.enableRootWrapping(false).updateMethod('patch');
158
+ );
159
+ ````
160
+
142
161
  ## Resource URLs
143
162
  The URL can be specified as one of three ways:
144
163
 
@@ -259,8 +278,8 @@ AngularJS automatically excludes all attribute keys that begin with $ in their t
259
278
  * **returns** {Serializer} - A Serializer constructor function
260
279
 
261
280
  ### Configuration
262
- The <code>railsSerializer</code> function takes a customizer function that is called on create within the context of the constructed Serializer. From within the customizer function you can call customization functions that affect what gets serialized and how or override the default options.
263
- In addition, <code>railsSerializer</code> exposes a field <code>defaultOptions</code> that allows you to globally override the defaults for the configuration options.
281
+ The <code>railsSerializer</code> function takes a customizer function that is called on create within the context of the constructed Serializer.
282
+ From within the customizer function you can call customization functions that affect what gets serialized and how or override the default options.
264
283
 
265
284
  #### Configuration Options
266
285
  Serializers have the following available configuration options:
@@ -279,13 +298,29 @@ Serializers have the following available configuration options:
279
298
  * parameters
280
299
  * **attribute** {string} - The name as it appeared in the JSON
281
300
  * **returns** {string} - The name as it should appear in the resource
282
- * excludeByDefault {boolean} - Specifies whether or not JSON serialization should exclude all attributes from serialization by default.
283
- * default: false
284
301
  * exclusionMatchers {array} - An list of rules that should be applied to determine whether or not an attribute should be excluded. The values in the array can be one of the following types:
285
302
  * string - Defines a prefix that is used to test for exclusion
286
303
  * RegExp - A custom regular expression that is tested against the attribute name
287
304
  * function - A custom function that accepts a string argument and returns a boolean with true indicating exclusion.
288
305
 
306
+ #### Provider Configuration
307
+ <code>railsSerializer</code> can be injected as <code>railsSerializerProvider</code> into your app's config method to configure defaults for all the serializers application-wide.
308
+ Each configuration option listed is exposed as a method on the provider that takes the configuration value as the parameter and returns the provider to allow method chaining.
309
+
310
+ * underscore - {function(fn):railsSerializerProvider}
311
+ * camelize - {function(fn):railsSerializerProvider}
312
+ * pluralize - {function(fn):railsSerializerProvider}
313
+ * exclusionMatchers - {function(matchers):railsSerializerProvider}
314
+
315
+ For example, to turn off the key renaming from underscore to camel case and vice versa you would do:
316
+
317
+ ````javascript
318
+ app.config(function (railsSerializerProvider) {
319
+ railsSerializerProvider.underscore(function (value) { return value; })
320
+ .camelize(function (value) { return value; });
321
+ );
322
+ ````
323
+
289
324
  #### Customization API
290
325
  The customizer function passed to the railsSerializer has available to it the following methods for altering the serialization of an object. None of these methods support nested attribute names (e.g. <code>'books.publicationDate'</code>), in order to customize the serialization of the <code>books</code> objects you would need to specify a custom serializer for the <code>books</code> attribute.
291
326
 
@@ -5,8 +5,9 @@ Gem::Specification.new do |gem|
5
5
  gem.authors = ["Tommy Odom", "Chris Chase"]
6
6
  gem.email = ["odom@finelineprototyping.com", "chris@finelineprototyping.com"]
7
7
  gem.description = %q{A small AngularJS add-on for integrating with Rails via JSON more easily.}
8
- gem.summary = %q{}
8
+ gem.summary = %q{AngularJS add-on resource add-on for integrating with Rails}
9
9
  gem.homepage = "https://github.com/finelineprototyping/angularjs-rails-resource"
10
+ gem.license = 'MIT'
10
11
 
11
12
  gem.files = `git ls-files`.split($\)
12
13
  gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
@@ -1,7 +1,7 @@
1
1
  module Angularjs
2
2
  module Rails
3
3
  module Resource
4
- VERSION = '0.2.1'
4
+ VERSION = '0.2.2'
5
5
  end
6
6
  end
7
7
  end
@@ -0,0 +1,43 @@
1
+ describe('resource provider factory config', function () {
2
+ 'use strict';
3
+
4
+ it('should allow disabling root wrapping globally', function () {
5
+ module('rails', function (railsResourceFactoryProvider) {
6
+ expect(railsResourceFactoryProvider.enableRootWrapping(false)).toBe(railsResourceFactoryProvider);
7
+ });
8
+
9
+ inject(function (railsResourceFactory) {
10
+ expect(railsResourceFactory({name: 'test', url: '/test'}).enableRootWrapping).toBe(false);
11
+ });
12
+ });
13
+
14
+ it('should allow setting updateMethod globally', function () {
15
+ module('rails', function (railsResourceFactoryProvider) {
16
+ expect(railsResourceFactoryProvider.updateMethod('patch')).toBe(railsResourceFactoryProvider);
17
+ });
18
+
19
+ inject(function (railsResourceFactory) {
20
+ expect(railsResourceFactory({name: 'test', url: '/test'}).updateMethod).toBe('patch');
21
+ });
22
+ });
23
+
24
+ it('should allow setting http headers options globally', function () {
25
+ module('rails', function (railsResourceFactoryProvider) {
26
+ expect(railsResourceFactoryProvider.httpConfig({headers: {'test': "header"}})).toBe(railsResourceFactoryProvider);
27
+ });
28
+
29
+ inject(function (railsResourceFactory) {
30
+ expect(railsResourceFactory({name: 'test', url: '/test'}).httpConfig.headers).toEqualData({'Accept': 'application/json', 'Content-Type': 'application/json', 'test': 'header'});
31
+ });
32
+ });
33
+
34
+ it('should allow setting default query parameters options globally', function () {
35
+ module('rails', function (railsResourceFactoryProvider) {
36
+ expect(railsResourceFactoryProvider.defaultParams({'test': "1"})).toBe(railsResourceFactoryProvider);
37
+ });
38
+
39
+ inject(function (railsResourceFactory) {
40
+ expect(railsResourceFactory({name: 'test', url: '/test'}).defaultParams).toEqualData({'test': '1'});
41
+ });
42
+ });
43
+ });
@@ -228,6 +228,53 @@ describe('railsResourceFactory', function () {
228
228
  expect(data).toEqualData({id: 123, abcDef: 'xyz', xyz: 'abc', extra: 'test'});
229
229
  }));
230
230
 
231
+ it('should be able to create new instance and update it using PATCH', inject(function($httpBackend) {
232
+ var promise, Resource, data, defaultParamsConfig = {};
233
+
234
+ angular.copy(config, defaultParamsConfig);
235
+ defaultParamsConfig.updateMethod = 'patch';
236
+
237
+ Resource = factory(defaultParamsConfig);
238
+ data = new Resource({abcDef: 'xyz'});
239
+
240
+ $httpBackend.expectPOST('/test', {test: {abc_def: 'xyz'}}).respond(200, {test: {id: 123, abc_def: 'xyz'}});
241
+ data.create();
242
+ $httpBackend.flush(1);
243
+
244
+ expect(data).toEqualData({id: 123, abcDef: 'xyz'});
245
+
246
+ $httpBackend.expectPATCH('/test/123', {test: {abc_def: 'xyz', id: 123, xyz: 'abc'}}).respond(200, {test: {id: 123, abc_def: 'xyz', xyz: 'abc', extra: 'test'}});
247
+ data.xyz = 'abc';
248
+ data.update();
249
+ $httpBackend.flush();
250
+
251
+ expect(data).toEqualData({id: 123, abcDef: 'xyz', xyz: 'abc', extra: 'test'});
252
+ }));
253
+
254
+ it('should be able to create new instance and update it using save using PATCH', inject(function($httpBackend) {
255
+ var promise, Resource, data, defaultParamsConfig = {};
256
+
257
+ angular.copy(config, defaultParamsConfig);
258
+ defaultParamsConfig.updateMethod = 'patch';
259
+
260
+ Resource = factory(defaultParamsConfig);
261
+ data = new Resource({abcDef: 'xyz'});
262
+
263
+ $httpBackend.expectPOST('/test', {test: {abc_def: 'xyz'}}).respond(200, {test: {id: 123, abc_def: 'xyz'}});
264
+ data.save();
265
+ $httpBackend.flush(1);
266
+
267
+ expect(data).toEqualData({id: 123, abcDef: 'xyz'});
268
+
269
+ $httpBackend.expectPATCH('/test/123', {test: {abc_def: 'xyz', id: 123, xyz: 'abc'}}).respond(200, {test: {id: 123, abc_def: 'xyz', xyz: 'abc', extra: 'test'}});
270
+ data.xyz = 'abc';
271
+ data.save();
272
+ $httpBackend.flush();
273
+
274
+ expect(data).toEqualData({id: 123, abcDef: 'xyz', xyz: 'abc', extra: 'test'});
275
+ }));
276
+
277
+
231
278
  it('create with default params should add parameter abc=1', inject(function($httpBackend) {
232
279
  var promise, Resource, data, defaultParamsConfig = {};
233
280
 
@@ -1,333 +1,395 @@
1
- describe('railsUrlSerializer', function () {
1
+ describe('railsSerializer', function () {
2
2
  'use strict';
3
- var factory, railsInjector;
4
3
 
5
- function createSerializer(options, customizer) {
6
- return railsInjector.createService(factory(options, customizer));
7
- }
8
-
9
- beforeEach(module('rails'));
10
-
11
- beforeEach(inject(function (railsSerializer, RailsResourceInjector) {
12
- factory = railsSerializer;
13
- railsInjector = RailsResourceInjector;
14
- }));
15
-
16
- it('should support customizer being first parameter', function () {
17
- var called = false;
18
-
19
- createSerializer(function () {
20
- called = true;
4
+ describe('provider config', function () {
5
+ it('should allow overriding underscore method', function () {
6
+ var overrideCalled = false;
7
+
8
+ module('rails', function (railsSerializerProvider) {
9
+ expect(railsSerializerProvider.underscore(function (value) {
10
+ overrideCalled = true;
11
+ return value;
12
+ })).toBe(railsSerializerProvider);
13
+ });
14
+
15
+ inject(function (railsSerializer, RailsResourceInjector) {
16
+ var test = {id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin'};
17
+ expect(RailsResourceInjector.createService(railsSerializer()).serialize(test)).toEqualData(test);
18
+ expect(overrideCalled).toBeTruthy();
19
+ });
21
20
  });
22
21
 
23
- expect(called).toBeTruthy();
24
- });
25
-
26
- it('should support customizer with options as first parameter', function () {
27
- var called = false;
28
-
29
- createSerializer({}, function () {
30
- called = true;
22
+ it('should allow overriding camelize method', function () {
23
+ var overrideCalled = false;
24
+
25
+ module('rails', function (railsSerializerProvider) {
26
+ expect(railsSerializerProvider.camelize(function (value) {
27
+ overrideCalled = true;
28
+ return value;
29
+ })).toBe(railsSerializerProvider);
30
+ });
31
+
32
+ inject(function (railsSerializer, RailsResourceInjector) {
33
+ var test = {id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin'};
34
+ expect(RailsResourceInjector.createService(railsSerializer()).deserialize(test)).toEqualData(test);
35
+ expect(overrideCalled).toBeTruthy();
36
+ });
31
37
  });
32
38
 
33
- expect(called).toBeTruthy();
39
+ it('should allow overriding pluralize method', function () {
40
+ module('rails', function (railsSerializerProvider) {
41
+ expect(railsSerializerProvider.pluralize(function (value) {
42
+ return value + 'ies';
43
+ })).toBe(railsSerializerProvider);
44
+ });
34
45
 
35
- });
36
-
37
- describe('default config', function () {
38
- var serializer;
39
-
40
- beforeEach(function () {
41
- serializer = createSerializer();
42
- });
43
-
44
- it('should underscore attributes on single object', function () {
45
- var orig = {id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin'},
46
- result = serializer.serialize(orig);
47
- expect(result).toEqualData({id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin'});
48
- result = serializer.deserialize(result);
49
- expect(result).toEqualData(orig);
46
+ inject(function (railsSerializer, RailsResourceInjector) {
47
+ expect(RailsResourceInjector.createService(railsSerializer()).pluralize('cook')).toEqual('cookies');
48
+ });
50
49
  });
51
50
 
52
- it('should underscore attributes on nested objects', function () {
53
- var orig = {id: 6, title: 'Winds of Winter', pages: 1105, publicationDate: '2020-05-25', author: {id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin'}},
54
- result = serializer.serialize(orig);
55
- expect(result).toEqualData({id: 6, title: 'Winds of Winter', pages: 1105, publication_date: '2020-05-25', author: {id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin'}});
56
- result = serializer.deserialize(result);
57
- expect(result).toEqualData(orig);
58
- });
59
-
60
- it('should underscore attribute inside array objects', function () {
61
- var orig = {id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin', books: [
62
- {id: 1, title: 'A Game of Thrones', publicationDate: '1996-08-06'}
63
- ]},
64
- result = serializer.serialize(orig);
65
- expect(result).toEqualData({id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin', books: [
66
- {id: 1, title: 'A Game of Thrones', publication_date: '1996-08-06'}
67
- ]});
68
- result = serializer.deserialize(result);
69
- expect(result).toEqualData(orig);
70
- });
51
+ it('should allow overriding exclusionMatchers method', function () {
52
+ module('rails', function (railsSerializerProvider) {
53
+ expect(railsSerializerProvider.exclusionMatchers(['_'])).toBe(railsSerializerProvider);
54
+ });
71
55
 
72
- it('should support primitive arrays', function () {
73
- var orig = {id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin', books: [1, 2, 3]},
74
- result = serializer.serialize(orig);
75
- expect(result).toEqualData({id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin', books: [1, 2, 3]});
76
- result = serializer.deserialize(result);
77
- expect(result).toEqualData(orig);
56
+ inject(function (railsSerializer, RailsResourceInjector) {
57
+ var test = {id: 1, _firstName: 'George', _middleName: 'R. R.', lastName: 'Martin'};
58
+ expect(RailsResourceInjector.createService(railsSerializer()).serialize(test)).toEqualData({id: 1, last_name: 'Martin'});
59
+ });
78
60
  });
79
-
80
- it('should exclude attributes that start with $', function () {
81
- var result = serializer.serialize({id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin', $birthDate: '1948-09-20'});
82
- expect(result).toEqualData({id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin'});
83
- result = serializer.deserialize({id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin', $birth_date: '1948-09-20'});
84
- expect(result).toEqualData({id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin'});
85
- });
86
-
87
- it('should exclude functions', function () {
88
- var result = serializer.serialize({id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin', $books: [], getNumBooks: function () {
89
- this.$books.length
90
- }});
91
- expect(result).toEqualData({id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin'});
92
- });
93
-
94
61
  });
95
62
 
96
- describe('custom options', function () {
97
- it('should allow overriding attribute transformation functions with undefined', function () {
98
- var test,
99
- serializer = createSerializer({underscore: undefined, camelize: undefined});
100
-
101
- test = {id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin'};
102
- expect(serializer.serialize(test)).toEqualData(test);
103
- test = {id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin'};
104
- expect(serializer.deserialize(test)).toEqualData(test);
105
- });
63
+ describe('default provider options', function () {
64
+ var factory, railsInjector;
106
65
 
107
- it('should allow overriding attribute transformation with custom function', function () {
108
- var result,
109
- serializer = createSerializer({
110
- underscore: function (attribute) {
111
- return 'x' + attribute
112
- },
113
- camelize: function (attribute) {
114
- return 'y' + attribute
115
- }
116
- });
66
+ function createSerializer(options, customizer) {
67
+ return railsInjector.createService(factory(options, customizer));
68
+ }
117
69
 
118
- result = serializer.serialize({id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin'});
119
- expect(result).toEqualData({xid: 1, xfirstName: 'George', xmiddleName: 'R. R.', xlastName: 'Martin'});
120
- result = serializer.deserialize({id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin'});
121
- expect(result).toEqualData({yid: 1, yfirst_name: 'George', ymiddle_name: 'R. R.', ylast_name: 'Martin'});
122
- });
70
+ beforeEach(module('rails'));
123
71
 
124
- it('should allow safely ignore null excludePrefixes', function () {
125
- var result, underscored, camelized,
126
- serializer = createSerializer({exclusionMatchers: null});
72
+ beforeEach(inject(function (railsSerializer, RailsResourceInjector) {
73
+ factory = railsSerializer;
74
+ railsInjector = RailsResourceInjector;
75
+ }));
127
76
 
128
- camelized = {id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin', $birthDate: '1948-09-20'};
129
- underscored = {id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin', $birth_date: '1948-09-20'};
130
- result = serializer.serialize(camelized);
131
- expect(result).toEqualData(underscored);
132
- result = serializer.deserialize(underscored);
133
- expect(result).toEqualData(camelized);
134
- });
77
+ describe('default config', function () {
78
+ var serializer;
135
79
 
136
- it('should allow safely ignore undefined excludePrefixes', function () {
137
- var result, underscored, camelized,
138
- serializer = createSerializer({exclusionMatchers: undefined});
80
+ beforeEach(function () {
81
+ serializer = createSerializer();
82
+ });
139
83
 
140
- camelized = {id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin', $birthDate: '1948-09-20'};
141
- underscored = {id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin', $birth_date: '1948-09-20'};
142
- result = serializer.serialize(camelized);
143
- expect(result).toEqualData(underscored);
144
- result = serializer.deserialize(underscored);
145
- expect(result).toEqualData(camelized);
146
- });
84
+ it('should support customizer being first parameter', function () {
85
+ var called = false;
147
86
 
148
- it('should allow empty excludePrefixes', function () {
149
- var result, underscored, camelized,
150
- serializer = createSerializer({exclusionMatchers: []});
87
+ createSerializer(function () {
88
+ called = true;
89
+ });
151
90
 
152
- camelized = {id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin', $birthDate: '1948-09-20'};
153
- underscored = {id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin', $birth_date: '1948-09-20'};
154
- result = serializer.serialize(camelized);
155
- expect(result).toEqualData(underscored);
156
- result = serializer.deserialize(underscored);
157
- expect(result).toEqualData(camelized);
158
- });
91
+ expect(called).toBeTruthy();
92
+ });
159
93
 
160
- it('should treat exclusionMatcher strings as prefix exclusions', function () {
161
- var result,
162
- serializer = createSerializer({exclusionMatchers: ['x']});
94
+ it('should support customizer with options as first parameter', function () {
95
+ var called = false;
163
96
 
164
- result = serializer.serialize({xid: 1, firstNamex: 'George', middleName: 'R. R.', lastName: 'Martin', $birthDate: '1948-09-20'});
165
- expect(result).toEqualData({first_namex: 'George', middle_name: 'R. R.', last_name: 'Martin', $birth_date: '1948-09-20'});
166
- result = serializer.deserialize({xid: 1, first_namex: 'George', middle_name: 'R. R.', last_name: 'Martin', $birth_date: '1948-09-20'});
167
- expect(result).toEqualData({xid: 1, firstNamex: 'George', middleName: 'R. R.', lastName: 'Martin', $birthDate: '1948-09-20'});
168
- });
97
+ createSerializer({}, function () {
98
+ called = true;
99
+ });
169
100
 
170
- it('should use combination of string prefix, function, and regexp for exclusions', function () {
171
- var result,
172
- serializer = createSerializer({exclusionMatchers: ['x', /^$/, function (key) {
173
- return key === 'middleName';
174
- }]});
101
+ expect(called).toBeTruthy();
102
+
103
+ });
104
+
105
+ it('should underscore attributes on single object', function () {
106
+ var orig = {id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin'},
107
+ result = serializer.serialize(orig);
108
+ expect(result).toEqualData({id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin'});
109
+ result = serializer.deserialize(result);
110
+ expect(result).toEqualData(orig);
111
+ });
112
+
113
+ it('should underscore attributes on nested objects', function () {
114
+ var orig = {id: 6, title: 'Winds of Winter', pages: 1105, publicationDate: '2020-05-25', author: {id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin'}},
115
+ result = serializer.serialize(orig);
116
+ expect(result).toEqualData({id: 6, title: 'Winds of Winter', pages: 1105, publication_date: '2020-05-25', author: {id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin'}});
117
+ result = serializer.deserialize(result);
118
+ expect(result).toEqualData(orig);
119
+ });
120
+
121
+ it('should underscore attribute inside array objects', function () {
122
+ var orig = {id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin', books: [
123
+ {id: 1, title: 'A Game of Thrones', publicationDate: '1996-08-06'}
124
+ ]},
125
+ result = serializer.serialize(orig);
126
+ expect(result).toEqualData({id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin', books: [
127
+ {id: 1, title: 'A Game of Thrones', publication_date: '1996-08-06'}
128
+ ]});
129
+ result = serializer.deserialize(result);
130
+ expect(result).toEqualData(orig);
131
+ });
132
+
133
+ it('should support primitive arrays', function () {
134
+ var orig = {id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin', books: [1, 2, 3]},
135
+ result = serializer.serialize(orig);
136
+ expect(result).toEqualData({id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin', books: [1, 2, 3]});
137
+ result = serializer.deserialize(result);
138
+ expect(result).toEqualData(orig);
139
+ });
140
+
141
+ it('should exclude attributes that start with $', function () {
142
+ var result = serializer.serialize({id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin', $birthDate: '1948-09-20'});
143
+ expect(result).toEqualData({id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin'});
144
+ result = serializer.deserialize({id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin', $birth_date: '1948-09-20'});
145
+ expect(result).toEqualData({id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin'});
146
+ });
147
+
148
+ it('should exclude functions', function () {
149
+ var result = serializer.serialize({id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin', $books: [], getNumBooks: function () {
150
+ this.$books.length
151
+ }});
152
+ expect(result).toEqualData({id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin'});
153
+ });
175
154
 
176
- result = serializer.serialize({xid: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin', $birthDate: '1948-09-20'});
177
- expect(result).toEqualData({first_name: 'George', last_name: 'Martin'});
178
- result = serializer.deserialize({xid: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin', $birth_date: '1948-09-20'});
179
- expect(result).toEqualData({xid: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin', $birth_date: '1948-09-20'});
180
155
  });
181
- });
182
156
 
183
- describe('customized serialization', function () {
184
- var camelizedAuthor = {
185
- id: 1,
186
- firstName: 'George',
187
- middleName: 'R. R.',
188
- lastName: 'Martin',
189
- birthDate: '1948-09-20',
190
- books: [
191
- {id: 1, title: 'A Game of Thrones', pages: 694, series: 'A Song of Ice and Fire', publicationDate: '1996-08-06', authorId: 1},
192
- {id: 2, title: 'A Clash of Kings', pages: 768, series: 'A Song of Ice and Fire', publicationDate: '1999-03-01', authorId: 1},
193
- ]
194
- },
195
- underscoredAuthor = {
196
- id: 1,
197
- first_name: 'George',
198
- middle_name: 'R. R.',
199
- last_name: 'Martin',
200
- birth_date: '1948-09-20',
201
- books: [
202
- {id: 1, title: 'A Game of Thrones', pages: 694, series: 'A Song of Ice and Fire', publication_date: '1996-08-06', author_id: 1},
203
- {id: 2, title: 'A Clash of Kings', pages: 768, series: 'A Song of Ice and Fire', publication_date: '1999-03-01', author_id: 1},
204
- ]
205
- };
206
-
207
- it('should allow single exclusion', function () {
208
- var result,
209
- serializer = createSerializer(function (config) {
210
- config.exclude('books');
211
- });
157
+ describe('custom options', function () {
158
+ it('should allow overriding attribute transformation functions with undefined', function () {
159
+ var test,
160
+ serializer = createSerializer({underscore: undefined, camelize: undefined});
161
+
162
+ test = {id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin'};
163
+ expect(serializer.serialize(test)).toEqualData(test);
164
+ test = {id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin'};
165
+ expect(serializer.deserialize(test)).toEqualData(test);
166
+ });
167
+
168
+ it('should allow overriding attribute transformation with custom function', function () {
169
+ var result,
170
+ serializer = createSerializer({
171
+ underscore: function (attribute) {
172
+ return 'x' + attribute
173
+ },
174
+ camelize: function (attribute) {
175
+ return 'y' + attribute
176
+ }
177
+ });
212
178
 
213
- result = serializer.serialize(camelizedAuthor);
214
- expect(result).toEqualData({id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin', birth_date: '1948-09-20'});
215
- result = serializer.deserialize(underscoredAuthor);
216
- expect(result).toEqualData(camelizedAuthor);
179
+ result = serializer.serialize({id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin'});
180
+ expect(result).toEqualData({xid: 1, xfirstName: 'George', xmiddleName: 'R. R.', xlastName: 'Martin'});
181
+ result = serializer.deserialize({id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin'});
182
+ expect(result).toEqualData({yid: 1, yfirst_name: 'George', ymiddle_name: 'R. R.', ylast_name: 'Martin'});
183
+ });
184
+
185
+ it('should allow safely ignore null excludePrefixes', function () {
186
+ var result, underscored, camelized,
187
+ serializer = createSerializer({exclusionMatchers: null});
188
+
189
+ camelized = {id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin', $birthDate: '1948-09-20'};
190
+ underscored = {id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin', $birth_date: '1948-09-20'};
191
+ result = serializer.serialize(camelized);
192
+ expect(result).toEqualData(underscored);
193
+ result = serializer.deserialize(underscored);
194
+ expect(result).toEqualData(camelized);
195
+ });
196
+
197
+ it('should allow safely ignore undefined excludePrefixes', function () {
198
+ var result, underscored, camelized,
199
+ serializer = createSerializer({exclusionMatchers: undefined});
200
+
201
+ camelized = {id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin', $birthDate: '1948-09-20'};
202
+ underscored = {id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin', $birth_date: '1948-09-20'};
203
+ result = serializer.serialize(camelized);
204
+ expect(result).toEqualData(underscored);
205
+ result = serializer.deserialize(underscored);
206
+ expect(result).toEqualData(camelized);
207
+ });
208
+
209
+ it('should allow empty excludePrefixes', function () {
210
+ var result, underscored, camelized,
211
+ serializer = createSerializer({exclusionMatchers: []});
212
+
213
+ camelized = {id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin', $birthDate: '1948-09-20'};
214
+ underscored = {id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin', $birth_date: '1948-09-20'};
215
+ result = serializer.serialize(camelized);
216
+ expect(result).toEqualData(underscored);
217
+ result = serializer.deserialize(underscored);
218
+ expect(result).toEqualData(camelized);
219
+ });
220
+
221
+ it('should treat exclusionMatcher strings as prefix exclusions', function () {
222
+ var result,
223
+ serializer = createSerializer({exclusionMatchers: ['x']});
224
+
225
+ result = serializer.serialize({xid: 1, firstNamex: 'George', middleName: 'R. R.', lastName: 'Martin', $birthDate: '1948-09-20'});
226
+ expect(result).toEqualData({first_namex: 'George', middle_name: 'R. R.', last_name: 'Martin', $birth_date: '1948-09-20'});
227
+ result = serializer.deserialize({xid: 1, first_namex: 'George', middle_name: 'R. R.', last_name: 'Martin', $birth_date: '1948-09-20'});
228
+ expect(result).toEqualData({xid: 1, firstNamex: 'George', middleName: 'R. R.', lastName: 'Martin', $birthDate: '1948-09-20'});
229
+ });
230
+
231
+ it('should use combination of string prefix, function, and regexp for exclusions', function () {
232
+ var result,
233
+ serializer = createSerializer({exclusionMatchers: ['x', /^$/, function (key) {
234
+ return key === 'middleName';
235
+ }]});
236
+
237
+ result = serializer.serialize({xid: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin', $birthDate: '1948-09-20'});
238
+ expect(result).toEqualData({first_name: 'George', last_name: 'Martin'});
239
+ result = serializer.deserialize({xid: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin', $birth_date: '1948-09-20'});
240
+ expect(result).toEqualData({xid: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin', $birth_date: '1948-09-20'});
241
+ });
217
242
  });
218
243
 
219
- it('should allow variable exclusions', function () {
220
- var result,
221
- serializer = createSerializer(function (config) {
222
- config.exclude('books', 'birthDate');
223
- });
244
+ describe('customized serialization', function () {
245
+ var camelizedAuthor = {
246
+ id: 1,
247
+ firstName: 'George',
248
+ middleName: 'R. R.',
249
+ lastName: 'Martin',
250
+ birthDate: '1948-09-20',
251
+ books: [
252
+ {id: 1, title: 'A Game of Thrones', pages: 694, series: 'A Song of Ice and Fire', publicationDate: '1996-08-06', authorId: 1},
253
+ {id: 2, title: 'A Clash of Kings', pages: 768, series: 'A Song of Ice and Fire', publicationDate: '1999-03-01', authorId: 1},
254
+ ]
255
+ },
256
+ underscoredAuthor = {
257
+ id: 1,
258
+ first_name: 'George',
259
+ middle_name: 'R. R.',
260
+ last_name: 'Martin',
261
+ birth_date: '1948-09-20',
262
+ books: [
263
+ {id: 1, title: 'A Game of Thrones', pages: 694, series: 'A Song of Ice and Fire', publication_date: '1996-08-06', author_id: 1},
264
+ {id: 2, title: 'A Clash of Kings', pages: 768, series: 'A Song of Ice and Fire', publication_date: '1999-03-01', author_id: 1},
265
+ ]
266
+ };
267
+
268
+ it('should allow single exclusion', function () {
269
+ var result,
270
+ serializer = createSerializer(function (config) {
271
+ config.exclude('books');
272
+ });
224
273
 
225
- result = serializer.serialize(camelizedAuthor);
226
- expect(result).toEqualData({id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin'});
227
- result = serializer.deserialize(underscoredAuthor);
228
- expect(result).toEqualData(camelizedAuthor);
229
- });
274
+ result = serializer.serialize(camelizedAuthor);
275
+ expect(result).toEqualData({id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin', birth_date: '1948-09-20'});
276
+ result = serializer.deserialize(underscoredAuthor);
277
+ expect(result).toEqualData(camelizedAuthor);
278
+ });
230
279
 
231
- it('should allow renaming attributes', function () {
232
- var result,
233
- serializer = createSerializer(function (config) {
234
- // this & config should be interchangeable
235
- this.exclude('books', 'birthDate');
236
- this.rename('id', 'authorId');
237
- this.rename('firstName', 'first');
238
- this.rename('middleName', 'middle');
239
- config.rename('lastName', 'last');
240
- });
280
+ it('should allow variable exclusions', function () {
281
+ var result,
282
+ serializer = createSerializer(function (config) {
283
+ config.exclude('books', 'birthDate');
284
+ });
241
285
 
242
- result = serializer.serialize(camelizedAuthor);
243
- expect(result).toEqualData({author_id: 1, first: 'George', middle: 'R. R.', last: 'Martin'});
244
- result = serializer.deserialize({author_id: 1, first: 'George', middle: 'R. R.', last: 'Martin'});
245
- expect(result).toEqualData({id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin'});
246
- });
286
+ result = serializer.serialize(camelizedAuthor);
287
+ expect(result).toEqualData({id: 1, first_name: 'George', middle_name: 'R. R.', last_name: 'Martin'});
288
+ result = serializer.deserialize(underscoredAuthor);
289
+ expect(result).toEqualData(camelizedAuthor);
290
+ });
291
+
292
+ it('should allow renaming attributes', function () {
293
+ var result,
294
+ serializer = createSerializer(function (config) {
295
+ // this & config should be interchangeable
296
+ this.exclude('books', 'birthDate');
297
+ this.rename('id', 'authorId');
298
+ this.rename('firstName', 'first');
299
+ this.rename('middleName', 'middle');
300
+ config.rename('lastName', 'last');
301
+ });
247
302
 
248
- it('should allow nested attributes', function () {
249
- var result,
250
- serializer = createSerializer(function () {
251
- this.nestedAttribute('books')
252
- });
303
+ result = serializer.serialize(camelizedAuthor);
304
+ expect(result).toEqualData({author_id: 1, first: 'George', middle: 'R. R.', last: 'Martin'});
305
+ result = serializer.deserialize({author_id: 1, first: 'George', middle: 'R. R.', last: 'Martin'});
306
+ expect(result).toEqualData({id: 1, firstName: 'George', middleName: 'R. R.', lastName: 'Martin'});
307
+ });
253
308
 
254
- result = serializer.serialize(camelizedAuthor);
255
- expect(result['books_attributes']).toEqualData([
256
- {id: 1, title: 'A Game of Thrones', pages: 694, series: 'A Song of Ice and Fire', publication_date: '1996-08-06', author_id: 1},
257
- {id: 2, title: 'A Clash of Kings', pages: 768, series: 'A Song of Ice and Fire', publication_date: '1999-03-01', author_id: 1}
258
- ]);
259
- result = serializer.deserialize(underscoredAuthor);
260
- expect(result).toEqualData(camelizedAuthor);
261
- });
309
+ it('should allow nested attributes', function () {
310
+ var result,
311
+ serializer = createSerializer(function () {
312
+ this.nestedAttribute('books')
313
+ });
262
314
 
263
- it('should add custom attribute from function', function () {
264
- var result,
265
- serializer = createSerializer(function () {
266
- this.add('numBooks', function (author) {
267
- return author.books.length;
315
+ result = serializer.serialize(camelizedAuthor);
316
+ expect(result['books_attributes']).toEqualData([
317
+ {id: 1, title: 'A Game of Thrones', pages: 694, series: 'A Song of Ice and Fire', publication_date: '1996-08-06', author_id: 1},
318
+ {id: 2, title: 'A Clash of Kings', pages: 768, series: 'A Song of Ice and Fire', publication_date: '1999-03-01', author_id: 1}
319
+ ]);
320
+ result = serializer.deserialize(underscoredAuthor);
321
+ expect(result).toEqualData(camelizedAuthor);
322
+ });
323
+
324
+ it('should add custom attribute from function', function () {
325
+ var result,
326
+ serializer = createSerializer(function () {
327
+ this.add('numBooks', function (author) {
328
+ return author.books.length;
329
+ });
268
330
  });
269
- });
270
331
 
271
- result = serializer.serialize(camelizedAuthor);
272
- expect(result['num_books']).toBe(2);
273
- });
332
+ result = serializer.serialize(camelizedAuthor);
333
+ expect(result['num_books']).toBe(2);
334
+ });
274
335
 
275
- it('should add custom attribute from constant value', function () {
276
- var result,
277
- serializer = createSerializer(function () {
278
- this.add('numBooks', 2);
279
- });
336
+ it('should add custom attribute from constant value', function () {
337
+ var result,
338
+ serializer = createSerializer(function () {
339
+ this.add('numBooks', 2);
340
+ });
280
341
 
281
- result = serializer.serialize(camelizedAuthor);
282
- expect(result['num_books']).toBe(2);
283
- });
342
+ result = serializer.serialize(camelizedAuthor);
343
+ expect(result['num_books']).toBe(2);
344
+ });
284
345
 
285
- it('should use custom serializer for books', function () {
286
- var result, serializedBooks, underscored,
287
- serializer = createSerializer(function () {
288
- this.serializeWith('books', factory(function () {
289
- this.rename('publicationDate', 'published');
290
- }));
291
- });
346
+ it('should use custom serializer for books', function () {
347
+ var result, serializedBooks, underscored,
348
+ serializer = createSerializer(function () {
349
+ this.serializeWith('books', factory(function () {
350
+ this.rename('publicationDate', 'published');
351
+ }));
352
+ });
292
353
 
293
- result = serializer.serialize(camelizedAuthor);
294
- serializedBooks = [
295
- {id: 1, title: 'A Game of Thrones', pages: 694, series: 'A Song of Ice and Fire', published: '1996-08-06', author_id: 1},
296
- {id: 2, title: 'A Clash of Kings', pages: 768, series: 'A Song of Ice and Fire', published: '1999-03-01', author_id: 1}
297
- ];
298
-
299
- expect(result['books']).toEqualData(serializedBooks);
300
- underscored = angular.copy(underscoredAuthor);
301
- underscored['books'] = serializedBooks;
302
- result = serializer.deserialize(underscored);
303
- expect(result).toEqualData(camelizedAuthor);
354
+ result = serializer.serialize(camelizedAuthor);
355
+ serializedBooks = [
356
+ {id: 1, title: 'A Game of Thrones', pages: 694, series: 'A Song of Ice and Fire', published: '1996-08-06', author_id: 1},
357
+ {id: 2, title: 'A Clash of Kings', pages: 768, series: 'A Song of Ice and Fire', published: '1999-03-01', author_id: 1}
358
+ ];
359
+
360
+ expect(result['books']).toEqualData(serializedBooks);
361
+ underscored = angular.copy(underscoredAuthor);
362
+ underscored['books'] = serializedBooks;
363
+ result = serializer.deserialize(underscored);
364
+ expect(result).toEqualData(camelizedAuthor);
365
+ });
304
366
  });
305
- });
306
367
 
307
- describe('default exclusion serialization', function () {
308
- it('should only serialize id', function () {
309
- var result,
310
- serializer = createSerializer(function (config) {
311
- // this & config should be interchangeable
312
- this.only('id');
313
- });
368
+ describe('default exclusion serialization', function () {
369
+ it('should only serialize id', function () {
370
+ var result,
371
+ serializer = createSerializer(function (config) {
372
+ // this & config should be interchangeable
373
+ this.only('id');
374
+ });
314
375
 
315
- result = serializer.serialize({id: 1, first: 'George', middle: 'R. R.', last: 'Martin'});
316
- expect(result).toEqualData({id: 1});
317
- result = serializer.deserialize({id: 1, first: 'George', middle: 'R. R.', last: 'Martin'});
318
- expect(result).toEqualData({id: 1, first: 'George', middle: 'R. R.', last: 'Martin'});
319
- });
376
+ result = serializer.serialize({id: 1, first: 'George', middle: 'R. R.', last: 'Martin'});
377
+ expect(result).toEqualData({id: 1});
378
+ result = serializer.deserialize({id: 1, first: 'George', middle: 'R. R.', last: 'Martin'});
379
+ expect(result).toEqualData({id: 1, first: 'George', middle: 'R. R.', last: 'Martin'});
380
+ });
320
381
 
321
- it('should only serialize id and last', function () {
322
- var result,
323
- serializer = createSerializer(function (config) {
324
- this.only('id', 'last');
325
- });
382
+ it('should only serialize id and last', function () {
383
+ var result,
384
+ serializer = createSerializer(function (config) {
385
+ this.only('id', 'last');
386
+ });
326
387
 
327
- result = serializer.serialize({id: 1, first: 'George', middle: 'R. R.', last: 'Martin'});
328
- expect(result).toEqualData({id: 1, last: 'Martin'});
329
- result = serializer.deserialize({id: 1, first: 'George', middle: 'R. R.', last: 'Martin'});
330
- expect(result).toEqualData({id: 1, first: 'George', middle: 'R. R.', last: 'Martin'});
388
+ result = serializer.serialize({id: 1, first: 'George', middle: 'R. R.', last: 'Martin'});
389
+ expect(result).toEqualData({id: 1, last: 'Martin'});
390
+ result = serializer.deserialize({id: 1, first: 'George', middle: 'R. R.', last: 'Martin'});
391
+ expect(result).toEqualData({id: 1, first: 'George', middle: 'R. R.', last: 'Martin'});
392
+ });
331
393
  });
332
394
  });
333
395
  });