Skip to content

Commit 0c0b103

Browse files
author
Robert-Jan Huijsman
authored
Add a toJSON() method to database.DeltaSnapshot, to unbreak our build (#118)
Add a toJSON() method to database.DeltaSnapshot, to unbreak our build after the release of firebase-admin 4.1.2.
1 parent 97df8b7 commit 0c0b103

File tree

2 files changed

+63
-44
lines changed

2 files changed

+63
-44
lines changed

spec/providers/database.spec.ts

Lines changed: 50 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,8 @@
2323
import * as database from '../../src/providers/database';
2424
import { expect as expect } from 'chai';
2525
import { fakeConfig } from '../support/helpers';
26-
import {apps as appsNamespace} from '../../src/apps';
27-
import {config} from '../../src/index';
26+
import { apps as appsNamespace } from '../../src/apps';
27+
import { config } from '../../src/index';
2828

2929
describe('DatabaseBuilder', () => {
3030

@@ -53,13 +53,13 @@ describe('DatabaseBuilder', () => {
5353

5454
it('should return a handler that emits events with a proper DeltaSnapshot', () => {
5555
let handler = database.ref('/users/{id}').onWrite(event => {
56-
expect(event.data.val()).to.deep.equal({foo: 'bar'});
56+
expect(event.data.val()).to.deep.equal({ foo: 'bar' });
5757
});
5858

5959
return handler({
6060
data: {
6161
data: null,
62-
delta: {foo: 'bar'},
62+
delta: { foo: 'bar' },
6363
},
6464
resource: 'projects/_/instances/subdomains/refs/users',
6565
} as any);
@@ -90,87 +90,87 @@ describe('DeltaSnapshot', () => {
9090

9191
let populate = (old: any, change: any) => {
9292
subject = new database.DeltaSnapshot(
93-
apps.admin,
94-
apps.admin,
95-
old,
96-
change,
97-
database.resourceToPath('projects/_/instances/mySubdomain/refs/foo')
98-
);
93+
apps.admin,
94+
apps.admin,
95+
old,
96+
change,
97+
database.resourceToPath('projects/_/instances/mySubdomain/refs/foo')
98+
);
9999
};
100100

101101
describe('#val(): any', () => {
102102
it('should return child values based on the child path', () => {
103-
populate({a: {b: 'c'}}, {a: {d: 'e'}});
104-
expect(subject.child('a').val()).to.deep.equal({b: 'c', d: 'e'});
103+
populate({ a: { b: 'c' } }, { a: { d: 'e' } });
104+
expect(subject.child('a').val()).to.deep.equal({ b: 'c', d: 'e' });
105105
});
106106

107107
it('should return null for children past a leaf', () => {
108-
populate({a: 23}, {b: 33});
108+
populate({ a: 23 }, { b: 33 });
109109
expect(subject.child('a/b').val()).to.be.null;
110110
expect(subject.child('b/c').val()).to.be.null;
111111
});
112112

113113
it('should return a leaf value', () => {
114114
populate(null, 23);
115115
expect(subject.val()).to.eq(23);
116-
populate({a: 23}, {b: 23, a: null});
116+
populate({ a: 23 }, { b: 23, a: null });
117117
expect(subject.child('b').val()).to.eq(23);
118118
});
119119

120-
it ('should coerce object into array if all keys are integers', () => {
121-
populate(null, {0: 'a', 1: 'b', 2: {c: 'd'}});
122-
expect(subject.val()).to.deep.equal(['a', 'b', {c: 'd'}]);
123-
populate(null, {0: 'a', 2: 'b', 3: {c: 'd'}});
124-
expect(subject.val()).to.deep.equal(['a', ,'b', {c: 'd'}]);
125-
populate(null, {'foo': {0: 'a', 1: 'b'}});
126-
expect(subject.val()).to.deep.equal({foo: ['a', 'b']});
120+
it('should coerce object into array if all keys are integers', () => {
121+
populate(null, { 0: 'a', 1: 'b', 2: { c: 'd' } });
122+
expect(subject.val()).to.deep.equal(['a', 'b', { c: 'd' }]);
123+
populate(null, { 0: 'a', 2: 'b', 3: { c: 'd' } });
124+
expect(subject.val()).to.deep.equal(['a', , 'b', { c: 'd' }]);
125+
populate(null, { 'foo': { 0: 'a', 1: 'b' } });
126+
expect(subject.val()).to.deep.equal({ foo: ['a', 'b'] });
127127
});
128128

129129
// Regression test: zero-values (including children) were accidentally forwarded as 'null'.
130-
it ('should deal with zero-values appropriately', () => {
130+
it('should deal with zero-values appropriately', () => {
131131
populate(null, 0);
132132
expect(subject.val()).to.equal(0);
133-
populate(null, {myKey: 0});
134-
expect(subject.val()).to.deep.equal({myKey: 0});
133+
populate(null, { myKey: 0 });
134+
expect(subject.val()).to.deep.equal({ myKey: 0 });
135135

136136
// Null values are still reported as null.
137-
populate({myKey: 'foo', myOtherKey: 'bar'}, {myKey: null});
138-
expect(subject.val()).to.deep.equal({myOtherKey: 'bar'});
137+
populate({ myKey: 'foo', myOtherKey: 'bar' }, { myKey: null });
138+
expect(subject.val()).to.deep.equal({ myOtherKey: 'bar' });
139139
});
140140
});
141141

142142
describe('#child(): DeltaSnapshot', () => {
143143
it('should work with multiple calls', () => {
144-
populate(null, {a: {b: {c: 'd'}}});
144+
populate(null, { a: { b: { c: 'd' } } });
145145
expect(subject.child('a').child('b/c').val()).to.equal('d');
146146
});
147147
});
148148

149149
describe('#exists(): boolean', () => {
150150
it('should be true for an object value', () => {
151-
populate(null, {a: {b: 'c'}});
151+
populate(null, { a: { b: 'c' } });
152152
expect(subject.child('a').exists()).to.be.true;
153153
});
154154

155155
it('should be true for a leaf value', () => {
156-
populate(null, {a: {b: 'c'}});
156+
populate(null, { a: { b: 'c' } });
157157
expect(subject.child('a/b').exists()).to.be.true;
158158
});
159159

160160
it('should be false for a non-existent value', () => {
161-
populate(null, {a: {b: 'c'}});
161+
populate(null, { a: { b: 'c' } });
162162
expect(subject.child('d').exists()).to.be.false;
163163
});
164164

165165
it('should be false for a value pathed beyond a leaf', () => {
166-
populate(null, {a: {b: 'c'}});
166+
populate(null, { a: { b: 'c' } });
167167
expect(subject.child('a/b/c').exists()).to.be.false;
168168
});
169169
});
170170

171171
describe('#previous: DeltaSnapshot', () => {
172172
it('should cause val() to return old data only', () => {
173-
populate({a: 'b'}, {a: 'c', d: 'c'});
173+
populate({ a: 'b' }, { a: 'c', d: 'c' });
174174
expect(subject.previous.child('a').val()).to.equal('b');
175175
});
176176

@@ -182,7 +182,7 @@ describe('DeltaSnapshot', () => {
182182

183183
describe('#current: DeltaSnapshot', () => {
184184
it('should cause a previous snapshot to return new data', () => {
185-
populate({a: 'b'}, {a: 'c', d: 'c'});
185+
populate({ a: 'b' }, { a: 'c', d: 'c' });
186186
expect(subject.previous.child('a').current.val()).to.equal('c');
187187
});
188188

@@ -194,7 +194,7 @@ describe('DeltaSnapshot', () => {
194194

195195
describe('#changed(): boolean', () => {
196196
it('should be true only when the current value has changed', () => {
197-
populate({a: {b: 'c'}}, {a: {d: 'e'}});
197+
populate({ a: { b: 'c' } }, { a: { d: 'e' } });
198198
expect(subject.child('a').changed()).to.be.true;
199199
expect(subject.child('a/b').changed()).to.be.false;
200200
expect(subject.child('a/d').changed()).to.be.true;
@@ -210,7 +210,7 @@ describe('DeltaSnapshot', () => {
210210

211211
describe('#forEach(childAction: Function)', () => {
212212
it('should iterate through child snapshots', () => {
213-
populate({a: 'b'}, {c: 'd'});
213+
populate({ a: 'b' }, { c: 'd' });
214214
let out = '';
215215
subject.forEach(snap => {
216216
out += snap.val();
@@ -233,7 +233,7 @@ describe('DeltaSnapshot', () => {
233233

234234
describe('#numChildren()', () => {
235235
it('should be key count for objects', () => {
236-
populate(null, {a: 'b', c: 'd'});
236+
populate(null, { a: 'b', c: 'd' });
237237
expect(subject.numChildren()).to.eq(2);
238238
});
239239

@@ -245,13 +245,13 @@ describe('DeltaSnapshot', () => {
245245

246246
describe('#hasChild(childPath): boolean', () => {
247247
it('should return true for a child or deep child', () => {
248-
populate(null, {a: {b: 'c'}, d: 23});
248+
populate(null, { a: { b: 'c' }, d: 23 });
249249
expect(subject.hasChild('a/b')).to.be.true;
250250
expect(subject.hasChild('d')).to.be.true;
251251
});
252252

253253
it('should return false if a child is missing', () => {
254-
populate(null, {a: 'b'});
254+
populate(null, { a: 'b' });
255255
expect(subject.hasChild('c')).to.be.false;
256256
expect(subject.hasChild('a/b')).to.be.false;
257257
});
@@ -287,4 +287,16 @@ describe('DeltaSnapshot', () => {
287287
expect(subject.child('foo/bar').key).to.equal('bar');
288288
});
289289
});
290+
291+
describe('#toJSON(): Object', () => {
292+
it('should return the current value', () => {
293+
populate(null, { a: 'b' });
294+
expect(subject.toJSON()).to.deep.equal(subject.val());
295+
expect(subject.previous.toJSON()).to.deep.equal(subject.previous.val());
296+
});
297+
it('should be stringifyable', () => {
298+
populate(null, { a: 'b' });
299+
expect(JSON.stringify(subject)).to.deep.equal('{"a":"b"}');
300+
});
301+
});
290302
});

src/providers/database.ts

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@
2222

2323
import * as _ from 'lodash';
2424
import { apps } from '../apps';
25-
import {Event, CloudFunction, makeCloudFunction} from '../cloud-functions';
26-
import {normalizePath, applyChange, pathParts, valAt, joinPath} from '../utils';
25+
import { Event, CloudFunction, makeCloudFunction } from '../cloud-functions';
26+
import { normalizePath, applyChange, pathParts, valAt, joinPath } from '../utils';
2727
import * as firebase from 'firebase-admin';
28-
import {config} from '../index';
28+
import { config } from '../index';
2929

3030
/** @internal */
3131
export const provider = 'google.firebase.database';
@@ -70,11 +70,11 @@ export function ref(path: string): RefBuilder {
7070
/** Builder used to create Cloud Functions for Firebase Realtime Database References. */
7171
export class RefBuilder {
7272
/** @internal */
73-
constructor(private apps: apps.Apps, private resource) {}
73+
constructor(private apps: apps.Apps, private resource) { }
7474

7575
/** Respond to any write that affects a ref. */
7676
onWrite(handler: (event: Event<DeltaSnapshot>) => PromiseLike<any> | any): CloudFunction<DeltaSnapshot> {
77-
const dataConstructor = (raw: Event<any>) => {
77+
const dataConstructor = (raw: Event<any>) => {
7878
if (raw.data instanceof DeltaSnapshot) {
7979
return raw.data;
8080
}
@@ -111,7 +111,7 @@ export function resourceToPath(resource) {
111111
throw new Error(`Unexpected resource string for Firebase Realtime Database event: ${resource}. ` +
112112
'Expected string in the format of "projects/_/instances/{firebaseioSubdomain}/refs/{ref=**}"');
113113
}
114-
let [, project, /* instance */ , path] = match;
114+
let [, project, /* instance */, path] = match;
115115
if (project !== '_') {
116116
throw new Error(`Expect project to be '_' in a Firebase Realtime Database event`);
117117
}
@@ -224,6 +224,13 @@ export class DeltaSnapshot implements firebase.database.DataSnapshot {
224224
return _.isPlainObject(val) ? Object.keys(val).length : 0;
225225
}
226226

227+
/** Prints the value of the snapshot; use '.previous' and '.current' to explicitly see
228+
* the previous and current values.
229+
*/
230+
toJSON(): Object {
231+
return this.val();
232+
}
233+
227234
/* Recursive function to check if keys are numeric & convert node object to array if they are */
228235
private _checkAndConvertToArray(node): any {
229236
if (node === null || typeof node === 'undefined') {

0 commit comments

Comments
 (0)