Angular testing - test.ts not found - javascript

I'm trying to follow the official Angular docs to set up testing for an Angular project - https://angular.io/guide/testing#service-tests
I've downloaded the sample Angular project from the page above, using the first (top) link. I've done an npm install and when I run ng serve it builds fine.
When I run ng test using the CLI, I get the message:
ERROR in Entry module not found: Error: Cant' resolve 'C:Code\testing\src\test.ts' in 'C:\Code\testing'
ERROR in error TS6053: File 'C:Code\testing\src\test.ts' not found.
I looked at this question - How to resolve test.ts when running ng test?, but in that case the file actually exists, but in the Angular example project it doesn't exist at all.
(When I first ran ng test I originally got a message about Jasmine Marbles being missing, which I resolved using:)
npm install jasmine-marbles --save
The documentation says:
You can fine-tune many options by editing the karma.conf.js and the
test.ts files in the src/ folder.
So I know the test.cs is some kind of configuration file, but how do I generate it? It doesn't exist in the Angular 'live example' project either. And how do I know that a test.cs I generate will work reliably with this project?

I used #joshbaeha's suggestion to ng new a new Angular 5 project and copied the test.ts file, which appears to be completely generic and not reliant on project structure or anything else. Everything is now working. Here it is:
test.ts
// This file is required by karma.conf.js and loads recursively all the .spec and framework files
import 'zone.js/dist/zone-testing';
import { getTestBed } from '#angular/core/testing';
import {
BrowserDynamicTestingModule,
platformBrowserDynamicTesting
} from '#angular/platform-browser-dynamic/testing';
declare const require: any;
// First, initialize the Angular testing environment.
getTestBed().initTestEnvironment(
BrowserDynamicTestingModule,
platformBrowserDynamicTesting()
);
// Then we find all the tests.
const context = require.context('./', true, /\.spec\.ts$/);
// And load the modules.
context.keys().map(context);

I don't know whether you can generate just the test.ts file or not, but as far as i know this file is automatically generated when you create a new angular project using angular-cli. So you can just create a new project using angular-cli then copy the src/test.ts file from that new project

Related

Jest not recognising JQuery Object ($)

I have used JavaScript to created a simple web application to measure how much time I spend on different projects.
I want to test the code with Jest and this works fine until I try to test a function that contains the JQuery object ($).
This is the error message I get:
ReferenceError: $ is not defined
The answers I have found online tells me that I need to add a jQuery dependency in my global object, which I have done. Below is my package.json file:
"jest": {
"setupFiles": ["PathToSetupFile/setup-jest.js"],
"type": "module"
and my setup-jest.js:
import $ from 'jquery';
global.$ = global.jQuery = $;
I am now met with a new error message:
SyntaxError: Cannot use import statement outside a module
I cannot find any further information on how to fix this. A few resources tell me I need to update my jest.config.js file but this file does not exist anywhere in my node modules.
I thought it would be helpful to start completely from the beginning and therefore address a much wider scope but never the less provide the exact answer to your problem at the end of my response here.
In PowerShell CD to your project folder
Install the jest node modules locally into your project folder using
npm install --save-dev jest
Install jest globally so you can use it as a CLI command
npm install jest -g
This installs Jest globally i.e. to your user profile %APPDATA%\npm location
Ensure %APPDATA%\npm is in your user profile environment PATH variable (in Windows settings, "Edit Environment variables for your account")
Check in your PowerShell console that it is in your path using $Env:PATH. (If your %APPDATA%\npm path still isn't showing then restart the PowerShell window, if the terminal is inside VSCode then you will have to restart VSCode so that the terminal inherits the new environment)
In order to import jquery you will need to a) install jquery and b) define a setup file for jest which is referenced in jest.config.js created using jest --init in your project folder.
Install jquery -
npm install --save-dev jquery
Generate jest.config.js -
jest --init
The following questions will help Jest to create a suitable configuration for your project
√ Would you like to use Typescript for the configuration file? ... no
√ Choose the test environment that will be used for testing » jsdom (browser-like)
√ Do you want Jest to add coverage reports? ... yes
√ Which provider should be used to instrument code for coverage? » v8
√ Automatically clear mock calls, instances, contexts and results before every test? ... yes
✏️ Modified your\project\folder\package.json
📝 Configuration file created at jest.config.js
If you don't specify the jsdom (browser-like) test environment then running code under test that uses jquery will yield an error of "jQuery requires a window with a document"
But this means the 'jest-environment-jsdom' must now be installed
(As of Jest 28 "jest-environment-jsdom" is no longer shipped by default, make sure to install it separately.) -
npm install --save-dev jest-environment-jsdom
Edit jest.config.js
Change
// setupFiles: [],
To
setupFiles: [ './jest.setup.js' ],
N.B. the "./" prefix is required otherwise jest will state it cannot find the jest.setup.js file.
The create jest.setup.js in your project folder and add the following -
const $ = require('jquery');
global.$ = global.jQuery = $;
Node uses the CommonJS module system (https://nodejs.org/en/knowledge/getting-started/what-is-require/)
so the above syntax is required to work with Node.js

Importing a Javascript plugin into Laravel for use in Vue

So I'm trying to build a Vue component using the features found in the Javascript plugin Cropper JS. My app is built using Laravel 5.6. I first pulled in Cropper JS using NPM:
npm install cropperjs
Next, in my resources/assets/js/app.js file, I added the following lines:
import Cropper from 'cropperjs'
Vue.use(Cropper);
Note: You can assume that Vue has already been properly setup in this case.
This compiles fine when I run 'npm run watch', but when I try to visit my web app (which is just displaying Hello World at this point), I see an error in the console which states:
Uncaught TypeError: Cannot call a class as a function
Now, in the past I have imported & used libraries that were pulled in via npm with the exact same commands. However, in those cases, the folder structure was a bit different, perhaps it was optimized for Vue?
Under my node_modules/cropperjs directory, the folder structure is as follows:
/dist
/src
/types
CHANGELOG.md
LICENSE
package.json
README.md
I hope this information is sufficient in troubleshooting the error.
Thank you.
Cropperjs is not a plugin of Vue, you can use vue-cropper or other image cropper,
if you want use cropperjs,you
let image = document.querySelector('XX')
var cropper = new Cropper(image,{options})

Unable to compile and publish my Typescript library using webpack or TSC

Ive created a library that helps to trace an object state using rx streams and
Im trying to publish it to npm community.
you can check this out In my github repo
I want to compile my library to a single Javascript file and also create a declaration file ".d.ts" for Typescript users.
As i understand, when running $ npm publish i release my entire repository. what i want is to release the dist folder with the library source and declaration file and so the end users will be able to debug my library if necessary through their code so i need also source map.
So first i need to compile my src directory to a single javascript file and i have 2 ways to do so, using tsc or with webpack.
What ive tried so far and you should know:
I used module alias, configured in tsconfig.json.
I separated the library's bussiness logic to multiple files.
I wanted to import internal library's modules using "#lib" prefix.
so in my tsconfig.json i added:
"paths": {
"#lib/*": [
"src/*"
]
},
That alone cause some problems.
first of all running the command:
$ tsc src/index.ts
doesn't work at all and it shows me an error:
src/index.ts(3,15): error TS2307: Cannot find module '#lib/state-traceable'.
src/index.ts(4,15): error TS2307: Cannot find module '#lib/traceable-decorator'. src/index.ts(5,15): error TS2307: Cannot find module '#lib/effect-decorator'.
src/index.ts(6,15): error TS2307: Cannot find module '#lib/meta'.
yet running the command:
$ tsc
does actually works but it compiles each source file and create declaration file for each one of them.
Additionally, it preserves the path alias "#lib/*" instead of compiling it to something javscript compatible with relative paths "../", "./" etc...
Using webpack:
I succeed to bundle all my library sources to a single file and get rid of the "#lib" prefix however im not able to create a single declaration file.
im using "awesome-typescript-loader" plugin for webpack.
I created an issue, thought its a bug but i yet received any response from them:
https://github.com/s-panferov/awesome-typescript-loader/issues/559
Also tried to get some help from Gitter chats, Typescript community, "awesome-typescript-loader" library has no dedicated chat but couldn't find any useful information. Most of the examples ive seen, Typescript library publishers used to create a single file in their source directory: "index.ts" and it makes life easier because you can use tsc and compile that single file to a javascript file.
I hope i will find salvation here.
Some general info about the environment itself:
OS: Windows 10 Pro
Node Version: 9.5.0
npm version: 5.6.0
webpack version: 4.2.0
Please use the path configuration like below
"paths": {
"#lib/state-traceable": ["src/state-traceable.ts"],
"#lib/meta": ["src/meta.ts"],
"#lib/effect-decorator": ["src/effect-decorator.ts"],
"#lib/traceable-decorator": ["src/traceable-decorator.ts"],
"#lib/contracts/*": ["src/contracts/*"],
"#lib/utils/*": ["src/utils/*"],
"#lib/rx-operators/*": ["src/rx-operators/*"]
},

Issue adding third-party (external ) js lib in angular5

I am working on to add jsplumb community js library version with the angular 5 application (Angular CLI: 1.6.1).
With the first build without any configuration to tsconfig.json I get the following error.
ERROR in src/app/jsplumb/jsplumb.component.ts(4,25): error TS6143: Module '../../../node_modules/jsplumb/dist/js/jsplumb.js' was resolved to 'D:/myproj/angular5/myapp/node_modules/jsplumb/dist/js/jsplumb.js', but '--allowJs' is not set.
With "allowJs":true in the tsconfig.json get the following error
ERROR in error TS5055: Cannot write file 'D:/myproj/angular5/myapp/node_modules/jsplumb/dist/js/jsplumb.js' because it would overwrite input file.
Adding a tsconfig.json file will help organize projects that contain both TypeScript and JavaScript files. Learn more at https://aka.ms/tsconfig.
As per tsconfig FAQ
Why am I getting the error TS5055: Cannot write file 'xxx.js' because it would overwrite input file.
with an outDir ("outDir": "./dist/out-tsc") this issue should be resolved. This is already set in my tsconfig.
If we add noEmit to true it simply builds the application, not including any js we get a blank white screen.
Let me know if anyone has tried to include external js with new angular cli and face the same kind of error and what is the solution for the same.
Without any additional option added to tsconfig.json if I try to modify any ts file the application will compile with success and I am able to work. But this does not help while running ng build, to create a deployable binary.
Update Workaround: until the fix in CLI is available. For development (ng serve) remove allowJs from tsconfig.json, when ever you get an error with adding allowJs simply modify a ts file to recompile the applicaiton, this time will compile with success. For production or distribution add back the allowJs to tsconfig.json run the application run with ng build --prod --watch=auto you should see the error about overriding the JS file in node_module, simple modify a ts file it should rebuild as --watch=auto is there in command but this time with sucess.
If you're trying to import a library to Angular 2+, you should do it inside angular-cli.json.
There you have a scripts key where you should configure the desired imports. They are generally like:
{
...
"scripts": [
"../node_modules/MODULE/file.js"
],
...
}
Also you can import the library (not recommended) inside your main index.html, using <script src="/path_relative_to_root/file.js">
https://github.com/angular/angular-cli/wiki/angular-cli
https://github.com/angular/angular-cli/wiki/stories-global-scripts
Angular Cli Webpack, How to add or bundle external js files?
have you tried upgrading it to angular 6? maybe they fixed this in the new version.
ng update #angular/cli

How to import JavaScript file into angular2

I am having trouble figuring out how to import a javascript file into my angular2 project. It is a file that is not a module that is apart of npm and the only instructions I have been able to find is using npm which is not an option here.
I am using angular cli and in my angular-cli.json file I have:
{
"apps": [
"styles": [..],
"scripts": ["../pathtomyjs/file.js"]
]}
I ran ng build and ng serve and when I open up my app and look at the web console and try referencing the function that is in my js file, I am able to do so successfully.
Example in the console I type in:
var test = MyObject;
and I get test = {};
However, when I try do
let test = MyObject;
in my component .ts file I get :
home.component.ts (10,11): Cannot find name 'MyObject'.)
Not sure how to do this in Angular2.
Thanks!
Do:
declare var MyObject: any;
let test = MyObject;
Or:
let test = (<any> MyObject);
For jQuery:
declare var jQuery: any;
jQuery.ajax({ ... });
Is it a 3rd party library? you'll have to let the typescript compiler know where the type definition files are. Normally, it looks under node_modules/#types folder. For example, if you wanted to use jQuery, you would install the necessary type definition files by running:
npm install #types/jquery
I did a deep dive on this here:
This is a great question and I'm glad you ask because I wish I had what I'm about to write the first time I encountered this little problem. This is a typescript/javascript and webpack issue before it is an angular issue. I definitely am planning a writeup on my blog soon as possible.
Your Scenario:
You run
npm install mathjs
Now you try to use math.js from a component:
Find math.js dist js file (node_modules/mathjs/dist/math.js) and reference like this
import {mathjs} from "../../node_modules/mathjs/dist/math";
But you get error message saying "set --allowJS". You do that like this:
Set --allowJS in config (tsconfig.json)
{ "compilerOptions": {
"allowJs": true, ...
Now you get:
ERROR in ../node_modules/mathjs/dist/math.js (12209,13): Unreachable
code detected.
Looking in the math.js source, you see that it is an old school module but there is no root wrapper function (one function to bring them all and in the darkness bind them..) (more on that later).
Solution: install a typings file for the target lib (#types/mathjs)
read more...
I put my js files into app/assets/scripts and load them in index.html
<script src="assets/scripts/foobar.js"></script> . This is for a ionic2 / angular2 project.
In the module you have to define your functions like this in global scope of the module file
declare var myFancyFunction;

Categories

Resources