Polymer use code from mixin in behavior - polymer-2.x

I have code in behaviors and in mixins. If I use both the mixin and the behavior in an element, the behavior can use functionality from the mixin and vice versa.
It seems a bit weird to write code that way though as you aren't making sure that the mixin is there from the behaviors' perspective, you are assuming the element includes both.
Is there a way to really include the mixin in the behavior or do I have to convert everything to Mixins and use the mixins in the mixins that need them to make sure they are always there?

Polymer 2 Using the Polymer.MixinBehavior concepts. The mixinBehavior function also mixes in the Legacy APIs, the same as if you extended Polymer.LegacyElement. These APIs are required since since hybrid behaviors depend on them.
Example:
class SampleElement extends Polymer.mixinBehaviors([MyBehavior, MyBehavior2, ... ], Polymer.Element) {
static get is() { return 'sample-element'}
...
}
customElements.define(SampleElement .is, sample);

Related

How to properly test component logic in Vue.js

I'm writing a new Vue project and want to test my components with vue-test-utils.
So far I've been writing unit-tests with a test case for each component method, testing its expected behavior while mocking other methods that it might call.
Recently I've read on the Vue docs that the unit tests for components should test general behavior and not rely on implemenation details:
https://vuejs.org/guide/scaling-up/testing.html#component-testing
which makes sense, but I still want to test the logic of my component's methods.
I don't want to extract it to different files / composables because they heavily rely on the component's data and other methods, and I don't wanna pass everything as parameters.
What do you recommend regarding this?
I can't mock methods anymore since setMethods is now deprecated in vue-test-utils, which is making it harder to test each method separately.
do you think I should give up on testing each method?
I find it helpful to test methods because usually small changes make those tests fail which help me notice errors in the code, but also makes it harder because every small legitimate change requires unit-test changes as well.
We have done unit test using vue-jest. Here are the steps.
Use the following code to set up the crypto property globally. This will allow Jest to access window.crypto and won't cause any issue.Create a crypto.mock file and paste following code.
const crypto = require('crypto')
Object.defineProperty(global.self, 'crypto', {
value: {
getRandomValues: arr => crypto.randomBytes(arr.length)
}
})
Now import this file in your test file component. Now You can use jasmine.Spy to spy on the elements.
let spyFor: jasmine.Spy; spyFor = spyOn(function.hello, 'hello'); expect(spyFor).toHaveBeenCalledTimes(1);
In this way you can mock on the methods. Pls free to ask if you have anything more.

Is it possible to spy on an imported function within a Vue SFC using Vitest and Vue Test Utils?

I'm working on unit testing all of my components, and I've hit a bit of a snag (or maybe a misunderstanding of how to properly test).
I have a component that receives some parameters from the store, and then calls a series of functions that mostly return an input string with some transformations applied.
This looks something like the following:
<script setup lang="ts">
import { someTextTransform } from '../utilities/someTextTransform';
...
let parsedText = store.input;
if (store.applySomeTextTransform) {
parsedText = someTextTransform(parsedText);
}
I have already tested these functions themselves, so to me it seems like testing the actual output of the calls is unnecessary and I instead could just test to see if the functions have been called.
Here is a snippet on spying from the Vitest docs
Mocking functions can be split up into two different categories; spying & mocking.
Sometimes all you need is to validate whether or not a specific function has been called (and possibly which arguments were passed). In these cases a spy would be all we need which you can use directly with vi.spyOn().
This is exactly what I want. I want only to know whether or not the function has been called. The functions themselves are simple enough that they do not require additional setup (i.e., mocking is not required).
However looking through the docs of Vue Test Utils I don't see a way to do this. It looks like a more common way to do this is to mock the functions first and then you can spy on them more easily, but then I would have to create mocks that don't actually mock the functions which seems like I'm adding code to my codebase for no benefit other than a weird workaround.
I may just be missing something on how to do this, but I might also be approaching the testing in a suboptimal way so any advice is appreciated.

Is there a class component library to Vue that does not use decorators?

The Vue class component library uses the #Component decorator, and must thus be transpiled to work. Is there a way to use Vue class components without this decorator? Like, either a work-around or another similar library?
Use-case: Lower commitment for a legacy project, but still possible to analyze with tsc.
Transpiled environment is the expected scenario of use for Vue. It relies on custom .vue format and may lack some features without it, as well as the support of some third-party libraries because they rely on it.
The use of classes never was a good idea in Vue because it doesn't follow OOP paradigm. A class isn't instantiated directly but used as syntactic structure that is translated to Vue.component definition. Vue class components have inherent problems, one of which is poor support for TypeScript types. If Vue classes aren't already used in the project, there are reasons for them to not be the first choice.
In case there's a necessity to use Vue class components, this can be done in vanilla ES6 because decorators proposal is syntactic sugar, decorators are functions with specific signatures that are applied to classes and members and decorate them.
#foo
#bar()
class Baz {}
is the same as
let Baz = foo(bar()(class Baz {}))
Different decorator types are applied in different ways, also there are some differences between TypeScript and Babel legacy decorators.
#Component
class Foo extends Vue {
#Provide('bar') baz = 'bar'
}
is translated to
let Foo = class Foo extends Vue {
constructor() {
this.baz = 'bar'
}
}
Provide('bar')(Foo.prototype, 'baz')
Foo = Component(Foo);
With Vue 3 typescript is well supported, you could create your component as follows :
import { defineComponent } from 'vue'
export default defineComponent({
//the component options like data,props,computed...
})
For more details check the official docs
A running example to get started

Should we convert mixins to the class-based component definition syntax in Vue 3?

After reading the plan for Vue 3, I noticed that the statement mixins will still be supported. However, Should I convert all of mixins components to class-based-components in case that Vue stops supporting mixins in the future?
mixins:
export default class MyComponent extends mixins(A, B, C) {
}
The class API that was originally planned for Vue 3 has been dropped and replaced with the composition API. While mixins will still be supported, composition functions have a number of advantages, such as avoiding namespace clashing, making it clearer where properties come from, and playing friendlier with Typescript.
Once Vue 3 is released I would recommend not writing more mixins but using Composition Functions. It'll be up to you to consider whether you rewrite old mixins - it will depend on whether you think the benefits of composition functions outweigh the initial cost of rewriting old mixins.

If Aurelia understands "import", why use dependency injection?

I don't understand.. if I can use import in Aurelia, why do I have to wire up the constructor with #autoinject() and all that? I'm sure I'm missing something, but, from what I can tell, I can just use my imported module whenever I want.
import something from "whatever"
export class SomeViewModel {
activate() {
// use something
}
}
Typically, in an Aurelia application, the thing you are importing isn't an instance of Something it's the class Something. To actually use whatever has been imported, you need an instance of it.
import Something from 'whatever';
let something = new Something();
When you use Aurelia's Dependency Injection system, you are utilizing a design pattern called "Inversion of Control." Instead of your class (or you) being in charge of instantiating its dependencies, it lists what dependencies it has and then has instances of the dependencies injected in to its constructor function.
This helps with testability, as now you can pass mocked instances of the dependencies to a class in your test fixtures (note that in your tests, your tests will pass the mocks to the constructor, and not rely on Aurelia's DI container).This also allows you to tap in to the Dependency Injection container's ability to be configured to create dependencies using different object lifestyles such as singletons and transient.
--- Edits to answer OP's questions from comments ---
If I import a module defined as export default class Something into an
aurelia view model using constructor injection, it does not need to be
instantiated. It is an instance of the class Something.
This is because Aurelia's Dependency Injection container is instantiating an instance for you. This is why your code looks like this:
import {inject} from 'aurelia-framework';
import Something from 'somewhere';
#inject(Something)
export class Foo {
constructor(something) {
this.something = something;
}
//...
}
and not
import Something from 'somewhere';
export class Foo {
constructor(Something) {
this.something = something;
}
//...
}
You are telling Aurelia "I need one of these, please give it to me," and Aurelia says "Sure thing, I've created one or I already had one lying around, here it is."
In other words, it appears that aurelia's constructor DI only works
with class exports, and it does instantiate the class. It looks like
if I want to import something like moment js into my aurelia view
model, I should just continue doing things the way I've always done
them (not using aurelia's DI). Does that sound correct?
This is correct. Libraries like moment give you a function to use, and not a class that can be instantiated by Aurelia. For these you would continue to use them as in the past.
Well technically you can use the imported modules without Aurelia's DI, but in most situations that would be a bad thing. The Dependency Injection layer gives you so much versatility and flexibility. It handles caching, it supports singleton and transient dependencies, handles lifetime and makes thing neater from an architectural perspective.