Skip to content

Commit

Permalink
test(collections): Add mock + tests for simple collections
Browse files Browse the repository at this point in the history
  • Loading branch information
posva committed Oct 10, 2017
1 parent 9642e47 commit 1acd0b6
Show file tree
Hide file tree
Showing 6 changed files with 245 additions and 46 deletions.
27 changes: 13 additions & 14 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
function createDoc (doc) {
// defaults everything to false, so no need to set
console.log('create', doc.data())
return Object.defineProperty(doc.data(), 'id', {
value: doc.id,
})
}
import { createSnapshot } from './utils'

function bindCollection({
vm,
Expand All @@ -16,11 +10,11 @@ function bindCollection({

const change = {
added: ({ newIndex, doc }) => {
array.splice(newIndex, 0, createDoc(doc))
array.splice(newIndex, 0, createSnapshot(doc))
},
modified: ({ oldIndex, newIndex, doc }) => {
array.splice(oldIndex, 1)
array.splice(newIndex, 0, createDoc(doc))
array.splice(newIndex, 0, createSnapshot(doc))
},
removed: ({ oldIndex }) => {
array.splice(oldIndex, 1)
Expand All @@ -46,11 +40,16 @@ function install (Vue, options) {
const { firestore } = this.$options
if (!firestore) return
Object.keys(firestore).forEach(key => {
bindCollection({
vm: this,
key,
collection: firestore[key],
})
const ref = firestore[key]
if (ref.add) {
bindCollection({
vm: this,
key,
collection: ref,
})
} else {
// TODO
}
})
}
})
Expand Down
6 changes: 6 additions & 0 deletions src/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
export function createSnapshot (doc) {
// defaults everything to false, so no need to set
return Object.defineProperty(doc.data(), 'id', {
value: doc.id,
})
}
57 changes: 57 additions & 0 deletions test/collection.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import test from 'ava'
import Vuefire from '../src'
import {
createSnapshot
} from '../src/utils'
import {
db,
tick,
Vue
} from './helpers'

Vue.use(Vuefire)

test.beforeEach(async t => {
t.context.collection = db.collection()
t.context.vm = new Vue({
render (h) {
return h('ul', this.items.map(
item => h('li', [item])
))
},
data: () => ({ items: null }),
firestore: {
items: t.context.collection
}
}).$mount()
await tick()
})

test('initialise the array', t => {
t.deepEqual(t.context.vm.items, [])
})

test('add elements', async t => {
await t.context.collection.add({ text: 'foo' })
t.deepEqual(t.context.vm.items, [{ text: 'foo' }])
await t.context.collection.add({ text: 'bar' })
t.deepEqual(t.context.vm.items, [{ text: 'foo' }, { text: 'bar' }])
})

test('delets items', async t => {
await t.context.collection.add({ text: 'foo' })
await t.context.collection.doc(t.context.vm.items[0].id).delete()
t.deepEqual(t.context.vm.items, [])
})

test('update items', async t => {
const doc = await t.context.collection.add({ text: 'foo' })
await doc.update({ text: 'bar' })
t.deepEqual(t.context.vm.items[0], { text: 'bar' })
})

test('add properties', async t => {
const doc = await t.context.collection.add({ text: 'foo' })
await doc.update({ other: 'bar' })
t.deepEqual(t.context.vm.items[0], { text: 'foo', other: 'bar' })
})
99 changes: 89 additions & 10 deletions test/helpers/mock.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,12 @@ DocumentSnapshot.prototype.data = function () {
return this._document
}

let id = 0
class Key {
export { DocumentSnapshot }

const noop = _ => null

export let id = 0
export class Key {
constructor () {
this.id = id++
}
Expand All @@ -17,22 +21,97 @@ class Key {
}
}

export const collection = {
data: [],
class DocumentReference {
constructor ({ collection, id, data, index }) {
this.collection = collection
this.id = id
this.data = data
this.index = index
}

async delete () {
return this.collection._remove(this.id)
}

async update (data) {
Object.assign(this.data, data)
return this.collection._modify(this.id, this.data)
}
}

class CollectionReference {
constructor () {
this.data = {}
this.cb = this.onError = noop
}

onSnapshot (cb, onError) {
this.cb = cb
this.onError = onError
},
}

add (item) {
this.data.push(item)
async add (data) {
const id = new Key()
this.data[id] = new DocumentReference({
collection: this,
id,
data,
index: Object.keys(this.data).length
})
this.cb({
docChanges: [{
doc: new DocumentSnapshot(null, new Key(), item), // TODO docsnapshot
newIndex: this.data.length - 1,
oldIndex: -1,
type: 'added',
doc: new DocumentSnapshot(null, id, data),
newIndex: Object.keys(this.data).length,
oldIndex: -1,
}]
})
return this.data[id]
}

doc (id) {
id = id || new Key()
return this.data[id] = this.data[id] || new DocumentReference({
collection: this,
id,
data: {},
index: Object.keys(this.data).length
})
}

async _remove (id) {
const ref = this.data[id]
delete this.data[id]
this.cb({
docChanges: [{
doc: new DocumentSnapshot(null, id, ref.data),
type: 'removed',
}]
})
ref.collection = null
ref.data = null
}

async _modify (id, data) {
this.cb({
docChanges: [{
type: 'modified',
doc: new DocumentSnapshot(null, id, data),
oldIndex: this.data[id].index,
newIndex: this.data[id].index,
}]
})

}
}

export const db = {
db: {},
n: 0,

collection (name) {
// create a collection if no name provided
name = name || `random__${this.n++}`
return db[name] = db[name] || new CollectionReference()
}
}
66 changes: 44 additions & 22 deletions test/index.js
Original file line number Diff line number Diff line change
@@ -1,32 +1,54 @@
import test from 'ava'
import Vuefire from '../src'
import { tick, Vue } from './helpers'
import { collection } from './helpers'
import {
createSnapshot
} from '../src/utils'
import {
db,
tick,
Vue
} from './helpers'

Vue.use(Vuefire)

const vm = new Vue({
render (h) {
return h('ul', this.items.map(
item => h('li', [item])
))
},
data: () => ({ items: [] }),
firestore: {
items: collection
}
}).$mount()

Vue.use(Vuefire)

test('foo', async t => {
test.beforeEach(async t => {
t.context.collection = db.collection()
t.context.document = t.context.collection.doc()
t.context.vm = new Vue({
render (h) {
return h('ul', this.items.map(
item => h('li', [item])
))
},
// purposely set items as null
// but it's a good practice to set it to an empty array
data: () => ({ items: null }),
firestore: {
items: t.context.collection,
item: t.context.document
}
}).$mount()
await tick()
t.deepEqual(vm.items, [])
t.pass()
})

test('bar', async t => {
const bar = Promise.resolve('bar')
test('detects collections', async t => {
await t.context.document.update({ foo: 'foo' })
t.deepEqual(t.context.vm.item, { foo: 'foo' })
})

test('detects documents', async t => {
await t.context.collection.add({ foo: 'foo' })
t.deepEqual(t.context.vm.items, [{ foo: 'foo' }])
})

t.is(await bar, 'bar')
test('does nothing with no firestore', t => {
const vm = new Vue({
render (h) {
return h('ul', this.items.map(
item => h('li', [item])
))
},
data: () => ({ items: null }),
})
t.deepEqual(t.context.vm.items, null)
})
36 changes: 36 additions & 0 deletions test/utils.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import test from 'ava'
import {
createSnapshot,
} from '../src/utils'
import {
collection,
Key,
id,
DocumentSnapshot
} from './helpers'

test.beforeEach(t => {
t.context.id = id
t.context.doc = new DocumentSnapshot(null, new Key(), {
n: 42,
is: true,
items: [{ text: 'foo' }]
})
t.context.snapshot = createSnapshot(t.context.doc)
})

test('createSnapshot adds an id', t => {
t.is(t.context.snapshot.id, t.context.id)
})

test('id is not enumerable', t => {
t.false(Object.keys(t.context.snapshot).includes('id'))
})

test('contains all the data', t => {
t.deepEqual(t.context.snapshot, {
n: 42,
is: true,
items: [{ text: 'foo' }]
})
})

0 comments on commit 1acd0b6

Please sign in to comment.