Skip to content
This repository has been archived by the owner on Jan 26, 2023. It is now read-only.

Commit

Permalink
feat: support filtering state export
Browse files Browse the repository at this point in the history
closes #27
  • Loading branch information
JohannesLamberts committed Aug 4, 2019
1 parent 212227f commit b73c4a2
Show file tree
Hide file tree
Showing 3 changed files with 150 additions and 4 deletions.
126 changes: 126 additions & 0 deletions src/registry.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
import {
createLocalVue,
mount,
} from '@vue/test-utils'
import { ComponentOptions } from 'vue'
import { Vue } from 'vue/types/vue'
import VueStates from './index'
import { ExportStateOptions } from './registry'

const localVue = createLocalVue()
localVue.use(VueStates)

/* tslint:disable-next-line:variable-name */
const createModel = (value: string) => ({
data() {
return {
key: value,
}
},
})

function createWrapper(
exportState?: ComponentOptions<Vue>['exportState'],
) {
return mount(
{
models: {
one: {
...createModel('one'),
exportState,
},
},
render(h) {
return h('div')
},
},
{ localVue },
)
}

function exportFromWrapper(
exportState?: ComponentOptions<Vue>['exportState'],
options?: ExportStateOptions,
) {
const wrapper = createWrapper(exportState)
return wrapper.vm.$modelRegistry.exportState(options)
}

const standardExportedState = {
'one~single': JSON.stringify({ key: 'one' }),
}

describe('registry', () => {
it('should export state', () => {
const wrapper = mount(
{
models: {
one: createModel('one'),
two: createModel('two'),
},
render(h) {
return h('div')
},
},
{ localVue },
)
const exported = wrapper.vm.$modelRegistry.exportState()
expect(exported)
.toEqual({
'one~single': JSON.stringify({ key: 'one' }),
'two~single': JSON.stringify({ key: 'two' }),
})
})

it('should filter exportState on boolean', () => {
expect(exportFromWrapper(false))
.toEqual({})
expect(exportFromWrapper(true))
.toEqual(standardExportedState)
})

it('should filter exportState on callback', () => {
expect(exportFromWrapper(function () {
// @ts-ignore
return this.key === 'one'
}))
.toEqual(standardExportedState)
expect(exportFromWrapper(function () {
// @ts-ignore
return this.key !== 'one'
}))
.toEqual({})
})

it('should forward args to callback', () => {
let shouldExport = true

const exportStateCallback = jest.fn(({ shouldExport }) => shouldExport)

function exportWithContext() {
return exportFromWrapper(
exportStateCallback,
{ context: { shouldExport } },
)
}

expect(exportWithContext())
.toEqual(standardExportedState)
expect(exportStateCallback)
.toHaveBeenLastCalledWith({ shouldExport })

shouldExport = false

expect(exportWithContext())
.toEqual({})
expect(exportStateCallback)
.toHaveBeenLastCalledWith({ shouldExport })
})

it('should use default when exportState is undefined', () => {
expect(exportFromWrapper())
.toEqual(standardExportedState)
expect(exportFromWrapper(undefined, { filterDefault: false }))
.toEqual({})
})
})
27 changes: 23 additions & 4 deletions src/registry.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
import { Vue } from 'vue/types/vue'
import { Export } from './types'

export interface ExportStateOptions {
filterDefault?: boolean,
context?: any,
}

/**
* root registry of history and models,
* to be registered on the Vue prototype
Expand Down Expand Up @@ -30,12 +35,26 @@ export default class Registry {
}
}

exportState(): Export {
exportState(
{
filterDefault = true,
context,
}: ExportStateOptions = {}): Export {
const mapped: Export = {}

Object.keys(this.models)
.forEach((key) => {
mapped[key] = JSON.stringify(Object.assign({}, this.models[key].$data))
Object.entries(this.models)
.filter(([_, vm]) => {
const { exportState } = vm.$options
if (typeof exportState === 'undefined') {
return filterDefault
}
if (typeof exportState === 'function') {
return exportState.call(vm, context)
}
return exportState
})
.forEach(([key, vm]) => {
mapped[key] = JSON.stringify(Object.assign({}, vm.$data))
})

return mapped
Expand Down
1 change: 1 addition & 0 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ declare module 'vue/types/options' {
models?: VueModelMap | ((this: Vue) => VueModelMap)
modelId?: string,
modelGId?: string,
exportState?: boolean | ((this: Vue, componentArgs: any) => boolean)
}
}

Expand Down

0 comments on commit b73c4a2

Please sign in to comment.