Interpolate variable in multiline vanilla javascipt - string

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';) ?

Related

How to determine if "click" or "box-select" was used with Streamlit/Plotly to return data from chart to Streamlit

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)

AWS-CDK: Need to pass resource generated in pipeline to a created stack

I'm currently working on a cross-account deployment pipeline.
I'm using 4 different stacks:
BackendPipelineStack
CommonInfrastructureStack
AssetDeploymentStack
BusinessAssetAPIStack
The last 2 stacks both have props that include a generated Layer and built JS files (for the different Lambdas).
My cdk.ts looks like this:
import * as cdk from "#aws-cdk/core"
import { BackendPipelineStack } from "../lib/backend-pipeline"
import { BusinessAssetAPIStack } from "../lib/business-asset-api-stack"
import { projectConfig } from "../config/config"
import { AssetDeploymentStack } from "../lib/asset-deployment-stack"
import { CommonInfrastructureStack } from "../lib/common-infrastructure-stack"
const app = new cdk.App()
const commonInfraStack = new CommonInfrastructureStack(app, "CommonInfrastructureStack", {
stackName: `${projectConfig.resourcePrefix}-common-infrastructure-stack`,
})
const apiStack = new BusinessAssetAPIStack(app, "BusinessAssetAPIStack", {
stackName: `${projectConfig.resourcePrefix}-business-asset-api-stack`,
...,
installationUserEmailIndexName: commonInfraStack.installationTechnicalAssetUserEmailIndexName,
})
const deploymentStack = new AssetDeploymentStack(app, "AssetDeploymentStack", {
stackName: `${projectConfig.resourcePrefix}-asset-deployment-stack`,
...,
installationAccountRegionIndexName: commonInfraStack.installationAccountRegionIndexName,
})
new BackendPipelineStack(app, "BackendPipelineStack", {
nonProdAccountId: "nonProdAccountId",
apiStack,
commonInfraStack,
deploymentStack,
})
My BackendPipelineStack stack is the one generating the codepipeline.Artifacts that store both the built JS files and Layers.
//backend-pipeline.ts
export class BackendPipelineStack extends Stack {
...
const lambdaBuildOutput = new Artifact("DistArtifact")
const lambdaLayer = new Artifact("LayerArtifact")
...
I want to be able to pass both Artifacts to the other stacks that are passed thru the PipelineStack constructor.
Is there anyway to do this?
I found the answer for those who would be stuck in the same situation as I was.
Looking into pipeline actions, there is one called CloudFormationCreateOrUpdateStack that allows to override parameters provided in the Lambda Stack thru CfnParametersCode (here's a python example).

Setting up a test Database for jest tests on Nodejs

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?

How to import an object and run a function for all properties in module?

I created a module to store an object with some properties containing array of strings. Once it is imported, I want to get a sample of this array (eg: using lodash / sample). So I do not have to use the 'sample' method every time the module is imported and a property is referenced. Obs.: I want to reference an object and a property, not a function.
/store.js
export default {
foo: [
`This is the first message`,
`This is the second message`,
`This is the third message`
],
bar: [
`This is the message one`,
`This is the message two`,
`This is the message three`
]
};
I want to avoid this:
/file.js
import store from './store';
import sample from 'lodash/sample';
const msg = sample(store.foo);
console.log(msg); // e.g: This is the second message
and use something like this:
/file.js
import store from './store';
const msg = store.foo;
console.log(msg); // e.g: This is the first message

xtend code generation calling entities from an xtext grammar

I am working on a code generator for my grammar that I have created:
Domainmodel:
(elements+=AbstractElement)*;
PackageDeclaration:
'package' name=QualifiedName '{'
(elements+=AbstractElement)*
'}';
AbstractElement:
PackageDeclaration | Type | Import;
QualifiedName:
ID ('-' ID)*;
QualifiedDate:
INT('-' INT)*
;
Import:
'import' importedNamespace=QualifiedNameWithWildcard;
QualifiedNameWithWildcard:
QualifiedName '.*'?;
Type:
(data+= DataType)* man+=Entity ;
DataType:
'tag' name=Tag;
Tag:
Hobbies='hobbies' | Work= 'work' |Fun='fun'
;
Entity:
name=Category '{'
feature+=Feature*
'}'
;
Feature:
component+=Man(',' component+=Opt)*
;
enum Category:
Blog='blog' | Article='articles'
;
Man:
name='title' '=' type=QualifiedName
;
Opt:
Tags|Date
;
Tags:
name='tags' '=' '['type= Tag(','tag+=Tag)*']'
|
name='tags' '=' '[' ']'
;
Date:
name='date' '=' type=QualifiedDate
;
I want my output of my code generator to look like this:
---
layout: post
title: "My Trip"
categories: blog
excerpt:
tags: [fun,hobbies]
image:
feature:
date: 2016-06-01T14:19:19-04:00
modified:
---
All I can get right is the static text, I can't seem to call: Category , title , tags , date
I've been trying for so long now but I can't seem to get anywhere, I keep getting strange errors which i don't understand
One of my attempts for just seeing what I can generate is:
class MyDslGenerator implements IGenerator2 {
def compile(Entity e)
{
'''
---
layout: post
title: "My Trip"
categories:«e.name»
excerpt:
tags: [fun,hobbies]
image:
feature:
date: 2016-06-01T14:19:19-04:00
modified:
---
'''
}
override doGenerate(Resource input, IFileSystemAccess2 fsa, IGeneratorContext context) {
for (e : input.allContents.toIterable.filter(Entity)) {
fsa.generateFile(
e.generateName,
e.compile)
}
}
when I run the generator I don't get anything replaced by <>. I can't seem to figure it out.
is this a question on how to walk the AST. your grammar and thus the inferred metamodel is quite "bad" to walk so you may have to do something like
title: «(e.feature.head.component.head as Man).type»
so i recommend you to restructure your grammar/AST to fit the stuff you need.
you can set the encoding for the xtend/xtext plugin like this
tasks.withType(org.xtext.gradle.tasks.XtextGenerate) {
options.encoding = 'ISO-8859-1'
}
does that help?
/**
* generated by Xtext 2.10.0
*/
package org.xtext.example.mydsl.tests;
import com.google.inject.Inject;
import org.eclipse.xtend2.lib.StringConcatenation;
import org.eclipse.xtext.junit4.InjectWith;
import org.eclipse.xtext.junit4.XtextRunner;
import org.eclipse.xtext.junit4.util.ParseHelper;
import org.eclipse.xtext.xbase.lib.Exceptions;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.xtext.example.mydsl.myDsl.Domainmodel;
import org.xtext.example.mydsl.tests.MyDslInjectorProvider;
#RunWith(XtextRunner.class)
#InjectWith(MyDslInjectorProvider.class)
#SuppressWarnings("all")
public class MyDslParsingTest {
#Inject
private ParseHelper<Domainmodel> parseHelper;
#Test
public void loadModel() {
try {
StringConcatenation _builder = new StringConcatenation();
_builder.append("Hello Xtext!");
_builder.newLine();
final Domainmodel result = this.parseHelper.parse(_builder);
Assert.assertNotNull(result);
} catch (Throwable _e) {
throw Exceptions.sneakyThrow(_e);
}
}
}

Resources