diff --git a/test/fixtures/ssr/components/test.vue b/test/fixtures/ssr/components/test.vue new file mode 100644 index 0000000000..cdc10f9b6f --- /dev/null +++ b/test/fixtures/ssr/components/test.vue @@ -0,0 +1,17 @@ + + + \ No newline at end of file diff --git a/test/fixtures/ssr/lib/db.js b/test/fixtures/ssr/lib/db.js new file mode 100644 index 0000000000..9c173807f6 --- /dev/null +++ b/test/fixtures/ssr/lib/db.js @@ -0,0 +1,4 @@ + +let idCtr = 0 + +export const nextId = () => ++idCtr diff --git a/test/fixtures/ssr/pages/asyncData.vue b/test/fixtures/ssr/pages/asyncData.vue new file mode 100644 index 0000000000..5f194666ed --- /dev/null +++ b/test/fixtures/ssr/pages/asyncData.vue @@ -0,0 +1,15 @@ + + + diff --git a/test/fixtures/ssr/pages/component.vue b/test/fixtures/ssr/pages/component.vue new file mode 100644 index 0000000000..316ad6e5ec --- /dev/null +++ b/test/fixtures/ssr/pages/component.vue @@ -0,0 +1,15 @@ + + + \ No newline at end of file diff --git a/test/fixtures/ssr/pages/data.vue b/test/fixtures/ssr/pages/data.vue new file mode 100644 index 0000000000..f627b7b373 --- /dev/null +++ b/test/fixtures/ssr/pages/data.vue @@ -0,0 +1,15 @@ + + + diff --git a/test/fixtures/ssr/pages/fetch.vue b/test/fixtures/ssr/pages/fetch.vue new file mode 100644 index 0000000000..27ed0ec8bc --- /dev/null +++ b/test/fixtures/ssr/pages/fetch.vue @@ -0,0 +1,14 @@ + + + diff --git a/test/fixtures/ssr/pages/store.vue b/test/fixtures/ssr/pages/store.vue new file mode 100644 index 0000000000..767e0f3b23 --- /dev/null +++ b/test/fixtures/ssr/pages/store.vue @@ -0,0 +1,5 @@ + \ No newline at end of file diff --git a/test/fixtures/ssr/store/index.js b/test/fixtures/ssr/store/index.js new file mode 100644 index 0000000000..e98ccc4f5d --- /dev/null +++ b/test/fixtures/ssr/store/index.js @@ -0,0 +1,22 @@ +import { nextId } from '@/lib/db' + +export const state = () => { + return { + id: nextId(), + id2: 0 + } +} + +export const mutations = { + setId2 (state, id) { + state.id2 = id + } +} + +export const actions = { + nuxtServerInit ({ commit, state }, { route }) { + if (route.query.onServerInit === '1') { + commit('setId2', nextId()) + } + } +} diff --git a/test/ssr.test.js b/test/ssr.test.js new file mode 100755 index 0000000000..09a3bc0aa7 --- /dev/null +++ b/test/ssr.test.js @@ -0,0 +1,84 @@ +import test from 'ava' +import { resolve } from 'path' +import { Nuxt, Builder, Utils } from '..' +import { uniq } from 'lodash' + +const port = 4008 +let nuxt = null + +// Utils +const range = n => [...Array(n).keys()] +const FOOBAR_REGEX = /([\s\S]*)<\/foobar>/ +const match = (regex, text) => (regex.exec(text) || [])[1] + +// Init nuxt.js and create server listening on localhost:4000 +test.before('Init Nuxt.js', async t => { + const options = { + rootDir: resolve(__dirname, 'fixtures/ssr'), + dev: false, + render: { + resourceHints: false + }, + build: { + extractCSS: true + } + } + nuxt = new Nuxt(options) + await new Builder(nuxt).build() + await nuxt.listen(port, 'localhost') +}) + +// == Uniq Test == +// The idea behind is pages using a shared nextId() which retuns an increamenting id +// So all responses should strictly be different and length of unique responses should equal to responses +// We strictly compare {id} section +// Because other response parts such as window.__NUXT may be different resulting false positive passes. +const uniqueTest = async (t, url) => { + let results = [] + + await Utils.parallel(range(20), async () => { + let { html } = await nuxt.renderRoute(url) + let foobar = match(FOOBAR_REGEX, html) + results.push(parseInt(foobar)) + }) + + let isUnique = uniq(results).length === results.length + + if (!isUnique) { + /* eslint-disable no-console */ + console.log(url + '\n' + results.join(', ') + '\n') + } + + t.true(isUnique) + + return results +} + +test('unique responses with data()', async t => { + await uniqueTest(t, '/data') +}) + +test('unique responses with component', async t => { + await uniqueTest(t, '/component') +}) + +test('unique responses with asyncData()', async t => { + await uniqueTest(t, '/asyncData') +}) + +test('unique responses with store initial state', async t => { + await uniqueTest(t, '/store') +}) + +test('unique responses with nuxtServerInit', async t => { + await uniqueTest(t, '/store?onServerInit=1') +}) + +test('unique responses with fetch', async t => { + await uniqueTest(t, '/fetch') +}) + +// Close server and ask nuxt to stop listening to file changes +test.after('Closing server and nuxt.js', t => { + nuxt.close() +})