Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Throw exception when using equal & same for some variable #791

Closed
huan opened this issue Nov 21, 2021 · 4 comments
Closed

Throw exception when using equal & same for some variable #791

huan opened this issue Nov 21, 2021 · 4 comments

Comments

@huan
Copy link

huan commented Nov 21, 2021

Versions

tap@15.0.10
wechaty@1.9.8
wechaty-puppet-mock@1.9.1

equal() Cannot read property 'length' of null

# Subtest: Wechaty <> Tap `Error: undefined is not a function`
    not ok 1 - Cannot read property 'length' of null
      ---
      stack: |
        Format.arrayIsEmpty (node_modules/tcompare/lib/format.js:390:31)
        Format.array (node_modules/tcompare/lib/format.js:384:14)
        Format.collection (node_modules/tcompare/lib/format.js:211:58)
        Format.printValue (node_modules/tcompare/lib/format.js:140:21)
        Format.print (node_modules/tcompare/lib/format.js:78:51)
        Same.simplePrint (node_modules/tcompare/lib/same.js:134:8)
        Same.diff (node_modules/tcompare/lib/same.js:434:35)
        Same.print (node_modules/tcompare/lib/same.js:146:37)
        simple (node_modules/tcompare/index.js:9:11)
        node_modules/tcompare/index.js:13:3
      at:
        line: 390
        column: 31
        file: node_modules/tcompare/lib/format.js
        function: Format.arrayIsEmpty
      type: TypeError
      tapCaught: returnedPromiseRejection
      test: "Wechaty <> Tap `Error: undefined is not a function`"
      source: |2
          arrayIsEmpty () {
            return this.objectAsArray.length === 0
        ------------------------------^
          }
          arrayEmpty () {
      ...
    
    1..1
    # failed 1 test

same() Error: undefined is not a function

$ ./src/t.ts 
TAP version 13
# Subtest: Wechaty <> Tap
    not ok 1 - undefined is not a function
      ---
      stack: >
        Object.createSeq [as createNode]
        (node_modules/yaml/dist/Schema-88e323a7.js:35:16)
      
        createNode (node_modules/yaml/dist/Schema-88e323a7.js:444:41)
      
        Schema.createNode (node_modules/yaml/dist/Schema-88e323a7.js:507:12)
      
        Schema.createPair (node_modules/yaml/dist/Schema-88e323a7.js:515:20)
      
        Object.createMap [as createNode] (node_modules/yaml/dist/Schema-88e323a7.js:13:63)
      
        createNode (node_modules/yaml/dist/Schema-88e323a7.js:444:41)
      
        Schema.createNode (node_modules/yaml/dist/Schema-88e323a7.js:507:12)
      
        Schema.createPair (node_modules/yaml/dist/Schema-88e323a7.js:515:20)
      
        Object.createMap [as createNode] (node_modules/yaml/dist/Schema-88e323a7.js:13:63)
      
        createNode (node_modules/yaml/dist/Schema-88e323a7.js:444:41)
      at:
        line: 35
        column: 16
        file: node_modules/yaml/dist/Schema-88e323a7.js
        function: Object.createSeq
        method: createNode
      type: TypeError
      tapCaught: returnedPromiseRejection
      test: Wechaty <> Tap
      source: |2
          if (obj && obj[Symbol.iterator]) {
            for (const it of obj) {
        ---------------^
              const v = schema.createNode(it, ctx.wrapScalars, null, ctx);
              seq.items.push(v);
      ...
    
    1..2
    # test count(1) != plan(2)
    # failed 1 test
not ok 1 - Wechaty <> Tap # time=42.396ms

1..1
# failed 1 test
# time=54.162ms

Reproduciable minimum code

NPM Versions:

npm install tap@15.0.10 wechaty@1.9.8 wechaty-puppet-mock@1.9.1

Code:

#!/usr/bin/env -S node --no-warnings --loader ts-node/esm

import { test } from 'tap'  // tap@15.0.10

import { WechatyBuilder } from 'wechaty'  // wechaty@1.9.8
import { PuppetMock }     from 'wechaty-puppet-mock'  // wechaty-puppet-mock@1.9.1

test('Wechaty <> Tap reproduce bug', async t => {
  const puppet = new PuppetMock()
  const wechaty = WechatyBuilder.build({ puppet })

  t.same(wechaty, undefined, 'should have wechaty registered after use plugin')
  /**
   * Error: Cannot read property 'length' of null
   *
   * stack: |
   *    Format.arrayIsEmpty (node_modules/tcompare/lib/format.js:390:31)
   */

  t.equal(wechaty, undefined, 'should have wechaty registered after use plugin')
  /**
   * Error: undefined is not a function
   *
   * stack: >
   *    Object.createSeq [as createNode]
   *    (node_modules/yaml/dist/Schema-88e323a7.js:35:16)
   */
}).catch(console.error)

Cross-posted from:

@isaacs
Copy link
Member

isaacs commented Nov 26, 2021

It's a bug in the MemoryCard module. huan/memory-card#39

The presence of this function tells tap that it's an array-like, but then the iterator function returns an invalid response, so Array.from() fails.

Nevertheless, tcompare should handle this case more gracefully. Leaving open, but I guess the solution here is to catch the error from Array.from(), and then if it does throw, mark the object as not array-like, no matter what it looks like, and back up and re-try the formatting operation with that new info.

@isaacs
Copy link
Member

isaacs commented Nov 26, 2021

Even more minimal example:

const t = require('tap')
t.test('same', async t => {
  t.same({ [Symbol.iterator] () { return {} } }, undefined)
})
t.test('equal', async t => {
  t.equal({ [Symbol.iterator] () { return {} } }, undefined)
})

@huan
Copy link
Author

huan commented Nov 27, 2021

@isaacs Thank you very much for pointing the problem out!

I believe I have fixed the iterator problem in the MemoryCard (this commit) by removing the [Symbol.iterator]() entrance and it should compatible with the current version of the Tap.

And I totally agree that the Tap should validate the [Symbol.iterator]() and ignore it if it does not follow the array convention.

BTW: could you also take a look at the below issue? I believe it's a blocker for ESM module developers/users when they need to publish binary commands under the Windows platform:

Thank you very much!

@isaacs
Copy link
Member

isaacs commented Dec 6, 2021

Anyone encountering this can fix it with npm update tcompare, or reinstall tap.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants