Explorar el Código

SSR warn for no VUE_ENV and add tests (#2844)

- Added test coverage for data observation and VUE environment variable
- Moved Test helpers into own folder for reusability
Blake Newman hace 10 años
padre
commit
35440d9856

+ 8 - 0
src/server/create-renderer.js

@@ -1,11 +1,19 @@
 import RenderStream from './render-stream'
 import { createRenderFunction } from './render'
+import { warn } from 'core/util/debug'
 
 export function createRenderer ({
   modules = [],
   directives = {},
   isUnaryTag = (() => false)
 } = {}) {
+  if (process.env.VUE_ENV !== 'server') {
+    warn(
+      'You are using createRenderer without setting VUE_ENV enviroment variable to "server". ' +
+      'It is recommended to set VUE_ENV=server this will help rendering performance, ' +
+      'by turning data observation off.'
+    )
+  }
   const render = createRenderFunction(modules, directives, isUnaryTag)
   return {
     renderToString (component) {

+ 8 - 0
test/helpers/.eslintrc

@@ -0,0 +1,8 @@
+{
+  "env": {
+    "jasmine": true
+  },
+  "globals": {
+    "waitForUpdate": true
+  }
+}

+ 43 - 0
test/helpers/to-have-been-warned.js

@@ -0,0 +1,43 @@
+if (typeof console === 'undefined') {
+  window.console = {
+    error: function () {}
+  }
+}
+
+function hasWarned (msg) {
+  var count = console.error.calls.count()
+  var args
+  while (count--) {
+    args = console.error.calls.argsFor(count)
+    if (args.some(containsMsg)) {
+      return true
+    }
+  }
+
+  function containsMsg (arg) {
+    if (arg instanceof Error) throw arg
+    return typeof arg === 'string' && arg.indexOf(msg) > -1
+  }
+}
+
+// define custom matcher for warnings
+beforeEach(function () {
+  spyOn(console, 'error')
+  jasmine.addMatchers({
+    toHaveBeenWarned: function () {
+      return {
+        compare: function (msg) {
+          var warned = Array.isArray(msg)
+            ? msg.some(hasWarned)
+            : hasWarned(msg)
+          return {
+            pass: warned,
+            message: warned
+              ? 'Expected message "' + msg + '" not to have been warned'
+              : 'Expected message "' + msg + '" to have been warned'
+          }
+        }
+      }
+    }
+  })
+})

+ 52 - 0
test/helpers/wait-for-update.js

@@ -0,0 +1,52 @@
+import Vue from 'vue'
+
+// helper for async assertions.
+// Use like this:
+//
+// vm.a = 123
+// waitForUpdate(() => {
+//   expect(vm.$el.textContent).toBe('123')
+//   vm.a = 234
+// })
+// .then(() => {
+//   // more assertions...
+//   done()
+// })
+// .catch(done)
+window.waitForUpdate = initialCb => {
+  let done
+  const queue = [initialCb]
+
+  function shift () {
+    const job = queue.shift()
+    let hasError = false
+    try {
+      job()
+    } catch (e) {
+      hasError = true
+      if (done) {
+        done.fail(e)
+      }
+    }
+    if (!hasError) {
+      if (queue.length) {
+        Vue.nextTick(shift)
+      }
+    }
+  }
+
+  Vue.nextTick(shift)
+
+  const chainer = {
+    then: nextCb => {
+      queue.push(nextCb)
+      return chainer
+    },
+    catch: doneCb => {
+      done = doneCb
+      return chainer
+    }
+  }
+
+  return chainer
+}

+ 1 - 0
test/ssr/jasmine.json

@@ -1,6 +1,7 @@
 {
   "spec_dir": "test/ssr",
   "spec_files": [
+    "ssr-env.spec.js",
     "ssr-string.spec.js",
     "ssr-stream.spec.js"
   ],

+ 45 - 0
test/ssr/ssr-env.spec.js

@@ -0,0 +1,45 @@
+import Vue from '../../dist/vue.common.js'
+import createRenderer from '../../dist/server-renderer.js'
+import '../helpers/to-have-been-warned.js'
+
+describe('SSR: VUE_ENV=server', () => {
+  it('_isServer set as "server" on Vue config', () => {
+    expect(Vue.config._isServer).toBe(true)
+  })
+
+  it('$isServer set as true on VM', () => {
+    const vm = new Vue({
+      data: {
+        foo: 'server',
+        bar: 'rendering'
+      }
+    })
+    expect(vm.$isServer).toBe(true)
+  })
+
+  it('no data observations', () => {
+    const vm = new Vue({
+      data: {
+        foo: 'server',
+        bar: 'rendering'
+      },
+      computed: {
+        combined () {
+          return this.foo + this.bar
+        }
+      }
+    })
+
+    vm.foo = ''
+    expect(vm.foo).toBe('')
+    expect(vm.combined).toBe('rendering')
+    expect(vm.$data.__ob__).toBe(undefined)
+  })
+
+  it('should warn when not set', () => {
+    process.env.VUE_ENV = ''
+    createRenderer()
+    expect('You are using createRenderer without setting VUE_ENV enviroment').toHaveBeenWarned()
+    process.env.VUE_ENV = 'server'
+  })
+})

+ 2 - 95
test/unit/index.js

@@ -1,102 +1,9 @@
 import Vue from 'vue'
+import '../helpers/to-have-been-warned.js'
+import '../helpers/wait-for-update.js'
 
 Vue.config.preserveWhitespace = false
 
-if (typeof console === 'undefined') {
-  window.console = {
-    error: function () {}
-  }
-}
-
-function hasWarned (msg) {
-  var count = console.error.calls.count()
-  var args
-  while (count--) {
-    args = console.error.calls.argsFor(count)
-    if (args.some(containsMsg)) {
-      return true
-    }
-  }
-
-  function containsMsg (arg) {
-    if (arg instanceof Error) throw arg
-    return typeof arg === 'string' && arg.indexOf(msg) > -1
-  }
-}
-
-// define custom matcher for warnings
-beforeEach(function () {
-  spyOn(console, 'error')
-  jasmine.addMatchers({
-    toHaveBeenWarned: function () {
-      return {
-        compare: function (msg) {
-          var warned = Array.isArray(msg)
-            ? msg.some(hasWarned)
-            : hasWarned(msg)
-          return {
-            pass: warned,
-            message: warned
-              ? 'Expected message "' + msg + '" not to have been warned'
-              : 'Expected message "' + msg + '" to have been warned'
-          }
-        }
-      }
-    }
-  })
-})
-
-// helper for async assertions.
-// Use like this:
-//
-// vm.a = 123
-// waitForUpdate(() => {
-//   expect(vm.$el.textContent).toBe('123')
-//   vm.a = 234
-// })
-// .then(() => {
-//   // more assertions...
-//   done()
-// })
-// .catch(done)
-window.waitForUpdate = initialCb => {
-  let done
-  const queue = [initialCb]
-
-  function shift () {
-    const job = queue.shift()
-    let hasError = false
-    try {
-      job()
-    } catch (e) {
-      hasError = true
-      if (done) {
-        done.fail(e)
-      }
-    }
-    if (!hasError) {
-      if (queue.length) {
-        Vue.nextTick(shift)
-      }
-    }
-  }
-
-  Vue.nextTick(shift)
-
-  const chainer = {
-    then: nextCb => {
-      queue.push(nextCb)
-      return chainer
-    },
-    catch: doneCb => {
-      done = doneCb
-      return chainer
-    }
-  }
-
-  return chainer
-}
-
 // require all test files
 const testsContext = require.context('./', true, /\.spec$/)
 testsContext.keys().forEach(testsContext)