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

Requires ESM module transformation #39

Closed
wSedlacek opened this issue Sep 18, 2021 · 7 comments
Closed

Requires ESM module transformation #39

wSedlacek opened this issue Sep 18, 2021 · 7 comments
Labels

Comments

@wSedlacek
Copy link

When trying to import this into a @nrwl/nx configured workspace I get the following error:

  ● Test suite failed to run

    Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

    By default "node_modules" folder is ignored by transformers.

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
     • 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/configuration
    For information about custom transformations, see:
    https://jestjs.io/docs/code-transformation

    Details:

    /Volumes/MacOS-Data/Home/wsedlacek/Devolpement/angular/brandingbrand/node_modules/rxjs/dist/types/internal/scheduler/AsyncScheduler.d.ts:1
    ({"Object.<anonymous>":function(module,exports,require,__dirname,__filename,jest){import { Scheduler } from '../Scheduler';
                                                                                      ^^^^^^

    SyntaxError: Cannot use import statement outside a module

      at Runtime.createScriptFromCode (../../../node_modules/jest-runtime/build/index.js:1679:14)
      at Object.<anonymous> (../../../node_modules/@hirez_io/observer-spy/src/fake-time.ts:2:1)

It appears that using this internal rxjs import results in an invalid import in some enviorments.

import { AsyncScheduler } from 'rxjs/internal/scheduler/AsyncScheduler';

@kylecordes
Copy link

This is a significant obstacle in what is otherwise an amazing piece of work -- thank you @shairez !

By researching the error elsewhere, we found a commonly used workaround: configure Jest to transform library code (in this case, include RxJS), to make it possible to work with the deep import. For example, to do that with Nx, adjust jest.preset.js:

const nxPreset = require('@nrwl/jest/preset');

// Some tests use hirez_io's Jest spy, which uses RxJS internals.
const esModules = ['lodash-es', '@hirez_io', 'rxjs'].join('|');

module.exports = {
  ...nxPreset,
  // Transform (compile) ES5 code for Jest module use:
  transformIgnorePatterns: [`/node_modules/(?!${esModules})`]
};

However, this is a somewhat problematic workaround, not a good solution, because it is slow.

Possible better solutions:

  • Persuade RxJS to publish the AsyncScheduler class so that it can be imported without reaching into internal, thus not requiring the transform.
  • Replace the deep import with a runtime hack, i.e. grab something exported (probably the asyncScheduler instance) and walk its references to grab the class.

@shairez
Copy link
Member

shairez commented Nov 22, 2021

Thanks @wSedlacek and @kylecordes !
Sorry about the delay, had a busy month and half
I'm planning to work on this issue this week, will update

@yharaskrik
Copy link

@shairez could I help with this? Would I be able to open a PR to get it fixed? I think its our last roadblock to updating our repo to v13

fwiech added a commit to fwiech/codewaffle that referenced this issue Dec 9, 2021
does not work at the moment with jest.
See hirezio/observer-spy#39
@dean-g
Copy link

dean-g commented Dec 10, 2021

@shairez Does this get fixed? my test is failing with the same error for the 2.1.0 version

Please advise me the correct version to download

`
SyntaxError: Cannot use import statement outside a module

  at Runtime.createScriptFromCode (../../../../../node_modules/jest-runtime/build/index.js:1728:14)
  at Object.<anonymous> (../../../../../node_modules/@hirez_io/observer-spy/src/fake-time.ts:2:1)

`

@github-actions
Copy link

🎉 This issue has been resolved in version 2.1.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

@shairez
Copy link
Member

shairez commented Dec 10, 2021

I think I managed to solve it
Please update to the latest version (2.1.1) and let me know if fakeTime works the same for you

@MrGung
Copy link

MrGung commented Feb 27, 2024

I am on version 2.2.0 (Angular 17.1.0, Jest 29.7.0) - the following test

        it('provides list of employess after client is loaded - with observable-spy', () => {

            const {service, dataAccessMock, currentClient$} = createService();

            jest.spyOn(dataAccessMock, 'getEmployeeList')
                .mockReturnValue(of([{surname: 'Tester'}] as EmployeeDto[]));
            currentClient$.next(makeHttpRequestIsSuccess(new Client({consultant_number: 1, client_number: 1})));

            const receivedEmployees = subscribeSpyTo(service.employees$);

            expect(receivedEmployees.getLastValue()).toStrictEqual(
                    expect.objectContaining(
                        {
                            successResult: {
                                employees: [expect.objectContaining({surname: 'Tester'})],
                                client: expect.objectContaining({consultant_number: 1, client_number: 1})
                            }
                        }));
        });

(still) gives me

Test suite failed to run

    Jest encountered an unexpected token

    Jest failed to parse a file. This happens e.g. when your code or its dependencies use non-standard JavaScript syntax, or when Jest is not configured to support such syntax.

    Out of the box Jest supports Babel, which will be used to transform your files into valid JS based on your Babel configuration.

    By default "node_modules" folder is ignored by transformers.

    Here's what you can do:
     • If you are trying to use ECMAScript Modules, see https://jestjs.io/docs/ecmascript-modules for how to enable it.
     • If you are trying to use TypeScript, see https://jestjs.io/docs/getting-started#using-typescript
     • 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/configuration
    For information about custom transformations, see:
    https://jestjs.io/docs/code-transformation

    Details:

    D:\DEV\frontend\node_modules\@angular\core\fesm2022\testing.mjs:7
    import { ɵDeferBlockState, ɵtriggerResourceLoading, ɵrenderDeferBlockState, ɵCONTAINER_HEADER_OFFSET, ɵgetDeferBlocks, InjectionToken, inject as inject$1, ɵNoopNgZone, NgZone, ɵEffectScheduler, ApplicationRef, getDebugNode, RendererFactory2, ɵstringify, ɵReflectionCapabilities, Directive, Component, Pipe, NgModule, ɵgetAsyncClassMetadataFn, ɵgenerateStandaloneInDeclarationsError, ɵDeferBlockBehavior, ɵUSE_RUNTIME_DEPS_TRACKER_FOR_JIT, ɵdepsTracker, ɵgetInjectableDef, resolveForwardRef, ɵNG_COMP_DEF, ɵisComponentDefPendingResolution, ɵresolveComponentResources, ɵRender3NgModuleRef, ApplicationInitStatus, LOCALE_ID, ɵDEFAULT_LOCALE_ID, ɵsetLocaleId, ɵRender3ComponentFactory, ɵcompileComponent, ɵNG_DIR_DEF, ɵcompileDirective, ɵNG_PIPE_DEF, ɵcompilePipe, ɵNG_MOD_DEF, ɵtransitiveScopesFor, ɵpatchComponentDefWithScope, ɵNG_INJ_DEF, ɵcompileNgModuleDefs, ɵclearResolutionOfComponentResourcesQueue, ɵrestoreComponentResolutionQueue, provideZoneChangeDetection, Compiler, ɵDEFER_BLOCK_CONFIG, COMPILER_OPTIONS, Injector, ɵisEnvironmentProviders, ɵNgModuleFactory, ModuleWithComponentFactories, ɵconvertToBitFlags, InjectFlags, ɵsetAllowDuplicateNgModuleIdsForTest, ɵresetCompiledComponents, ɵsetUnknownElementStrictMode, ɵsetUnknownPropertyStrictMode, ɵgetUnknownElementStrictMode, ɵgetUnknownPropertyStrictMode, runInInjectionContext, EnvironmentInjector, ɵflushModuleScopingQueueAsMuchAsPossible } from '@angular/core';
    ^^^^^^

    SyntaxError: Cannot use import statement outside a module

       7 |     }
       8 | };
    >  9 | import 'jest-preset-angular/setup-jest';
         | ^
      10 |

      at Runtime.createScriptFromCode (../../../node_modules/jest-runtime/build/index.js:1505:14)
      at Object.<anonymous> (../../../node_modules/jest-preset-angular/setup-jest.js:3:24)
      at Object.<anonymous> (../../../test-setup.base.ts:9:1)
      at Object.<anonymous> (src/test-setup.ts:1:1)

The workaround provided by @kylecordes did not work for me - I haven't looked deeper, though, there...

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

No branches or pull requests

6 participants