XPath: handling invalid second parameter of contains() function - xpath

I have kind of invalid xpath expression where second parameter is not a string:
//ng-messages/span[contains(., fieldName)]
This expression still returns some of span's. I'm curious how xpath handles this invalid second parameter.

The predicate in expression span[contains(., fieldName)] checks if the current span element contains the value of string(fieldName), where fieldName is child of the span.
The predicate will evaluates to true if fieldName exists whatever its content, because fieldName is part of the span. And it is also evaluates to true when the span doesn't have child fieldName, because string(fieldName) will then returns an empty string and the expression contains('whatever', '') is always evaluates to true.

See XPath 1.0, §3.2 Function Calls:
A FunctionCall expression is evaluated by using the FunctionName to identify a function in the expression evaluation context function library, evaluating each of the Arguments, converting each argument to the type required by the function, and finally calling the function, passing it the converted arguments.
An argument is converted to type string as if by calling the string function. (...)
contains() is defined like this:
Function: boolean contains(string, string)
The contains function returns true if the first argument string contains the second argument string, and otherwise returns false.
And finally, the string() function has all cases defined depending on the input: node-set, number, boolean. If it's something else:
An object of a type other than the four basic types is converted to a string in a way that is dependent on that type.
At first sight, I don't know how your XPath engine will convert fieldName.

Related

Why cant nullable arrays/hashmaps be accessed using []

When I have a nullable array/list/hashmap such as
var x: ArrayList<String>? = null
I know can access the element at index 1 like so
var element = x?.get(1)
or I could do it in a unsafe way like this
var element = x!![1]
but why can't I do something like this
var element = x?[1]
what's the difference between getting elements from an array using the first example and the last example, and why is the last example not allowed?
In the first example, you're using the safe call operator ?. to call the get function with it.
In the second example, you're using the [] operator on the non-nullable return value of the x!! expression, which of course is allowed.
However, the language simply doesn't have a ?[] operator, which would be the combination of the two. The other operators offered are also don't have null-safe variants: there's no ?+ or ?&& or anything like that. This is just a design decision by the language creators. (The full list of available operators is here).
If you want to use operators, you need to call them on non-nullable expressions - only functions get the convenience of the safe call operator.
You could also define your own operator as an extension of the nullable type:
operator fun <T> List<T>?.get(index: Int) = this?.get(index)
val x: ArrayList<String>? = null
val second = x[2] // null
This would get you a neater syntax, but it hides the underlying null handling, and might confuse people who don't expect this custom extension on collections.

Is 'x?.y' in Swift the same as 'x?' followed by '.y'?

I understand that in Swift, if I define
var opt:String? = "Optional"
I will get an error if I attempt
opt.isEmpty
since opt is of type String? which does does not have an isEmpty method. And I thought that I understood that
opt?.isEmpty
does not produce an error because opt? unwraps (any non-nil) opt, resulting in a String, which does have an isEmpty method. But
opt?
on its own results in a String? and not a String.
Is ?. a different operator from ? followed by .?
Try
(opt?).isEmpty
and get a suggestive error.
Yes opt?.isEmpty is different from String?.It is called optional chaining.From swift programming guide:
You specify optional chaining by placing a question mark (?) after the
optional value on which you wish to call a property, method or
subscript if the optional is non-nil. This is very similar to placing
an exclamation mark (!) after an optional value to force the
unwrapping of its value. The main difference is that optional chaining
fails gracefully when the optional is nil, whereas forced unwrapping
triggers a runtime error when the optional is nil.
This creates optional as you thinking
var opt:String?
Now
opt?.isEmpty //it will not crash if opt is nil
is same as except
opt!.isEmpty //it will crash if opt is nil
if opt! is nil than it will not crash at runtime.Optional chaining is used to call long sequences of optional without calling.Every optional chain returns optional i.e opt? returns optional unwraps it and if nil than not call isEmpty else call isEmpty and reutns value.
Also
(opt?).isEmpty
When you are writing above statement it is just optional(not optional of optional) and it fails to unwrap because of braces.So error is showing
$T2?? does not have a member named `isEmpty`
to unwrap it use
(opt?)!.isEmpty
it will return false
Edit: To clarify more
var o1 = opt?
var o2 = ((opt?)?)
is doing nothing in its own it just assign same value to o1,o2 i.e String?.
to unwrap opt and o1,o2 they both are optional and need single ! operator to unwrap it.
Also please do not misunderstood between String? and opt? they both are different when ? is used after some type in decleration it makes optional and when ? used after variable optit is used for unwrap in optional chaining and return optional value it is returning
Extra Stuff:
try this to more clarify
(((opt?)?)!).isEmpty //it will unwrap with single !
((((opt?)?)!)?).isEmpty //compiler will show suggestion to remove ?
the below statement makes optional of optional of optional
var opt:String??? = "Optional"
to unwrap
opt!!!.isEmpty
EDIT2
opt? always return optional but if opt is defined as String! it is implicit optional and opt? will return optional(explicit).But if opt is already optional opt? will do nothing
From swift programming guide
To put it another way:
If the type you are trying to retrieve is not optional, it will become optional because of the optional chaining.
If the type you are trying to retrieve is already optional, it will not become more optional because of the chaining.
Therefore:
If you try to retrieve an Int value through optional chaining, an Int? is always returned, no matter how many levels of chaining are used.
Similarly, if you try to retrieve an Int? value through optional chaining, an Int? is always returned, no matter how many levels of chaining are used.
But opt? on its own results in a String? and not a String.
Yes. According to the Swift language reference, Expressions, Postfix Expressions, Optional-Chaining Expression:
On its own, the postfix ? operator simply returns the value of its
argument as an optional.
So putting a ? by itself at the end of an optional is a complete no-op. It has no effect.
Is ?. a different operator from ? followed by .?
Yes. More specifically, ? has the optional-chaining effect when used in any "postfix expression", including when followed by () (function call), . (member access), and [] (subscript).

Typescript rest parameter in the middle of arguments list

I would like to declare a function which last parameter is always a callback. However when i do:
interface Statement extends events.EventEmitter {
bind(...args, callback?:(err?:Error)=>void) : Statement;
}
I get an error
error TS1014: Rest parameter must be last in list
Is it possible in typescript to heve Rest parameter not as a last param in the argument list? Is there any hack that could help me solve this problem?
While a rest parameter needs to be the last one, you can now use variadic tuple types in TS 4.0:
type VarCallback<T extends any[]> = (...args: [...T, (err?: Error) => void]) => void
VarCallback ensures, the last function parameter is a callback type (err?: Error) => void.
For example, declare a function type with the first two parameters string and number:
type MyCallback = VarCallback<[string, number]>
// (a1: string, a2: number, a3: (err?: Error | undefined) => void) => void
const myCb: MyCallback = (s, n, cb) => {/* your implementation */ }
// s,n,cb are strongly typed now
Live code sample
This isn't supported in TypeScript. The best you can do is ...args: any[], or only use libraries with more sensible parameter orderings.
The TypeScript spec for the rest parameter is aligned with ES6's: it is the last arg in the param list. You should change your argument order.
from TypeScript Language Spec (#Parameter List):
A signature’s parameter list consists of zero or more required parameters, followed by zero or more
optional parameters, finally followed by an optional rest parameter.
from ES6: rest parameters - Semantics:
The last parameter in the [[FormalParameters]] List is used for the rest parameter. Of the standard built-in ECMAScript objects, only Function objects implement [[HasRestParameters]].

TDD: What to test in code where is 800 and more possible outputs?

I have class that have properties IsMacro, Value, Visible, DataType and one method GetResolvedValue. I dont know what to test. I do some math and I figure out that there is over 800 possible outputs for that method.
enum DataTypeEnum:
Bool,
String,
DateTime,
Integer,
LongInteger,
Decimal,
...
class Macro
property bool IsMacro;
property string Value;
property bool Visible;
property DataTypeEnum DataType;
function GetResolvedValue(Resolver) {
string value = Value;
if (IsMacro && Visilbe) {
value = Resolver.resolve(value);
}
switch (DataType){
case String:
// returns value if is string e.g.: "text"
// othervise returns empty string
case Bool:
// returns value if is bool string e.g.: "true"
// othervise returns empty string
case DateTime:
// returns value if is DateTime string e.g.: "2/2/2010"
// othervise returns empty string
...
}
}
So it must always return string with value that is valid for associated datatype or empty string.
With this code there is a lot of combinations and I dont know how to test it. Shoud I test all posible solutions?
Listen to your tests!
Even now, before even being written, your tests tell you that this method massively violates the SRP and needs to be refactored.
You should probably extract a whole hierarchy of classes from this one method.

Is it possible to pass a Razor construct to a helper method, using Razor's #: operator?

I am trying to pass some Html constructed by using razor's #: operator to a helper method, but I can not figure out how to do this. The compiler states that the Razor expression is a lambda expression, but it does not say, what is this lambda expression like... no clues at all!
If I try to do this:
#(MyClass.MyMethod(new
{
Html = #:<div></div>
}
))
The error is as follows:
Cannot assign lambda expression to anonymous type property
If I try this instead, then it states it as being a lambda again:
#(MyClass.MyMethod(
#:<div></div>
))
If the MyMethod receives a string: i.e. public string MyMethod(string razorConstructedString)
, then the compiler says: Cannot convert lambda expression to type 'string' because it is not a delegate type.
The question is: what type should I declare MyMethod, so that it can receive the razor constructed parameter?
Thanks!
This is called an inline helper.
It's a Func<AnyType, HelperResult>.
You can call this delegate with a parameter, and the parameter will be accessible in the helper, named item.

Resources