hubot icon indicating copy to clipboard operation
hubot copied to clipboard

Robot uses deprecated `require.extensions` prevents using Jest for testing

Open jeremygaither opened this issue 6 years ago • 3 comments

Node.js global require.extensions was deprecated since v0.10.6 and appears to have been removed from the documentation as of v8 LTS:

This block of code causes problems when testing with Jest and hubot-test-helper: https://github.com/hubotio/hubot/blob/ea182fa73852177897db51e119ce78e4c645bacc/src/robot.js#L352-L355

The module hubot-test-helper uses const Hubot = require('hubot/es2015'); to require in Hubot: https://github.com/mtsmfm/hubot-test-helper/blob/master/src/index.js#L5

Global require.extensions is undefined running under the default Jest test runner (logging added to diagnose problem):

failing scenario

  console.log node_modules/hubot-test-helper/src/index.js:161
    script /Users/REDACTED/scripts/REDACTED.js

  console.log node_modules/hubot/src/robot.js:351
    filepath /Users/REDACTED/scripts filename REDACTED.js

  console.log node_modules/hubot/src/robot.js:354
    full /Users/REDACTED/scripts/REDACTED ext .js

  console.log node_modules/hubot/src/robot.js:356
    in robot require undefined

  console.log node_modules/hubot/src/robot.js:361
    not require extensions

Related: https://github.com/facebook/jest/issues/281 (workarounds are not working for Hubot)

Is there another recommended way to use Jest with Hubot, or is the preferred/recommended testing framework Mocha?

Would it be better to remove this check that is relying on a deprecated object to exist? The code does indeed run in Jest with the default runner and minimal config changed when the above block is removed. I don't know if https://github.com/hubotio/hubot/issues/1355 is still a concern. It does attempt to load non-js files (and folders that may not have an index.js) but the try/catch block can avoid problems if process.exit(1) is removed.

working modified scenario

    console.log node_modules/hubot-test-helper/src/index.js:161
      script ../scripts
    console.log node_modules/hubot/src/robot.js:351
      filepath /Users/REDACTED/scripts filename deploy-queue.js
    console.log node_modules/hubot/src/robot.js:354
      full /Users/REDACTED/scripts/deploy-queue ext .js
    console.log node_modules/hubot/src/robot.js:356
      in robot require undefined
    console.log node_modules/hubot/src/robot.js:369
      required /Users/REDACTED/scripts/deploy-queue
    console.log node_modules/hubot/src/robot.js:373
      loaded script as function
    console.log node_modules/hubot/src/robot.js:351
      filepath /Users/REDACTED/scripts filename error-handler.js
    console.log node_modules/hubot/src/robot.js:354
      full /Users/REDACTED/scripts/error-handler ext .js
    console.log node_modules/hubot/src/robot.js:356
      in robot require undefined
    console.log node_modules/hubot/src/robot.js:369
      required /Users/REDACTED/scripts/error-handler
    console.log node_modules/hubot/src/robot.js:373
      loaded script as function
    console.log node_modules/hubot/src/robot.js:351
      filepath /Users/REDACTED/scripts filename foo.yaml
    console.log node_modules/hubot/src/robot.js:354
      full /Users/REDACTED/scripts/foo ext .yaml
    console.log node_modules/hubot/src/robot.js:356
      in robot require undefined
    console.log node_modules/hubot/src/robot.js:380
      Unable to load /Users/REDACTED/scripts/foo: Error: Cannot find module '/Users/REDACTED/scripts/foo' from 'robot.js'
          at Resolver.resolveModule (/Users/REDACTED/node_modules/jest-resolve/build/index.js:221:17)
          at Resolver._getVirtualMockPath (/Users/REDACTED/node_modules/jest-resolve/build/index.js:338:16)
          at Resolver._getAbsolutePath (/Users/REDACTED/node_modules/jest-resolve/build/index.js:324:14)
          at Resolver.getModuleID (/Users/REDACTED/node_modules/jest-resolve/build/index.js:301:31)
          at Runtime._shouldMock (/Users/REDACTED/node_modules/jest-runtime/build/index.js:766:37)
          at Runtime.requireModuleOrMock (/Users/REDACTED/node_modules/jest-runtime/build/index.js:460:14)
          at MockRobot.loadFile (/Users/REDACTED/node_modules/hubot/src/robot.js:368:22)
          at Helper.createRoom (/Users/REDACTED/node_modules/hubot-test-helper/src/index.js:165:17)
          at Object.createRoom (/Users/REDACTED/test/REDACTED.test.js:36:31)
          at Object.asyncJestLifecycle (/Users/REDACTED/node_modules/jest-jasmine2/build/jasmine_async.js:63:37)
    console.log node_modules/hubot/src/robot.js:351
      filepath /Users/REDACTED/scripts filename REDACTED.js
    console.log node_modules/hubot/src/robot.js:354
      full /Users/REDACTED/scripts/REDACTED ext .js
    console.log node_modules/hubot/src/robot.js:356
      in robot require undefined
    console.log scripts/REDACTED.js:8
      /Users/REDACTED/scripts/REDACTED.js loaded
    console.log node_modules/hubot/src/robot.js:369
      required /Users/REDACTED/scripts/REDACTED
    console.log node_modules/hubot/src/robot.js:373
      loaded script as function
    console.log node_modules/hubot/src/robot.js:351
      filepath /Users/REDACTED/scripts filename lib
    console.log node_modules/hubot/src/robot.js:354
      full /Users/REDACTED/scripts/lib ext 
    console.log node_modules/hubot/src/robot.js:356
      in robot require undefined
    console.log node_modules/hubot/src/robot.js:380
      Unable to load /Users/REDACTED/scripts/lib: Error: Cannot find module '/Users/REDACTED/scripts/lib' from 'robot.js'
          at Resolver.resolveModule (/Users/REDACTED/node_modules/jest-resolve/build/index.js:221:17)
          at Resolver._getVirtualMockPath (/Users/REDACTED/node_modules/jest-resolve/build/index.js:338:16)
          at Resolver._getAbsolutePath (/Users/REDACTED/node_modules/jest-resolve/build/index.js:324:14)
          at Resolver.getModuleID (/Users/REDACTED/node_modules/jest-resolve/build/index.js:301:31)
          at Runtime._shouldMock (/Users/REDACTED/node_modules/jest-runtime/build/index.js:766:37)
          at Runtime.requireModuleOrMock (/Users/REDACTED/node_modules/jest-runtime/build/index.js:460:14)
          at MockRobot.loadFile (/Users/REDACTED/node_modules/hubot/src/robot.js:368:22)
          at Helper.createRoom (/Users/REDACTED/node_modules/hubot-test-helper/src/index.js:165:17)
          at Object.createRoom (/Users/REDACTED/test/REDACTED.test.js:36:31)
          at Object.asyncJestLifecycle (/Users/REDACTED/node_modules/jest-jasmine2/build/jasmine_async.js:63:37)
    console.log node_modules/hubot/src/robot.js:351
      filepath /Users/REDACTED/scripts filename REDACTED.js
    console.log node_modules/hubot/src/robot.js:354
      full /Users/REDACTED/scripts/REDACTED ext .js
    console.log node_modules/hubot/src/robot.js:356
      in robot require undefined
    console.log node_modules/hubot/src/robot.js:369
      required /Users/REDACTED/scripts/REDACTED
    console.log node_modules/hubot/src/robot.js:373
      loaded script as function
    console.log node_modules/hubot/src/robot.js:351
      filepath /Users/REDACTED/scripts filename REDACTED.js
    console.log node_modules/hubot/src/robot.js:354
      full /Users/REDACTED/scripts/REDACTED ext .js
    console.log node_modules/hubot/src/robot.js:356
      in robot require undefined
    console.log node_modules/hubot/src/robot.js:369
      required /Users/REDACTED/scripts/REDACTED
    console.log node_modules/hubot/src/robot.js:373
      loaded script as function

modified test code

    /*
    // see https://github.com/hubotio/hubot/issues/1355
    if (!require.extensions[ext]) { // eslint-disable-line
      console.log('not require extensions')
      return
    }
    */

    try {
      const script = require(full)
      console.log(`required ${full}`);

      if (typeof script === 'function') {
        script(this)
        console.log(`loaded script as ${typeof script}`);
        this.parseHelp(path.join(filepath, filename))
      } else {
        console.log(`Expected ${full} to assign a function to module.exports, got ${typeof script}`)
        this.logger.warning(`Expected ${full} to assign a function to module.exports, got ${typeof script}`)
      }
    } catch (error) {
      console.log(`Unable to load ${full}: ${error.stack}`)
      this.logger.error(`Unable to load ${full}: ${error.stack}`)
      // process.exit(1)
    }
  }

jeremygaither avatar Nov 29 '18 08:11 jeremygaither

@jeremygaither did you ever figure out a workaround for this?

dtothefp avatar Oct 10 '19 20:10 dtothefp

@dtothefp I really haven't tried again with Jest, since I ran into considerable problems. The async nature of Jest made many things with hubot and hubot-test-helper much harder versus Mocha, if I recall correctly.

jeremygaither avatar Oct 11 '19 01:10 jeremygaither

No

On Thu, Oct 10, 2019, 3:54 PM David Fox-Powell [email protected] wrote:

@jeremygaither https://github.com/jeremygaither did you ever figure out a workaround for this?

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/hubotio/hubot/issues/1483?email_source=notifications&email_token=ANK56DJGONXBDV4EHH42HZTQN6I6ZA5CNFSM4GHE2AOKYY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2ZLOORPWSZGOEA54WMI#issuecomment-540789553, or unsubscribe https://github.com/notifications/unsubscribe-auth/ANK56DME7GQEUHAD65LZCXTQN6I6ZANCNFSM4GHE2AOA .

dreamgirlDavis avatar Oct 11 '19 07:10 dreamgirlDavis

This was fixed in https://github.com/hubotio/hubot/pull/1581

technicalpickles avatar Apr 18 '23 13:04 technicalpickles