Unit Test Vue Component Rails App - ruby-on-rails

I have created vue components using this structure.
Vue.component('my-component', {
template: '<div>A custom component!</div>'
})
I would like to test this using karma and jasmine or jasmine rails gem. I can't figure out how to test the component. In all the examples on the docs they use a requirejs module way of testing. I use the global component way of creating components.
These are the examples from the docs.
<template>
<span>{{ message }}</span>
</template>
<script>
export default {
data () {
return {
message: 'hello!'
}
},
created () {
this.message = 'bye!'
}
}
</script>
// Import Vue and the component being tested
import Vue from 'vue'
import MyComponent from 'path/to/MyComponent.vue'
// Here are some Jasmine 2.0 tests, though you can
// use any test runner / assertion library combo you prefer
describe('MyComponent', () => {
// Inspect the raw component options
it('has a created hook', () => {
expect(typeof MyComponent.created).toBe('function')
})
// Evaluate the results of functions in
// the raw component options
it('sets the correct default data', () => {
expect(typeof MyComponent.data).toBe('function')
const defaultData = MyComponent.data()
expect(defaultData.message).toBe('hello!')
})
// Inspect the component instance on mount
it('correctly sets the message when created', () => {
const vm = new Vue(MyComponent).$mount()
expect(vm.message).toBe('bye!')
})
// Mount an instance and inspect the render output
it('renders the correct message', () => {
const Ctor = Vue.extend(MyComponent)
const vm = new Ctor().$mount()
expect(vm.$el.textContent).toBe('bye!')
})
})

import foo from 'bar'; and var foo = require('bar'); does the same thing, making foo available as a variable in the current file. In the test example, MyComponent is the imported vue component instance, which can also be achieved with MyComponent = Vue.component(...); in the current file. So if your test is in the same file, just use the MyComponent variable, if not, you'll need to export MyComponent first with module.exports = MyComponent or export default MyComponent. These exports assume MyComponent is the only thing you want to export, if you want to export multiple variables, checkout the docs: http://wiki.commonjs.org/wiki/Modules/1.1 https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Statements/export

Related

Using BullMQ with NestJs, is it possible to use a config variable as part of a Job name?

I'm trying to use an environment variable value in the nestjs/bull module's #Process() decorator, as follows. How should I provide the 'STAGE' variable as part of the job name?
import { Process, Processor } from '#nestjs/bull';
import { Inject } from '#nestjs/common';
import { ConfigService } from '#nestjs/config';
import { Job } from 'bull';
#Processor('main')
export class MqListener {
constructor(
#Inject(ConfigService) private configService: ConfigService<SuperRootConfig>,
) { }
// The reference to configService is not actually allowed here:
#Process(`testjobs:${this.configService.get('STAGE')}`)
handleTestMessage(job: Job) {
console.log("Message received: ", job.data)
}
}
EDITED with answers (below) from Micael and Jay:
Micael Levi answered the initial question: You can't use the NestJS ConfigModule to get your config into a memory variable. However, running dotenv.config() in your bootstrap function will not work either; you get undefined values for the memory variables if you try to access them from within a Method Decorator. To resolve this, Jay McDoniel points out that you have to import the file before you import AppModule. So this works:
// main.ts
import { NestFactory } from '#nestjs/core';
require('dotenv').config()
import { AppModule } from './app.module';
async function bootstrap() {
const app = await NestFactory.create(AppModule);
await app.listen(process.env.PORT || 4500);
}
bootstrap();
You cannot use this on that context due to how decorator evaluation works. At that time, there's no instance created for MqListener class, thus, using this.configService doens't make sense.
You'll need to access process.env. directly. And so will call dotenv (or what lib that read & parses your dot env file) in that file.

Vaadin 14: sending data from a web component to server

How can i send data from client to server using html5 webcomponent
setting up data from server to client, is very easy, works like a charm
how ever cannot find solution to send data to server
Please assist, but Iam not going to use Lit or Polymer
#JavaScript
class SimpleComponent extends HtmlElement {
connectedCallback() {
this.innerHTML = '<input type="text" id="test"/>";
this._input = this.querySelector('#test');
this._input.onchange = function() {
***** i want to send the value to server ****
})
}
setInputValue(value) {
this._input.value = value;
}
}
customElements.define("simple-com",SimpleComponent);
Now Java at Server
#Tag("simple-com")
class SimpleComponent extends Component {
public SimpleComponent() {
}
public void setValue(String value) {
getElement().callJsFunction("setValue",value);
}
}
The main challenge compared to Polymer or LitElement is that an event handler defined using the pattern innerElement.onchange = function() {} will not be run with this referencing the custom element instance. This in turn means that trying to use this.$server won't work because this isn't pointing to the expected value even though $server is indeed present in the place where it's supposed to be.
The easiest way of fixing this is to change the code to use an arrow function (() => {}) instead of an explicit function. This works because arrow functions inherit this from the scope where the function is defined whereas explicit functions have this defined in different ways depending on how it is run. Another approach would be to store a reference to this in a separate variable (e.g. let root = this) and then reference that variable instead of this in the function (e.g root.$server.doSomething()).
Putting everything together, this is what the code looks like with my modifications to make everything work.
class SimpleComponent extends HTMLElement {
connectedCallback() {
this.innerHTML = '<input type="text" id="test"/>';
this._input = this.querySelector('#test');
this._input.onchange = () => {
this.$server.handleChange(this._input.value);
};
}
setValue(value) {
this._input.value = value;
}
}
customElements.define("simple-com", SimpleComponent);

AWS CDK- Access resource from other stack

Suppose i have a resource, say stepfunction activity, in one stack. How can i access it's arn in other stack?
I found CfnConstruct suitables for exporting (https://docs.aws.amazon.com/cdk/api/latest/docs/#aws-cdk_core.CfnOutput.html). As of now i have used CfnConstruct to export it:
this.initiateValidationActivityArn = new cdk.CfnOutput(this, 'InitiateValidationActivityArn', {
value: igvsStateMachine.initiateValidationActivity.activityArn
});
Now how can i access it in other file. I have tried this:
ecsService.initiateValidationActivityArn.value
But value is private to construct so can't use it.
If you have the stacks in one deployable cdk-app, you can access the property value from the stack by making it accessible from outside / not-private.
What I recommend doing is to keep it readonly so that it can't be re-initialized from outside the stack.
// file: ./lib/first-stack.ts
// import statements
export class FirstStack extends Stack {
readonly vpc: IVpc;
constructor(...) {
// setup
this.vpc = new Vpc(this, "VPC", {...});
}
}
In the dependent stack, you can pass it via (custom) props.
// file: ./lib/second-stack.ts
export interface SecondStackProps extends StackProps {
importedVpc: IVpc;
}
export class SecondStack extends Stack {
constructor(scope: cdk.Construct, id: string, props: SecondStackProps) {
super(scope, id, props);
const importedVpc = props.importedVpc;
// do sth. with your imported resource
}
}
Why is that working you may ask...?
It works because CDK generates the Resource IDs and during the synth phase it can put the tokens for the resources inside the generated templates.
This doesn't work, when you have separated cdk-apps / deployments of stacks, because CDK can't resolve the (existing) Resource ID Tokens during cdk-synth.
With that, you need to have another approach:
// file: ./lib/first-stack-separated-deployment.ts
// import statements
export class FirstStackSeparatedDeployment extends Stack {
cfnVpcId: CfnOutput;
constructor(...) {
// setup
const vpc = new Vpc(this, "VPC", {...});
this.cfnVpcId= new cdk.CfnOutput(this, "FirstStackCfnVpcId", {
value: vpc.vpcId,
exportName: "UniqueNameForYourVpcId"
});
}
}
In the other stack, which requires the already deployed resource, you do the following:
// file: ./lib/second-stack-separated-deployment.ts
export class SecondStackSeparatedDeployment extends Stack {
constructor(...) {
// setup
const vpcId = Fn.importValue("UniqueNameForYourVpcId")
const importedVpc = ec2.Vpc.fromVpcAttributes(this, "ImportedVpc", {
vpcId: vpcId,
availabilityZones: [this.region],
})
// proceed further...
}
}
Basically, you take the exportName from the CfnOutput Construct as an identifier and import it via the core Fn.importValue.
With that approach, the first stack already needs to be deployed.

How to use the createDummyGenerator() function?

I can't understand how to use the createDummyGenerator() function when testing a generator that relies on external generators.
I have tried:
test.js:
...
return helpers.run(require.resolve('../generators/app'))
.withGenerators([
[helpers.createDummyGenerator(), 'license:app'],
])
.then(() => {
assert.textEqual('true', 'true')
});
...
index.js:
...
default() {
this.composeWith('license:app', { name: 'foo' });
}
...
This makes the test fail because it can't find a generator for license:app. I have generator-license in my package.json as a dependency.
I also tried the following:
test.js:
...
beforeEach(() => {
jest.mock('generator-license/app', () => {
const helpers = require('yeoman-test');
return helpers.createDummyGenerator();
});
}
...
index.js:
...
default() {
this.composeWith(require.resolve('generator-license/app', { name: 'foo' }));
}
...
This doesn't mock the generator at all, and it uses the actual generator-license code, which makes the test fail because not all prompts are supplied (some are meant to be asked by the license generator)
How am I supposed to use the createDummyGenerator() helper to completely stub out the license generator?
Well, I feel like an idiot... I had a typo in another test that didn't mock the module, and that's what was making the test suite fail... Nevermind, nothing to see here :)

Vue2: The right way to include / inject a global utility class

I have Vue.js project where I would like to use a utility class for functions I want to use in all my modules.
modules/Utils.js
export default class Utils {
array_count (arr) {
return Array.isArray(arr) ? arr.length : 0;
}
}
main.js
import Vue from 'vue';
import Utils from 'modules/Utils';
export default new Vue({
el: '#app',
router,
template: '<App/>',
components: {
App
},
utils: Utils // this has no affect?
});
modules/some.js
import Vue from 'vue';
import Utils from 'modules/Utils'; // I don't want this
var utils = new Utils; // I don't want this
console.log(utils.array_count(['a','b','c']));
I don't really understand how to inject the Utils Class. The example above works - but I would like to get rid of the import of the Class in each module. I thought when I add it in main.js as a dependency, I should be able to call it anywhere in my project.
when you want to access the helpers from every component you could register a global mixin.
Change your Utils.js to look like a Mixin.
export default {
methods: {
array_count (arr) {
return Array.isArray(arr) ? arr.length : 0;
}
}
}
Then, import the mixin and add it globally.
import Vue from 'vue';
import Utils from 'modules/Utils';
Vue.mixin(Utils);
export default new Vue({
el: '#app',
router,
template: '<App/>',
components: {
App
},
Alternatively, if you want some helper functions not to be available globally but just in some components, you could import the mixin and add it manually to Vue components.

Resources