WebStorm has a handy feature that allows you to quickly implement methods declared by interface. For example:
deserialize: (key: string, value: string) => ISearchFilter;
will get auto-implemented to
deserialize(key: string, value: string): ISearchFilter {
return undefined;
}
Is there a way to instruct WebStorm on how the method should be created? In my case, I'd love to see an implemented method throw an error. For example:
deserialize(key: string, value: string): ISearchFilter {
throw new Error(classname+":deserialize not yet implemented");
return undefined;
}
Is is possible to create such stubs with WebStorm?
You can try changing the TypeScript Implemented Method Body template in Settings | Editor | File and Code Templates, Code accordingly
Related
I am very new to testing and I'm struggling my way through all this new stuff I am learning. Today I want to write a test for a vuetify <v-text-field> component like this:
<v-text-field
v-model="user.caption"
label="Name"
:disabled="!checkPermissionFor('users.write')"
required
/>
my test should handle the following case:
an active, logged in user has a array in vuex store which has his permissions as a array of strings. exactly like this
userRights: ['dashboard', 'imprint', 'dataPrivacy']
the checkPermissionFor() function is doing nothing else then checking the array above with a arr.includes('x')
after it came out the right is not included it gives me a negotiated return which handles the disabled state on that input field.
I want to test this exact scenario.
my test at the moment looks like this:
it('user has no rights to edit other user overview data', () => {
const store = new Vuex.Store({
state: {
ActiveUser: {
userData: {
isLoggedIn: true,
isAdmin: false,
userRights: ['dashboard', 'imprint', 'dataPrivacy']
}
}
}
})
const wrapper = shallowMount(Overview, {
store,
localVue
})
const addUserPermission = wrapper.vm.checkPermissionFor('users.write')
const inputName = wrapper.find(
'HOW TO SELECT A INPUT LIKE THIS? DO I HAVE TO ADD A CLASS FOR IT?'
)
expect(addUserPermission).toBe(false)
expect(inputName.props('disabled')).toBe(false)
})
big questions now:
how can I select a input from vuetify which has no class like in my case
how can I test for "is the input disabled?"
wrapper.find method accepts a query string. You can pass a query string like this :
input[label='Name'] or if you know the exact index you can use this CSS query too : input:nth-of-type(2).
Then find method will return you another wrapper. Wrapper has a property named element which returns the underlying native element.
So you can check if input disabled like this :
const buttonWrapper = wrapper.find("input[label='Name']");
const isDisabled = buttonWrapper.element.disabled === true;
expect(isDisabled ).toBe(true)
For question 1 it's a good idea to put extra datasets into your component template that are used just for testing so you can extract that element - the most common convention is data-testid="test-id".
The reason you should do this instead of relying on the classes and ids and positional selectors or anything like that is because those selectors are likely to change in a way that shouldn't break your test - if in the future you change css frameworks or change an id for some reason, your tests will break even though your component is still working.
If you're (understandably) worried about polluting your markup with all these data-testid attributes, you can use a webpack plugin like https://github.com/emensch/vue-remove-attributes to strip them out of your dev builds. Here's how I use that with laravel mix:
const createAttributeRemover = require('vue-remove-attributes');
if (mix.inProduction()) {
mix.options({
vue: {
compilerOptions: {
modules: [
createAttributeRemover('data-testid')
]
}
}
})
}
as for your second question I don't know I was googling the same thing and I landed here!
I'm developing a web application using Angular 6. I have a question:
I'm creating a custom input component (for text input) such as:
#Component({
selector: 'input-text',
templateUrl: './input-text.component.html'
]
})
export class InputTextComponent {
#Input() pattern?: string;
}
I would like a user can insert a regular expression for the validation of the input field, in this way:
<input-text pattern="^[a-z0-9_-]{8,15}$"></input-text>
The template of my component is defined like this:
<input type="text" [attr.pattern]="pattern"/>
Unfortunately I know absolutely nothing about regular expressions.
I would like to do two things:
1 - Create a method that checks the validity of the regular expression and changes the visual style.
2 - Make sure that if the input (with a pattern field) is inserted into a form, the attribute form.valid remains false until the expression is valid.
Thanks for your help!
Check regex validity
You can simply catch exceptions thrown by the RegExp constructor when instanciating it.
try {
const regex = new RegExp(pattern);
} catch (error) {
// If it goes here, then the regex model is not correct
console.error(error.message)
}
Change the visual style
You can simply use the ngClass attribute to change your input style.
If you enter the catch statement, set a style variable to change the class like so
private hasBadInput: boolean;
// [...]
catch (error) {
hasBadInput= true;
}
Then apply a specific class in that case:
<input-text [ngClass]="{'yourErrorClass': hasBadInput}"><input-text>
Form validity
You did well using [attr.pattern], the form should automatically consider the entered pattern. You should try your form with a hard written regex before, and then use the input one.
Follow this official guideline to create Angular 2+ forms.
On Github, many Handlebars helpers are presented. You can find them here.
I'd like to use them, but have no Idea, how to include them. The code is looking as it's javascript (files are ending with .js ...), but words like 'import','export','default' are confusing me.
As I understand (guess), I have to include the if-condition.js at first. Later, the other (included) files refer to this file.
But when I do this, the console throws an Error:
Uncaught SyntaxError: Unexpected reserved word .
Has anyone an idea, how to get these codes working?
import and export are keywords for the upcoming module syntax in the next version of Javascript. You can use them today by using a transpiler to convert it to normal ES5 syntax.
However, if you're only using a few helpers, it's very easy to 'transpile' them by hand. Instead of exporting the function, just pass it to a Ember.Hanldebars.registerBoundHelper call. Here's the if-condition helper:
Ember.Handlebars.registerBoundHelper('if-condition', function() {
var args = [].slice.call(arguments);
var options = args.pop();
var context = (options.contexts && options.contexts[0]) || this;
if (!options.conditional) {
throw new Error("A conditional callback must be specified when using the if-condition helper");
}
// Gather all bound property names to pass in order to observe them
var properties = options.types.reduce(function(results, type, index) {
if (type === 'ID') {
results.push(args[index]);
}
return results;
}, []);
// Resolve actual values for all params to pass to the conditional callback
var normalizer = function() {
return Ember.Handlebars.resolveParams(context, args, options);
};
// This effectively makes the helper a bound helper
// NOTE: 'content' path is used so that multiple properties can be bound to using the `childProperties` argument,
// however this means that it can only be used with a controller that proxies values to the 'content' property
return Ember.Handlebars.bind.call(context, 'content', options, true, options.conditional, normalizer, properties);
});
I am using F# and Foq to write unit tests for a C# project.
I am trying to set up a mock of an interface whose method has an out parameter, and I have no idea how to even start. It probably has to do with code quotations, but that's where my understanding ends.
The interface is this:
public interface IGetTypeNameString
{
bool For(Type type, out string typeName);
}
In C# Foq usage for the interface looks like this:
[Fact]
public void Foq_Out()
{
// Arrange
var name = "result";
var instance = new Mock<IGetTypeNameString>()
.Setup(x => x.For(It.IsAny<Type>(), out name))
.Returns(true)
.Create();
// Act
string resultName;
var result = instance.For(typeof(string), out resultName);
// Assert
Assert.True(result);
Assert.Equal("result", resultName);
}
As for how to achieve that with F#, I am completely lost. I tried something along the lines of
let name = "result"
let instance = Mock<IGetTypeNameString>().Setup(<# x.For(It.IsAny<Type>(), name) #>).Returns(true).Create();
which results in the quotation expression being underlined with an error message of
This expression was expected to have type IGetTypeNameString -> Quotations.Expr<'a> but here has type Quotations.Expr<'b>
Without any indication what types a and b are supposed to be, I have no clue how to correct this.
:?>
(It gets even wilder when I use open Foq.Linq; then the Error List window starts telling me about possible overloads with stuff like Action<'TAbstract> -> ActionBuilder<'TAbstract>, and I get even loster....)
Any assistance or explanation greatly appreciated!
Edit:
So, as stated here, byref/out parameters can not be used in code quotations. Can this be set up at all then in F#?
Foq supports setting up of C# out parameters from C# using the Foq.Linq namespace.
The IGetTypeNameString interface can be easily setup in F# via an object expression:
let mock =
{ new IGetTypeNameString with
member __.For(t,name) =
name <- "Name"
true
}
For declarations that have no analog in F#, like C#'s protected members and out parameters, you can also use the SetupByName overload, i.e.:
let mock =
Mock<IGetTypeNameString>()
.SetupByName("For").Returns(true)
.Create()
let success, _ = mock.For(typeof<int>)
There is a cookbook for adding globals to the twig templating engine, but it doesn't get into doing the same thing for the php engine. How would I do this?
So I might have something like:
# config.yml
someSortOfReferenceToThePHPEngineInstance:
calls:
- [ addGlobals, ["foo", "bar"] ]
- [ addGlobals, ["myService", "#myService"] ]
And then access those like:
// templateName.contentType.php
<?
echo $foo; // echos "bar"
echo $myService->myMethod($foo); // echos the result of modifying "bar" with "myMethod" method of "myService" service
I could not find any documention on this for the PHP engine...
What does work however is:
Config:
//config.yml
parameters:
hello: "YO!"
PHP Template:
// index.html.php
<?php
print $view->container->parameters['hello'];
This does not fit as nicely as the twig convention... Maybe there is better way - I have not debugged any further...
Here are a couple of options:
If you create a base controller that all others inherit from, you can override symfony's render function and add keys to the parameters argument, like:
public function render($view, array $parameters = array(), Response $response = null){
if(!array_key_exists("bar", $parameters){
$parameters["foo"] = $this->get("foo");
}
if(!array_key_exists("bar", $parameters){
$parameters["bar"] = $this->get("bar");
}
return parent::render($view, $parameters, $response);
}
This is the only way I see to modify the "global" variables "globally", though they'll not be available in any views rendered by controllers you don't create (of course, those'll likely be done in Twig anyway and you can use the normal twig means of adding functionality).
The PHP rendering engine has what're called "helpers", which you can access via array keys of $view, like:
$view["foo"]->doSomething();
We created a class for easily making services into helpers:
use Symfony\Component\Templating\Helper\Helper as BaseHelper;
class Helper extends BaseHelper{
protected $name;
public $service;
public function __construct($name, $service){
$this->name = $name;
$this->service = $service;
}
public function __get($name){
if(isset($this->service->$name)){
return $this->service->$name;
}
}
public function __call($name, $arguments){
if(method_exists($this->service, $name)){
return call_user_func_array(array($this->service,$name), $arguments);
}
}
public function getName(){
return $this->name;
}
}
Then in our configuration under the services we'd add:
helper.foo:
class: %helper.class%
arguments:
name: "foo"
helper: "#foo"
tags:
- { name: templating.helper, alias: foo }
This would theoretically be available then to any view files, even those with controllers you don't have control of.
I had a very same problem. For some reason this feature is only available for Twig templating with TwigBundle. Both Twig and PHP templating engines provide possibility to define global variables, but only Twig engine has configuration for that. For me the only real way to achieve that is something you proposed in the question post - to define method calls (and this is the way Twig globals are registered).
Problem is, that with DI extensions you can't access service definition from outside your extension, so you can't add these calls from your DI extension. The way for me was to do that with DI compiler pass.
But I'm also developer of ChillDevViewHelpersBundle and since I was facing this problem in most of my projects I decided to implement it there for common use and you can use 0.1.8 release for this feature.