dsherret / ts-nameof

nameof in TypeScript
MIT License
492 stars 23 forks source link

Using ts-nameof with Vue Unit Tests + jest #88

Closed Shinigami92 closed 4 years ago

Shinigami92 commented 4 years ago

My unit test is failing with ReferenceError: nameof is not defined

My current jest.config.js

module.exports = {
  preset: '@vue/cli-plugin-unit-jest/presets/typescript-and-babel',
  reporters: [
    'default',
    ['jest-junit', { outputDirectory: 'reports/unit' }],
    ['jest-html-reporter', { outputPath: 'reports/unit/test-report.html' }]
  ],
  collectCoverage: true,
  collectCoverageFrom: ['**/*.ts'],
  coverageReporters: ['lcov'],
  setupFiles: ['./tests/unit/jest.dropmultivueinstancewarning.js'],
  setupFilesAfterEnv: ['./tests/unit/jest.setup.js'],
  globals: {
    'ts-jest': {
      astTransformers: ['ts-nameof']
    }
  }
};

globals ts-jest astTransformers seems to have no effect 😕

My tsconfig.json

{
  "compilerOptions": {
    "target": "es5",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    },
    "lib": ["esnext", "dom", "dom.iterable", "scripthost"],
    "plugins": [{ "name": "typescript-tslint-plugin" }],
    "noUnusedLocals": true,
    "allowJs": true,
    "emitDecoratorMetadata": true,
    "downlevelIteration": true,
    "removeComments": true
  },
  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "tests/**/*.ts", "tests/**/*.tsx"],
  "exclude": ["node_modules"]
}

The project itself is working fine! Only jest test fails

Shinigami92 commented 4 years ago

I found a terrifying workaround 😂

window.nameof = (o: Function) => {
  try {
    o();
  } catch (error) {
    const prefix = "Cannot read property '";
    const suffix = "' of undefined";
    const value = (error as Error).message.slice(prefix.length, -suffix.length);
    return value;
  }
};

describe("HelloWorld.vue", () => {
  it("renders props.msg when passed", () => {
    const msg = "new message";
    const name1 = "name1";
    const name2 = "name2";
    const wrapper = shallowMount(HelloWorld, {
      propsData: { msg }
    });
    expect(wrapper.text()).toMatch(msg);
    expect(wrapper.text()).toMatch(name1);
    expect(wrapper.text()).toMatch(name2);
  });
});
Shinigami92 commented 4 years ago

I think I tried everything now :( Still no success

I tried:

module.exports = merge.recursive(vuePreset, { reporters: [ 'default', ['jest-junit', { outputDirectory: 'reports/unit' }], ['jest-html-reporter', { outputPath: 'reports/unit/test-report.html' }] ], collectCoverage: true, collectCoverageFrom: ['*/.ts'], coverageReporters: ['lcov'], setupFiles: ['./tests/unit/jest.dropmultivueinstancewarning.js'], setupFilesAfterEnv: ['./tests/unit/jest.setup.js'], globals: { 'ts-jest': { babelConfig: false, // also tried true compiler: 'ttypescript', astTransformers: ['ts-nameof'] } } });


- Also tried tsconfig.json

```json
{
  "compilerOptions": {
    "target": "es5",
    "module": "esnext",
    "strict": true,
    "jsx": "preserve",
    "importHelpers": true,
    "moduleResolution": "node",
    "experimentalDecorators": true,
    "esModuleInterop": true,
    "allowSyntheticDefaultImports": true,
    "sourceMap": true,
    "baseUrl": ".",
    "paths": {
      "@/*": ["src/*"]
    },
    "lib": ["esnext", "dom", "dom.iterable", "scripthost"],
    "plugins": [{ "transform": "ts-nameof", "type": "raw" }, { "name": "typescript-tslint-plugin" }],
    "noUnusedLocals": true,
    "allowJs": true,
    "emitDecoratorMetadata": true,
    "downlevelIteration": true,
    "removeComments": true
  },
  "include": ["src/**/*.ts", "src/**/*.tsx", "src/**/*.vue", "tests/**/*.ts", "tests/**/*.tsx"],
  "exclude": ["node_modules"],
  "plugins": [{ "transform": "ts-nameof", "type": "raw" }]
}

And I think I tried every combination of the above!

Still getting ReferenceError: nameof is not defined

Very frustrating


My mock is not a solution, because we also use nameof<MyComponent>() in some places

dsherret commented 4 years ago

@Shinigami92 maybe try using https://github.com/nonara/ts-patch/ and see if that fixes the problem.

Shinigami92 commented 4 years ago

@Shinigami92 maybe try using https://github.com/nonara/ts-patch/ and see if that fixes the problem.

First we need to resolve some (macos?) bugs...

https://github.com/nonara/ts-patch/issues/3 https://github.com/nonara/ts-patch/issues/4

Shinigami92 commented 4 years ago

YEEEEEESSSS 🎉 nuff said

dsherret commented 4 years ago

@Shinigami92 oh, it worked? I think I'm going to update the instructions to use it (#92). Seems like an easier setup.

Shinigami92 commented 4 years ago

Yes, but there are some bugs with MacOS (we are working on fixes)

What I needed to do:

  1. yarn add -D ts-patch

  2. tsconfig.json

Add "plugins": [{ "transform": "ts-nameof", "type": "raw" }, /* ... */] to compilerOptions

  1. jest.config.js
    // ...
    globals: {
    'ts-jest': {
    astTransformers: ['ts-nameof']
    }
    }
    // ...

Then Vue's "test:unit": "vue-cli-service test:unit" worked