Optimizing Mocha Chai testing of a simple JavaScript application - mocha.js

I am tasked with testing this index.js file using Mocha Chai Testing:
module.exports = {
addDetails: function() {
let data =[]
data.push("one");
return data
},
deleteDetails: function() {
let data =["one" , "two"]
data.splice(0 , 1)
return data
},
editDetails: function() {
let data =["one"]
data.splice(0 , 1 , "three")
return data
},
updateDetails: function() {
let data = ["one" , "three"]
data.splice(1 , 0 , "two")
return data
},
detailsPop: function() {
let numb = ["one" , "two"]
numb.pop()
return numb
},
concatData: function() {
let data1 = ["one"]
let data2 = ["two"]
let result = data1.concat(data2)
return result
}
}
I am using this virtual environment as my work environment (HackerRank):
Here is the indextest.js file I wrote testing each of the functions in index.js:
var assert = require("assert");
var crud = require('../src/index');
describe('Crud application', function(){
//write your code here
it("testing addDetails", function() {
assert.equal(crud.addDetails(), [ 'one' ], 'addDetails works!');
});
it("testing deleteDetails", function() {
assert.equal(crud.deleteDetails(), [ 'two' ], 'deleteDetails works!');
});
it("testing editDetails", function() {
assert.equal(crud.editDetails(), [ 'three' ], 'editDetails works!');
});
it("testing updateDetails", function() {
assert.equal(crud.updateDetails(), [ 'one', 'two', 'three' ], 'updateDetails works!');
});
it("testing detailsPop", function() {
assert.equal(crud.detailsPop(), [ 'one' ], 'detailsPop works!');
});
it("testing concatData", function() {
assert.equal(crud.concatData(), [ 'one', 'two' ], 'concatData works!');
});
});
My test performance is being scored using score.sh
npm install
npx nyc mocha --timeout 10000 --reporter mocha-junit-reporter --exit
npx nyc --reporter=clover mocha --timeout 10000 --reporter mocha-junit-reporter --exit
node xml-merge.js
My indextest.js is not accepted by score.sh. Here is my console:
user#workspaceew8g7c7x4yebmr8m:/projects/challenge$ npm test
js_crud#1.0.0 test /projects/challenge
mocha --timeout 10000 --reporter mocha-junit-reporter --collectCoverageFrom=src/index.js --exit
npm ERR! Test failed. See above for more details.
user#workspaceew8g7c7x4yebmr8m:/projects/challenge$
What is a better way to test using Mocha Chai? How could I change my indextest.js file to provide better testing for my index.js?

Related

CKEditor5 v.32 on Laravel 8 / Laravel Mix 6

Does anybody have a working webpack.mix.js config for CKEditor5 32 on Laravel 8 (Laravel Mix 6 and Webpack 5) already? I have been banging my head to the wall for the past 8 hours and still could not manage to make it work.
Here is the console error I receive.
Before, when I was using Laravel Mix 5 and Webpack 4, this config solution seemed to be working.
But now all I get are a bunch of the same errors during npm compilation.
Config's snipped that worked for me
const CKEditorWebpackPlugin = require('#ckeditor/ckeditor5-dev-webpack-plugin');
const CKEditorStyles = require('#ckeditor/ckeditor5-dev-utils').styles;
//Includes SVGs and CSS files from "node_modules/ckeditor5-*" and any other custom directories
const CKEditorRegex = {
svg: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/, //If you have any custom plugins in your project with SVG icons, include their path in this regex as well.
css: /ckeditor5-[^/\\]+[/\\].+\.css$/,
};
//Exclude CKEditor regex from mix's default rules
Mix.listen('configReady', config => {
const rules = config.module.rules;
const targetSVG = (/(\.(png|jpe?g|gif|webp|avif)$|^((?!font).)*\.svg$)/).toString();
const targetFont = (/(\.(woff2?|ttf|eot|otf)$|font.*\.svg$)/).toString();
const targetCSS = (/\.p?css$/).toString();
rules.forEach(rule => {
let test = rule.test.toString();
if ([targetSVG, targetFont].includes(rule.test.toString())) {
rule.exclude = CKEditorRegex.svg;
} else if (test === targetCSS) {
rule.exclude = CKEditorRegex.css;
}
});
});
mix.webpackConfig({
plugins: [
new CKEditorWebpackPlugin({
language: 'en',
addMainLanguageTranslationsToAllAssets: true
}),
],
module: {
rules: [
{
test: CKEditorRegex.svg,
use: ['raw-loader']
},
{
test: CKEditorRegex.css,
use: [
{
loader: 'style-loader',
options: {
injectType: 'singletonStyleTag',
attributes: {
'data-cke': true
}
}
},
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: CKEditorStyles.getPostCssConfig({
themeImporter: {
themePath: require.resolve('#ckeditor/ckeditor5-theme-lark')
},
minify: true
})
}
}
]
}
]
}
});
Specs:
node v.16.11.1
npm v.8.0.0
Laravel v.8.77.1
package.json
"laravel-mix": "6.0.40",
"postcss-loader": "^6.2.1",
"raw-loader": "^4.0.1",
"sass": "^1.49.4",
"sass-loader": "^12.4.0",
"style-loader": "^2.0.0"
The Mix.listen() was deprecated and will go away in a future release. should replaced by mix.override().
Thanks #bakis.
This is the only working version after hours of searching. Exclude CKEditor regex from mix's default rules is the key neglected.
/** ckeditor 5 webpack config ****/
const CKEditorWebpackPlugin = require('#ckeditor/ckeditor5-dev-webpack-plugin');
const CKEditorStyles = require('#ckeditor/ckeditor5-dev-utils').styles;
//Includes SVGs and CSS files from "node_modules/ckeditor5-*" and any other custom directories
const CKEditorRegex = {
svg: /ckeditor5-[^/\\]+[/\\]theme[/\\]icons[/\\][^/\\]+\.svg$/, //If you have any custom plugins in your project with SVG icons, include their path in this regex as well.
css: /ckeditor5-[^/\\]+[/\\].+\.css$/,
};
mix.webpackConfig({
plugins: [
new CKEditorWebpackPlugin({
language: 'en',
addMainLanguageTranslationsToAllAssets: true
}),
],
module: {
rules: [
{
test: CKEditorRegex.svg,
use: ['raw-loader']
},
{
test: CKEditorRegex.css,
use: [
{
loader: 'style-loader',
options: {
injectType: 'singletonStyleTag',
attributes: {
'data-cke': true
}
}
},
'css-loader',
{
loader: 'postcss-loader',
options: {
postcssOptions: CKEditorStyles.getPostCssConfig({
themeImporter: {
themePath: require.resolve('#ckeditor/ckeditor5-theme-lark')
},
minify: true
})
}
}
]
}
]
}
});
//Exclude CKEditor regex from mix's default rules
mix.override(config => {
const rules = config.module.rules;
const targetSVG = (/(\.(png|jpe?g|gif|webp|avif)$|^((?!font).)*\.svg$)/).toString();
const targetFont = (/(\.(woff2?|ttf|eot|otf)$|font.*\.svg$)/).toString();
const targetCSS = (/\.p?css$/).toString();
rules.forEach(rule => {
let test = rule.test.toString();
if ([targetSVG, targetFont].includes(rule.test.toString())) {
rule.exclude = CKEditorRegex.svg;
} else if (test === targetCSS) {
rule.exclude = CKEditorRegex.css;
}
});
});

Laravel and Vue Pagination Fail

When I press the page 2 on pagination component, page=2 data comes to application and data never shows up on screen and pagination goes to 1 and everything is going to start point. I use bootstrap-vue for ui component library.
pagination component image:
Vue data variables:
isBusy: false,
output: {
message: "",
status: false
},
currentPage: 1,
tableData:{},
laravel api routes
Route::prefix('/pcustomers')->group( function() {
Route::post('/load', 'App\Http\Controllers\EmailListController#postPCustomer');
Route::middleware('auth:api')->post('/post', 'App\Http\Controllers\EmailListController#postPCustomer')->middleware(['web']);
Route::middleware('auth:api')->get('/all', 'App\Http\Controllers\EmailListController#allPCustomers')->middleware(['web']);
Route::middleware('auth:api')->get('/pcdata', 'App\Http\Controllers\EmailListController#pcData')->middleware(['web']);
Route::middleware('auth:api')->get('/delete', 'App\Http\Controllers\EmailListController#deletePCustomer')->middleware(['web']);
});
EmailListController function
public function pcData()
{
$pcData = DB::table('email_list')
->join('users', 'users.id', '=', 'email_list.workerId')
->select('email_list.*', 'users.username')
->paginate(100);
return response()->json($pcData);
}
Pagination component:
<b-pagination
v-model="currentPage"
:total-rows="tableData.total"
:per-page="tableData.to"
#input="getNewPageData()"
first-number
last-number
>
</b-pagination>
Here the axios post method for getting the data
getNewPageData(){
let list = this;
list.isBusy = true;
const page = list.currentPage;
axios.get("api/v1/pcustomers/pcdata?page="+page)
.then(function (response) {
list.tableData = response.data;
list.isBusy = false;
})
.catch(function (error) {
list.output = error;
});
},
It works at here for page 1
created(){
this.getNewPageData(this.currentPage);
}
Data Response for page 1:
{
"current_page":1,
"data":[
"..."
],
"first_page_url":"http:\/\/127.0.0.1:8000\/api\/v1\/pcustomers\/pcdata?page=1",
"from":1,
"last_page":4,
"last_page_url":"http:\/\/127.0.0.1:8000\/api\/v1\/pcustomers\/pcdata?page=4",
"links":[
{
"url":null,
"label":"Previous",
"active":false
},
{
"url":"http:\/\/127.0.0.1:8000\/api\/v1\/pcustomers\/pcdata?page=1",
"label":1,
"active":true
},
{
"url":"http:\/\/127.0.0.1:8000\/api\/v1\/pcustomers\/pcdata?page=2",
"label":2,
"active":false
},
{
"url":"http:\/\/127.0.0.1:8000\/api\/v1\/pcustomers\/pcdata?page=3",
"label":3,
"active":false
},
{
"url":"http:\/\/127.0.0.1:8000\/api\/v1\/pcustomers\/pcdata?page=4",
"label":4,
"active":false
},
{
"url":"http:\/\/127.0.0.1:8000\/api\/v1\/pcustomers\/pcdata?page=2",
"label":"Next",
"active":false
}
],
"next_page_url":"http:\/\/127.0.0.1:8000\/api\/v1\/pcustomers\/pcdata?page=2",
"path":"http:\/\/127.0.0.1:8000\/api\/v1\/pcustomers\/pcdata",
"per_page":100,
"prev_page_url":null,
"to":100,
"total":366
}
I did some changes on b-table and axios and it works now.
<b-table
id="pcustomers-table"
ref="pcustomers-table"
:busy="isBusy"
:items="tableData"
:fields="fields"
:per-page="resourceData.per_page"
:sort-by.sync="sortBy"
:sort-desc.sync="sortDesc"
small
striped
hover
>
I removed :current-page="currentPage" here.
getPCustomersResourceData(){
let list = this;
list.isBusy = true;
const page = list.currentPage;
axios.get("api/v1/pcustomers/pcdata?page="+page)
.then(function (response) {
list.resourceData = response.data;
list.tableData = list.resourceData.data;
list.isBusy = false;
})
.catch(function (error) {
list.output = error;
});
},
I get the whole data and separate here like:
resourceData: {},
tableData:[],
Thanks to github.com/gilbitron and Kamlesh Paul.

How to wait for result of service get?

I'm pretty sure the get function of the person service I use below returns a function, but my test doesn't seem to execute either branch, so it times out. Does that mean that get does not return a promise?
describe('person service', function () {
beforeEach(module('tournament'));
var person;
beforeEach(inject(function (_personService_) {
person = _personService_;
}));
it('should get person data', (done) => {
var expectedPerson = [
{ id: 2, last: 'Steigerwald', first: 'Michael' },
];
person.get(2).then(
(result) => {
expect(result).toEqual(expectedPerson);
done();
},
(reason) => {
console.log(reason.message);
done();
}
);
});
});

How to add antd to Nextjs

I create a project base on with-ant-design-less and then try to add sass to project. I change the following files:
next.config.js:
/* eslint-disable */
const withSass = require("#zeit/next-sass");
const withLess = require("#zeit/next-less");
const lessToJS = require("less-vars-to-js");
const fs = require("fs");
const path = require("path");
// Where your antd-custom.less file lives
const themeVariables = lessToJS(
fs.readFileSync(path.resolve(__dirname, "./assets/antd-custom.less"), "utf8")
);
module.exports = withSass({
cssModules: true,
cssLoaderOptions: {
importLoaders: 1,
localIdentName: "[folder]_[local]___[hash:base64:5]",
},
...withLess({
lessLoaderOptions: {
javascriptEnabled: true,
modifyVars: themeVariables, // make your antd custom effective
},
webpack: (config, { isServer }) => {
if (isServer) {
const antStyles = /antd\/.*?\/style.*?/;
const origExternals = [...config.externals];
config.externals = [
(context, request, callback) => {
if (request.match(antStyles)) return callback();
if (typeof origExternals[0] === "function") {
origExternals[0](context, request, callback);
} else {
callback();
}
},
...(typeof origExternals[0] === "function" ? [] : origExternals),
];
config.module.rules.unshift({
test: antStyles,
use: "null-loader",
});
}
return config;
},
}),
});
package.json
{
"name": "with-ant-design-less",
"version": "1.0.0",
"scripts": {
"dev": "next",
"build": "next build",
"start": "next start"
},
"dependencies": {
"#zeit/next-less": "^1.0.1",
"#zeit/next-sass": "^1.0.1",
"antd": "^3.5.4",
"babel-plugin-import": "^1.7.0",
"less": "3.0.4",
"less-vars-to-js": "1.3.0",
"next": "latest",
"null-loader": "2.0.0",
"react": "^16.7.0",
"sass": "^1.26.3",
"react-dom": "^16.7.0"
},
"license": "ISC",
"devDependencies": {
"#types/node": "^13.13.1",
"typescript": "^3.8.3"
}
}
but when I run the project I get the following error:
[ error ] ./pages/index.module.scss
To use Next.js' built-in Sass support, you first need to install `sass`.
Run `npm i sass` or `yarn add sass` inside your workspace.
Although I'm looking for better solution to setup the project because in this way all the style will be in one big chunk that cause performance issue.
Any idea? Thanks
next.config.js:
const withPlugins = require('next-compose-plugins');
const withCss = require('#zeit/next-css');
const withSass = require('#zeit/next-sass');
const withLess = require('#zeit/next-less');
const lessToJS = require('less-vars-to-js');
const fs = require('fs');
const path = require('path');
const lessThemeVariablesFilePath = './static/ant-theme-variables.less';
const themeVariables = lessToJS(
fs.readFileSync(path.resolve(__dirname, lessThemeVariablesFilePath), 'utf8'),
);
const lessNextConfig = {
lessLoaderOptions: {
javascriptEnabled: true,
modifyVars: themeVariables,
},
webpack: (config, { isServer }) => {
if (isServer) {
const antStyles = /antd\/.*?\/style.*?/;
const origExternals = [...config.externals];
config.externals = [
(context, request, callback) => {
if (request.match(antStyles)) return callback();
if (typeof origExternals[0] === 'function') {
origExternals[0](context, request, callback);
} else {
callback();
}
},
...(typeof origExternals[0] === 'function' ? [] : origExternals),
];
config.module.rules.unshift({
test: antStyles,
use: 'null-loader',
});
}
return config;
},
};
const sassNextConfig = {
cssModules: true,
cssLoaderOptions: {
localIdentName: '[path]___[local]___[hash:base64:5]',
},
};
module.exports = withPlugins([
[withLess, lessNextConfig],
[withSass, sassNextConfig],
]);
babel config:
module.exports = {
presets: ['next/babel'],
plugins: [
['import', { libraryName: 'antd', style: true }],
],
};
I use sass, less and css. it depends on your requirement. and you can add your custom variables in an static file as I did.
hope be helpful.
So, for people who came here just for the basic addition, you can add antd to your nextjs app by installing antd
npm i antd
and then you can add the antd styles to your
_app.js file
after your global styles:
import 'antd/dist/antd.css'

How can I iterate over the test data using webdriverio with mocha?

I have a JSON based test data, how can I iterate over this test data for the test to run for each cred object?
cred: {
nameValue: 'ant',
emailValue: 'ant#gmail.com',
passwordValue: 'ant',
},
cred: {
nameValue: 'bat',
emailValue: 'bat#gmail.com',
passwordValue: 'bat',
},
your test data JSON file should be like this,
[
{
"nameValue": "ant",
"emailValue": "ant#gmail.com",
"passwordValue": "ant"
},
{
"nameValue": "bat",
"emailValue": "bat#gmail.com",
"passwordValue": "bat"
}
]
Now you can access them by index ( as in an array )
const testDataObject = require("path to testData json");
// to loop on all elements
testDataObject.forEach(function(element) {
it(' test case def ', function() {
console.log("nameValue "+ element['nameValue']+ "emailValue
"+element['emailValue'] + "passwordValue "+element[passwordValue]);
});
});
// to select any particular index
it(' test case def ', function() {
console.log("nameValue "+ testDataObject[1]['nameValue']+ "emailValue
"+testDataObject[1]['emailValue'] + "passwordValue "+testDataObject[1][passwordValue]);
});
});
And name your testData file name as Credentials_Valid.json ( best practice )
or
you can do in this way
{
"cred1":
{
"nameValue": "ant",
"emailValue": "ant#gmail.com",
"passwordValue": "ant",
},
"cred2":
{
"nameValue": "bat",
"emailValue": "bat#gmail.com",
"passwordValue": "bat",
}
}
and access the test data in nodejs code by
console.log( `${testDataObject['cred1']["nameValue"]}` );
console.log( `${testDataObject['cred1']["emailValue"]}` );
console.log( `${testDataObject['cred1']["passwordValue"]}` );

Resources