I am quite new to Testing with jest and was learning to write tests for my code. The current setup is :
//cityService.ts:
import {inject, injectable} from "inversify";
import {NUCLEUS_TYPES} from "../nucleus/NUCLEUS_TYPES";
import {AppLogger} from "../libs/logger";
import {CityReadOnlyDao, CityReadWriteDao} from "../nucleus/daos/cityDao";
import {ICityAttributes} from "../nucleus/interfaces/attributeInterfaces";
import {ICityModel} from "../nucleus/interfaces/modelInterfaces";
import {BaseService} from "../nucleus/services/baseService";
import {escapeRegExp} from "../utils/helper";
import {SortOrder} from "../nucleus/constants/enums";
#injectable()
export class CityService extends BaseService<ICityModel, ICityAttributes>{
constructor(#inject(NUCLEUS_TYPES.AppLogger) protected appLogger: AppLogger,
#inject(NUCLEUS_TYPES.ReadOnlyDao.City) protected cityReadOnlyDao: CityReadOnlyDao,
#inject(NUCLEUS_TYPES.ReadWriteDao.City) protected cityReadWriteDao: CityReadWriteDao){
super(cityReadOnlyDao, cityReadWriteDao);
}
async suggestCity(req) {
this.appLogger.debug(typeof req.body.query);
let regQuery = new RegExp(escapeRegExp(req.body.query.trim()), 'i');
let cities = await this.find({
condition: {'name': {$regex: regQuery}},
sortField: 'used',
sortOrder: SortOrder.DESC,
count: (req.body.limit ? Number(req.body.limit) : 10),
start: (req.body.skip ? Number(req.body.skip) : 0)
});
return ({state: true, cities});
}
}
And a sample test is :
import { CityService } from "../src/services/cityService";
import container from "../src/libs/ioc";
let cityService = container.get<CityService>(TYPES.Service.City);
test("Testing with full Name", async () => {
expect.hasAssertions();
let response = await cityService.suggestCity({
body: {
query: 'London'
}
});
expect(response.cities).toEqual(expect.arrayContaining([expect.objectContaining({ name: 'London' })]));
});
The test runs and passes without a hitch. Now my doubt was that I am hitting my database with this test. Is there a way to test this without the function calling my database? Perhaps Making a mock database. Can someone point me in the right direction as to how should I proceed with it?
Related
I'm not a Javascript/Typescript/React dev. I'm hacking my way through this for a work project.
I'm using Streamlit, with plotly.
I'm hacking the basic code from streamlit-plotly-events.
I was trying to have the click or box-select information passed back with the data selected via the plotlyEventHandler() (see code below.) However, both this.props.args["click_event"] and this.props.args["select_event"] are true, regardless of whether you use box-select in the plotly chart, or click a single data point in the chart.
I thought of assuming if there is only one data point, then it was a click - but you can box select only one data point.
// import React, {useState,useEffect} from "react"
import React, { ReactNode } from "react"
//import React from "react"
import {
StreamlitComponentBase,
withStreamlitConnection,
Streamlit,
// ComponentProps,
} from "streamlit-component-lib"
import Plot from "react-plotly.js"
class StreamlitPlotlyEventsCapture extends StreamlitComponentBase {
public render = (): ReactNode => {
// Pull Plotly object from args and parse
const plot_obj = JSON.parse(this.props.args["plot_obj"]);
const override_height = this.props.args["override_height"];
const override_width = this.props.args["override_width"];
// Event booleans
const click_event = this.props.args["click_event"];
const select_event = this.props.args["select_event"];
const hover_event = this.props.args["hover_event"];
Streamlit.setFrameHeight(override_height);
return (
<Plot
data={plot_obj.data}
layout={plot_obj.layout}
config={plot_obj.config}
frames={plot_obj.frames}
onClick={click_event ? this.plotlyEventHandler : function(){}}
onSelected={select_event ? this.plotlyEventHandler : function(){}}
onHover={hover_event ? this.plotlyEventHandler : function(){}}
style={{width: override_width, height: override_height}}
className="stPlotlyChart"
/>
)
}
/** Click handler for plot. */
private plotlyEventHandler = (data: any) => {
// Build array of points to return
var clickedPoints: Array<any> = [];
//const util = require('util')//#33333 used with util.inspect(arrayItem) below
// I dont know why we can't directly use "this.variables" in the clickedPoints.push
// but we can't, so we create the variables here.
var wasClicked = this.props.args["click_event"];
var wasSelected = this.props.args["select_event"];
var wasHovered = this.props.args["hover_event"];
data.points.forEach(function (arrayItem: any) {
// console.log(util.inspect(arrayItem, {maxArrayLength: null, depth:null }))
clickedPoints.push({
// I dont know why we can't directly use "this.variables" here, but we can't
// so we use the variables created above.
clicked:wasClicked,
selected:wasSelected,
hovered:wasHovered,
x: arrayItem.x,
y: arrayItem.y,
curveNumber: arrayItem.curveNumber,
pointNumber: arrayItem.pointNumber,
pointIndex: arrayItem.pointIndex
})
});
// Return array as JSON to Streamlit
Streamlit.setComponentValue(JSON.stringify(clickedPoints))
}
}
export default withStreamlitConnection(StreamlitPlotlyEventsCapture)
Recently, I wanted to develop a plugin for javascipt for visual studio code. It's essence is to generate 3 files with template text in them. I stored the template text as a multiline string in a variable, but I never managed to insert the variable interpolation into the multiline string.
Code sample below:
const blocName = await vscode.window.showInputBox({
placeHolder: "Bloc name",
prompt: "Enter the BLoC name",
});
const blocNameLower = blocName.toLowerCase();
const bloc = 'import \'dart:async\';\n\
import \'package:${blocNameLower}_bloc/bloc.dart\'\;\n\
import \'package:meta/meta.dart\';\n\
\n\
part \'${blocNameLower}_event.dart\';\n\
part \'${blocNameLower}_state.dart\';\n\
\n\
class ${blockName}Bloc extends Bloc<${blockName}Event, ${blockName}State> {\n\
${blockName}Bloc() : super(${blockName}Initial()) {\n\
on<${blockName}Event>((event, emit) {\n\
// TODO: implement event handler\n\
});\n\
}\n\
}';
Let's assume input is Test:
Actual behavior:
import 'dart:async';
import 'package:${blocNameLower}_bloc/bloc.dart';
import 'package:meta/meta.dart';
part '**${blocNameLower}**_event.dart';
part '${blocNameLower}_state.dart';
class ${blockName}Bloc extends Bloc<${blockName}Event, ${blockName}State> {
${blockName}Bloc() : super(${blockName}Initial()) {
on<${blockName}Event>((event, emit) {
// TODO: implement event handler
});
}
}
Expected behavior:
import 'dart:async';
import 'package:test_bloc/bloc.dart';
import 'package:meta/meta.dart';
part '**test**_event.dart';
part 'test_state.dart';
class TestBloc extends Bloc<TestEvent, TestState> {
TestBloc() : super(TestInitial()) {
on<TestEvent>((event, emit) {
// TODO: implement event handler
});
}
}
Is there any chance to interpolate variable in multiline line..(as with 'part test_event.dart';) ?
As per the single-spa official doc, we can share the application's UI state by using RxJs.
Observables / Subjects (RxJs) - one microfrontend emits new values to
a stream that can be consumed by any other microfrontend. It exports
the observable to all microfrontends from its in-browser module, so
that others may import it.
Link: https://single-spa.js.org/docs/recommended-setup/#ui-state
Link: https://single-spa.js.org/docs/faq/#how-can-i-share-application-state-between-applications
I was trying to create an example in React, where I am using single-spa parcel to include my micro-apps in root application. I was trying to share the UI state using RxJs.
When I googled it for single-spa RxJs, I didn't find anything. Can anyone provide me a basic example where I will be able to share UI state for below use cases:
Sharing the UI state from root app to my micro-apps.
Sharing the UI state from micro-apps to root apps.
Sharing the UI state between micro-apps.
Here is a high level overview on how to approach this:
add rxjs as a shared dependency in your import map
"rxjs": 'https://unpkg.com/#esm-bundle/rxjs/system/rxjs.min.js,
"rxjs/operators": 'https://unpkg.com/#esm-bundle/rxjs/system/rxjs-operators.min.js,
consider pinning these to a specific version!
create a utility module (create-single-spa makes this easy!) that sets up and exports the observable with data that you need
include this utility module in importmap too
import and subscribe to observable from the utility module in the apps that need it
don't forget to unsubscribe when your apps unmount.
celebrate 🎉
I have created single-spa-example-rxjs-shared-state as an example repo that shows how to use an Rxjs utility module with cross-frontend imports.
This does the trick
In root html js file add the following
Import { Subject, Subscription } from 'https://dev.jspm.io/rxjs#6/_esm2015';
import { filter, map } from 'https://dev.jspm.io/rxjs#6/_esm2015/operators';
export class EventBusService {
constructor() {this.subject$ = new Subject(); }
emit(event) {
this.subject$.next(event);
}
on(eventName, action) {
return this.subject$.pipe(
filter( (e) => e.name === eventName),
map( (e) => e["data"])).subscribe(action);
}
}
var EventBus= new EventBusService()`enter code here`;
System.import('single-spa').then(function (singleSpa) {
singleSpa.registerApplication(
'app1',
function () {
return System.import('app1');
},
function (location) {
return true;
// return location.pathname.startsWith('/app1');
},
{ EventBus: EventBus }
);
singleSpa.registerApplication(
'app2',
function () {
return System.import('app2');
},
function (location) {
return true
// return location.pathname.startsWith('/app2');
},
{ EventBus: EventBus }
)
singleSpa.start();
})
In component
import { Component,OnInit ,ChangeDetectorRef} from '#angular/core';
import { assetUrl } from 'src/single-spa/asset-url';
import { singleSpaPropsSubject, SingleSpaProps } from 'src/single-spa/single-spa-props';
import { Subscription } from 'rxjs';
#Component({
selector: 'app1-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
export class AppComponent implements OnInit {
singleSpaProps: SingleSpaProps;
subscription: Subscription;
title = 'app1';
yoshiUrl = assetUrl("yoshi.png");
msgFromMicro="";
titleToPass="";
constructor(private ChangeDetectorRef:ChangeDetectorRef){
}
ngOnInit(): void {
this.subscription = singleSpaPropsSubject.subscribe(
props => {
this.singleSpaProps = props;
console.log(props);
this.lookForEvents();
}
);
}
lookForEvents(){
this.singleSpaProps['EventBus'].on('msgFrmMicro2',(data)=>{
this.msgFromMicro=data;
this.ChangeDetectorRef.detectChanges();
});
}
sendMsg(){
// alert(this.titleToPass);
debugger;
this.singleSpaProps['EventBus'].emit({name:'msgFrmMicro1',data:this.titleToPass});
}
ngOnDestroy(): void {
this.subscription.unsubscribe();
}
}
Take look at the following repo, handled the same scenario by passing observable ref to micro apps through customprops of single spa
https://github.com/SENTHILnew/micro_spa_intercom
Can someone please give me a detailed example of RobinBuschmann/soap-typescript/soap-decorators Example. I am looking to create a wsdl xml for node-soap. The example given on github of RobinBuschmann/soap-typescript does not seem to work as is. I put the first three code snippets in a file called createWsdl.js and ran it with "node createWsdl.js" and I get an error. I suspect I am not doing the right thing. Can someone please help me or give me a detailed example that actually works.
I used node-soap and soap-decorators to communicate with Quickbooks. The following is from my app.ts file:
this.express.use(
'/soap',
soap(this.quickbooksController, {
overrideRootElement: {
namespace: '',
xmlnsAttributes: [
{
name: 'xmlns',
value: 'http://developer.intuit.com/'
}
]
}
})
);
The controller is annotated like so:
import { SoapOperation, SoapService } from 'soap-decorators';
import { AuthenticateRequest, AuthenticateResponse } from './model/authenticate.interface';
#SoapService({
portName: 'QBWebConnectorSvcSoap',
serviceName: 'QBWebConnectorSvc',
targetNamespace: 'http://developer.intuit.com/'
})
export class QuickbooksController {
#SoapOperation(AuthenticateResponse)
authenticate(data: AuthenticateRequest, res: (res: AuthenticateResponse) => any): void {
res({ authenticateResult: { string: ['', 'NVU'] } });
}
}
My request and response objects are decorated as XSD types:
import { XSDComplexType, XSDElement } from 'soap-decorators';
#XSDComplexType
export class AuthenticateRequest {
#XSDElement
strUserName: string;
#XSDElement
strPassword: string;
}
#XSDComplexType
class AuthenticateResult {
#XSDElement({ type: 'string' })
string: string[];
}
#XSDComplexType({ name: 'authenticateResponse' })
export class AuthenticateResponse {
#XSDElement
authenticateResult: AuthenticateResult;
}
I just want to show the name of the current logged in user, but I cant make it works.
I wrote this on the app.component:
import { Component } from '#angular/core';
import template from './app.component.html';
import {ROUTER_DIRECTIVES} from '#angular/router';
import {LoginButtons} from 'angular2-meteor-accounts-ui';
//import our Carousel Component
import {CSSCarouselComponent} from './imports/componenets/carousel/carousel.component';
import { InjectUser } from 'angular2-meteor-accounts-ui';
#Component({
selector: 'app',
template,
directives: [ROUTER_DIRECTIVES, LoginButtons,CSSCarouselComponent]
})
#InjectUser('user')
export class AppComponent {
user: Meteor.User;
constructor() {
console.log(this.user);
}
loginFacebook(event) {
Meteor.loginWithFacebook({}, function(err){
if (err) {
throw new Meteor.Error("Facebook login failed");
}
console.log(Meteor.user().profile.name;);
});
}
}
console.log(this.user); returns undefined.
console.log(Meteor.user().profile.name;); works and gives me the name, but I have no success to export it to the html and show that.
You have to reference Meteor in your Component, for example as let M = Meteor;. Then you can use {{M.user().profile.name}} in your html.
Also this.user is never set in your code, you just define its class. Anyway, you should always use Meteor.user() or M.user(), because it's always up-to-date.