David-Desmaisons/Vue.resize

Can't run tests because IntersectionObserver is not defined

ciemarr opened this issue · 2 comments

There seems to be a problem with some combination of Vue, Webpack, Mocha, vue-resize-directive, and the intersection-observer polyfill. (I've cross-posted this question to the Vue community more broadly, too.)

The v-resize directive does work just fine in a real browser. It's only the test that is failing to find the definition of IntersectionObserver.

Repro Steps

I created a new Vue project:

  1. vue create vue-resize-directive-test
    • selected Babel, Typescript, class-component syntax, and Mocha + Chai
  2. yarn test:unit on generated example code passes

Then I added the v-resize directive:

  1. yarn add vue-resize-directive
  2. added a placeholder Typescript definition file, typings/vue-resize-directive.d.ts:
declare module 'vue-resize-directive';
  1. updated tsconfig.json to include the definition:
    "paths": {
      "@/*": [
        "src/*"
      ],
      "*": [
        "typings/*"
      ]
    },
  1. added the directive to a component:
<template>
  <div class="hello" v-resize="onResize">
    Hello, World!
  </div>
</template>

<script lang="ts">
import { Component, Prop, Vue } from 'vue-property-decorator';
import resize from 'vue-resize-directive';

@Component({ directives: {resize} })
export default class HelloWorld extends Vue {
  onResize() { console.log("Resized!") }
}
</script>
  1. yarn test:unit on generated example code fails with an error that "ReferenceError: IntersectionObserver is not defined":
 WEBPACK  Compiled successfully in 13052ms

 MOCHA  Testing...



  HelloWorld.vue
[Vue warn]: Error in directive resize inserted hook: "ReferenceError: IntersectionObserver is not defined"

found in

---> <HelloWorld> at src/components/HelloWorld.vue
       <Root>
ReferenceError: IntersectionObserver is not defined
    at u (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue-resize-directive/dist/Vueresize.js:1:1)
    at inserted (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue-resize-directive/dist/Vueresize.js:1:1)
    at callHook$1 (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:6620:1)
    at callInsert (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:6559:1)
    at wrappedHook (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:2225:1)
    at invokeWithErrorHandling (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:1847:1)
    at Object.invoker [as insert] (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:2165:1)
    at invokeInsertHook (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:6286:1)
    at VueComponent.patch [as __patch__] (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:6505:1)
    at VueComponent.Vue._update (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:3898:1)
    at VueComponent.updateComponent (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:4019:1)
    at Watcher.get (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:4419:1)
    at new Watcher (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:4408:1)
    at mountComponent (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:4026:1)
    at VueComponent../node_modules/vue/dist/vue.runtime.esm.js.Vue.$mount (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/vue/dist/vue.runtime.esm.js:8350:1)
    at mount (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/@vue/test-utils/dist/vue-test-utils.js:8649:1)
    at shallowMount (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/node_modules/@vue/test-utils/dist/vue-test-utils.js:8677:1)
    at Context.it (/Users/cmrodgers/github/mine/vue-resize-directive-test/dist/webpack:/tests/unit/example.spec.ts:8:1)
    at callFn (/Users/cmrodgers/github/mine/vue-resize-directive-test/node_modules/mocha/lib/runnable.js:372:21)
    at Test.Runnable.run (/Users/cmrodgers/github/mine/vue-resize-directive-test/node_modules/mocha/lib/runnable.js:364:7)
    at Runner.runTest (/Users/cmrodgers/github/mine/vue-resize-directive-test/node_modules/mocha/lib/runner.js:455:10)
    at /Users/cmrodgers/github/mine/vue-resize-directive-test/node_modules/mocha/lib/runner.js:573:12
    at next (/Users/cmrodgers/github/mine/vue-resize-directive-test/node_modules/mocha/lib/runner.js:369:14)
    at /Users/cmrodgers/github/mine/vue-resize-directive-test/node_modules/mocha/lib/runner.js:379:7
    at next (/Users/cmrodgers/github/mine/vue-resize-directive-test/node_modules/mocha/lib/runner.js:303:14)
    at Immediate._onImmediate (/Users/cmrodgers/github/mine/vue-resize-directive-test/node_modules/mocha/lib/runner.js:347:5)
    at runCallback (timers.js:694:18)
    at tryOnImmediate (timers.js:665:5)
    at processImmediate (timers.js:647:5)

I also repeated the same steps, but with plain Javascript instead of Typescript:

<template>
  <div class="hello" v-resize="onResize">
    Hello, World!
  </div>
</template>

<script>
import resize from 'vue-resize-directive';

export default {
  name: 'HelloWorld',
  directives: { resize },
  methods: {
    onResize: function() { console.log("Resized!") }
  }
}
</script>

Same error.

Debugging Info

I confirmed that the intersection-observer Node package exists in node_modules/, so I would have expected it to polyfill correctly.

I tried running the tests as yarn test:unit --require intersection-observer and/or --include node_modules/intersection-observer/intersection-observer.js, but that made no difference.

Version Info:

  • vue-resize-directive in package.json: 1.1.4
  • vue in package.json: 2.5.22
  • intersection-observer in node_modules:0.5.1
  • vue --version: 3.40
  • yarn --version: node-1.13.0
  • node --version: 10.11.0

I still don't know what the problem with the IntersectionObserver polyfill in tests is, but I am able to ignore it for now by passing a second parameter into shallowMount to mock out the resize directive:

var mockDirective = {};
shallowMount(HelloWorld, { directives: { resize: mockDirective } });

I was reading your first post before seeing your second comment, and I was thinking exatly the same thing that you suggest before.
For test purpose a mock directive should do the trick.