stevermeister / ngx-cookie-service

Angular (4.2+ ...12) service for cookies. Originally based on the `ng2-cookies` library.
https://www.npmjs.com/package/ngx-cookie-service
MIT License
547 stars 90 forks source link

Adding ngx-cookie-service broke Jest tests #39

Closed thomasdtucker closed 6 years ago

thomasdtucker commented 6 years ago

Expected Behavior

Dependency should import correctly and operate normally during test runs

Actual Behavior

ttucker:rac-web-admin thomastucker$ yarn test yarn run v1.9.2 $ jest PASS src/app/auth/reducers/auth.reducer.spec.ts AuthReducer undefined action ✓ should return the default state (9ms) LOGIN_SUCCESS ✓ should add a user set loggedIn to true in auth state (1ms) LOGOUT ✓ should logout a user (1ms)

PASS src/app/+promotions/containers/add-promotion-page/add-promotion-page.component.spec.ts AddPromotionPageComponent ✓ should create (120ms)

PASS src/app/core/containers/page-not-found/page-not-found.component.spec.ts PageNotFoundComponent ✓ should create (116ms)

PASS src/app/core/containers/app/app.component.spec.ts AppComponent ✓ should create (120ms)

PASS src/app/core/components/header/header.component.spec.ts HeaderComponent ✓ should create (185ms)

PASS src/app/core/components/sidenav/sidenav.component.spec.ts SidenavComponent ✓ should create (234ms)

FAIL src/app/app-routing.module.spec.ts ● Test suite failed to run

Jest encountered an unexpected token

This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

Here's what you can do:
 • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
 • If you need a custom transformation specify a "transform" option in your config.
 • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html

Details:

/Users/thomastucker/dev/rac-web-admin/node_modules/ngx-cookie-service/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){export * from './cookie-service/cookie.service';
                                                                                         ^^^^^^

SyntaxError: Unexpected token export

  15 | export class AuthGuard implements CanActivate {
  16 |   constructor(
> 17 |     private cookie: CookieService,
     |                            ^
  18 |     private store: Store<fromAuth.State>,
  19 |   ) {}
  20 | 

  at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)
  at Object.<anonymous> (src/app/auth/services/auth-guard.service.ts:17:28)

FAIL src/app/auth/services/auth-guard.service.spec.ts ● Test suite failed to run

Jest encountered an unexpected token

This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

Here's what you can do:
 • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
 • If you need a custom transformation specify a "transform" option in your config.
 • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html

Details:

/Users/thomastucker/dev/rac-web-admin/node_modules/ngx-cookie-service/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){export * from './cookie-service/cookie.service';
                                                                                         ^^^^^^

SyntaxError: Unexpected token export

  15 | export class AuthGuard implements CanActivate {
  16 |   constructor(
> 17 |     private cookie: CookieService,
     |                            ^
  18 |     private store: Store<fromAuth.State>,
  19 |   ) {}
  20 | 

  at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)
  at Object.<anonymous> (src/app/auth/services/auth-guard.service.ts:17:28)

FAIL src/app/auth/effects/auth.effects.spec.ts ● Test suite failed to run

Jest encountered an unexpected token

This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

Here's what you can do:
 • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
 • If you need a custom transformation specify a "transform" option in your config.
 • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html

Details:

/Users/thomastucker/dev/rac-web-admin/node_modules/ngx-cookie-service/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){export * from './cookie-service/cookie.service';
                                                                                         ^^^^^^

SyntaxError: Unexpected token export

  17 |   @Effect()
  18 |   login$ = this.actions$.pipe(
> 19 |     ofType<AuthActions.Login>(AuthActions.AuthActionTypes.LOGIN),
     |                            ^
  20 |     map(action => action.payload.credentials),
  21 |     flatMap((credentials: Credentials) =>
  22 |       this.authService.login(credentials).pipe(

  at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)
  at Object.<anonymous> (src/app/auth/effects/auth.effects.ts:19:28)

FAIL src/app/+promotions/promotions.module.spec.ts ● Test suite failed to run

Jest encountered an unexpected token

This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

Here's what you can do:
 • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
 • If you need a custom transformation specify a "transform" option in your config.
 • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html

Details:

/Users/thomastucker/dev/rac-web-admin/node_modules/ngx-cookie-service/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){export * from './cookie-service/cookie.service';
                                                                                         ^^^^^^

SyntaxError: Unexpected token export

  15 | export class AuthGuard implements CanActivate {
  16 |   constructor(
> 17 |     private cookie: CookieService,
     |                            ^
  18 |     private store: Store<fromAuth.State>,
  19 |   ) {}
  20 | 

  at ScriptTransformer._transformAndBuildScript (node_modules/jest-runtime/build/script_transformer.js:403:17)
  at Object.<anonymous> (src/app/auth/services/auth-guard.service.ts:17:28)

PASS src/app/auth/containers/login-page/login-page.component.spec.ts Login Page ✓ should compile (390ms)

Test Suites: 4 failed, 7 passed, 11 total Tests: 9 passed, 9 total Snapshots: 4 passed, 4 total Time: 3.301s Ran all test suites. error Command failed with exit code 1. info Visit https://yarnpkg.com/en/docs/cli/run for documentation about this command.

Steps to Reproduce the Problem

ng create app add jest https://brianflove.com/2018/05/26/angular-jest-testing/ add ngx-cookie-service view tests failing

Specifications

danil-z commented 6 years ago

I've tried following jest config without luck:

  preset: 'jest-preset-angular',
  transform: {
    '^.+\\.(ts|html)$': '<rootDir>/node_modules/jest-preset-angular/preprocessor.js',
    '^.+\\.js$': 'babel-jest'
  },
  transformIgnorePatterns: [
    'node_modules/(?!@ngrx)',
    'node_modules/(?!ngx-cookie-service)'
  ]

with babel packages installed (npm i -D babel-jest babel-preset-env)

evtk commented 6 years ago

checking in to report the same issue.

adover commented 6 years ago

Same here. Not found a fix yet.

flakolefluk commented 6 years ago

The problem is that ngx-cookie-service is compiled to es2015, which must be transformed before tests. you can make it work by installing babel-jest and babel-prest-env

npm install --save-dev babel-jest babel-preset-env

then in your package json where the jest config is:

    "jest": {
        ....some stuff in here
        "transformIgnorePatterns": [
              "node_modules/(?!(ngx-cookie-service)/)"
        ],
        "transform": {
         "^.+\\.js$": "babel-jest"
    }

and create a .babelrc file in the project root with

{
  "presets": ["env"]
}
kedruff commented 6 years ago

The problem is that ngx-cookie-service is compiled to es2015, which must be transformed before tests.

Actually, the bigger issue is that ngx-cookie-service isn't bundled in proper Angular Package Format... if it were, it would work no problem.

flakolefluk commented 6 years ago

The problem is that ngx-cookie-service is compiled to es2015, which must be transformed before tests.

Actually, the bigger issue is that ngx-cookie-service isn't bundled in proper Angular Package Format... if it were, it would work no problem.

The issue is related to Jest not transforming the files in node_modules folder. Changing the source tsconfig to compile to es5 would solve the issue as well without needing to install babel-jest or anything. Angular Package Format includes multiple output formats, but if you import es2015 in your test, it would still fail.

dereklin commented 5 years ago

I combine these solutions to get my testing somewhat working: https://github.com/7leads/ngx-cookie-service/issues/39#issuecomment-432833790 and https://github.com/meltedspark/angular-builders/issues/85#issuecomment-437922158

I have a nrwl/nx mono repo. I have been using jest to test everything on one-go. All the tests pass with no issues.

I try to convert one app from karma to jest so that I can do this with jest:

ng test app1

I get this error:

/workspace/node_modules/ngx-cookie-service/index.js:1
({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,global,jest){export * from './cookie-service/cookie.service';
                                                                                             ^^^^^^

With the combined solution, when I have my transform like this:

  transform: {
    '^.+\\.(ts|html)$': 'jest-preset-angular/preprocessor.js'
  },

Running tests for the whole mono repo works, but the individual app will fail.

When I have it like:

  transform: {
    '^.+\\.(ts|html)$': 'jest-preset-angular/preprocessor.js',
    '^.+\\.js$': 'babel-jest'
  },

The individual app tests will pass, but the mono repo tests will fail ...

KiranMantha commented 5 years ago

Hi All,

I just found a solution to this problem.

  1. add a folder __mocks__ in root folder where the node_modules folder reside.

  2. add ngx-cookie-service.js file in __mocks__ folder and place the following code:

    class MockCookieService {
    constructor() {
      this._cookieReg = {};
    }
    check(name) {
      return this._cookieReg[name] ? true : false;
    }
    get(name) {
      return this._cookieReg[name];
    }
    getAll() {
      return this._cookieReg;
    }
    set(
      name,
      value,
      expires,
      path,
      domain,
      secure,
      sameSite
    ) {
      this._cookieReg[name] = name + '=' + value;
    }
    delete(name, path, domain) {
      delete this._cookieReg[name];
    }
    deleteAll(path, domain) {
      this._cookieReg = {};
    }
    }
    
    module.exports = {
    CookieService: MockCookieService
    };
  3. now in actual component spec file, place the following code:

import { CookieService } from 'ngx-cookie-service';
jest.genMockFromModule('ngx-cookie-service');
TestBed.configureTestingModule({
  declarations: [Your-Component],
  providers: [CookieService]
})
  1. now run jest the tests will run fine.
leonaAtkins commented 5 years ago

Hi All,

I just found a solution to this problem.

  1. add a folder __mocks__ in root folder where the node_modules folder reside.
  2. add ngx-cookie-service.js file in __mocks__ folder and place the following code:
class MockCookieService {
  constructor() {
    this._cookieReg = {};
  }
  check(name) {
    return this._cookieReg[name] ? true : false;
  }
  get(name) {
    return this._cookieReg[name];
  }
  getAll() {
    return this._cookieReg;
  }
  set(
    name,
    value,
    expires,
    path,
    domain,
    secure,
    sameSite
  ) {
    this._cookieReg[name] = name + '=' + value;
  }
  delete(name, path, domain) {
    delete this._cookieReg[name];
  }
  deleteAll(path, domain) {
    this._cookieReg = {};
  }
}

module.exports = {
  CookieService: MockCookieService
};
  1. now in actual component spec file, place the following code:
import { CookieService } from 'ngx-cookie-service';
jest.genMockFromModule('ngx-cookie-service');
TestBed.configureTestingModule({
  declarations: [Your-Component],
  providers: [CookieService]
})
  1. now run jest the tests will run fine.

I've tried this but still getting the errors.

I'm still getting

Jest encountered an unexpected token

This usually means that you are trying to import a file which Jest cannot parse, e.g. it's not plain JavaScript.

By default, if Jest sees a Babel config, it will use that to transform your files, ignoring "node_modules".

Here's what you can do:
 • To have some of your "node_modules" files transformed, you can specify a custom "transformIgnorePatterns" in your config.
 • If you need a custom transformation specify a "transform" option in your config.
 • If you simply want to mock your non-JS modules (e.g. binary assets) you can stub them out with the "moduleNameMapper" config option.

You'll find more details and examples of these config options in the docs:
https://jestjs.io/docs/en/configuration.html

I've switched to ngx-cookie instead, which uses an additional dependency which isn't ideal but at least the tests work.

JoA-MoS commented 5 years ago

Upgrading ngx-cookie-service to ^2.1.0 fixed the problem for me. If you can try updating ngx-cookie-service

EDIT: Also, you need to have the __mocks__ file as mentioned by @KiranMantha. I did not need to add it to all my tests as indicated in step 3 as jest will do that automatically when it finds in import in the mocks folder

kburns1 commented 5 years ago

Still running into this issue under ^2.1.0. Any one else?

daddyschmack commented 5 years ago

Yes, still encountering issue, and followed the instructions to implement babel.. no joy...

rbinsztock commented 5 years ago

Why this issue is closed ?

I updated from 2.1.0 to 2.2.0 and the error disappear.

FloNeu commented 8 months ago

Was looking for something different - but as i ran into the 'same' problem with jest and another library - related to jest not transforming esm modules - i will leave this link here to save someone the headacke https://stackoverflow.com/questions/70571424/angular-v13-jest-with-nx-test-syntaxerror-cannot-use-import-statement-outside/70615775#70615775