hapijs - route config 'id' attribute - won't accept string value - hapi.js

I'm not sure if this is a bug or not, so I'm asking here, rather than submitting a bug report.
In the documentation for the latest version of hapijs (16.1.1)
https://hapijs.com/api#serverlookupid
For server.lookup, it clearly indicates that an 'id' property can be a string.
const route = server.lookup('root');
However strings are expressively forbidden by the actual implementation code.
https://github.com/hapijs/hapi/blob/master/lib/connection.js#L340
Hoek.assert(id && typeof id === 'string', 'Invalid route id:', id);
Am I missing something here? Is this a bug, or an error in the documentation, or am I simply misunderstanding something?
It seems an strange limitation to impose. Strings are a lot more logical for a route id.
The other issue, is that in the index.d.ts, it specifically forces the use of a string parameter.
This functionality just seems completely broken. How am I supposed to use it, if when creating a route I need to use a numeric id, and then when trying to retrieve it I'm forced to use a string?

You are reading the assert backwards. The error message only displays if the assertion fails. If an id is provided it can only be of type string.

Related

References to IDs in APIs responses, null or 0?

I consider myself that 0 is not a good thing to do when returning information from an API
e.g.
{
userId: int|null
}
I have a colleague that insists in that userId should be 0 or -1, but that forces a system to know that the 0 means "not set", instead of null which is universally known as not set.
The same happens with string params, like logoUrl. However, in this case I think it is acceptable to have an empty string instead of null if the variable is not set or was unset.
Is there bibliography, standards, etc, that I can refer to?
I'm not aware of any standard around that, but the way I take those kind of decisions is by thinking about the way consumer services would read this response, the goal being to provide a very smooth and clean consuming workflow. This exercise can even be transformed into a documentation for your API consumers.
In your case, instead of returning a null/0 field, I would simply remove that field altogether when it's empty and let the consumers explicitly mark that field as optional in the model they use to deserialize this response.
In that way, they'll explicitly have to deal with those optional fields, than relying on the API to always provide a value for them.

Proper error propagation in clojure

I'm currently working on my first major project in clojure and have run into a question regarding coding style and the most "clojure-esque" way of doing something. Basically I have a function I'm writing which takes in a data structure and a template that the function will try to massage the data structure into. The template structure will look something like this:
{
:key1 (:string (:opt :param))
:key2 (:int (:opt :param))
:key3 (:obj (:tpl :template-structure))
:key4 (:list (:tpl :template-structure))
}
Each key is an atom that will be searched for in the given data structure, and it's value will be attempted to be matched to the type given in the template structure. So it would look for :key1 and check that it's a string, for instance. The return value would be a map that has :key1 pointing to the value from the given data structure (the function could potentially change the value depending on the options given).
In the case of :obj it takes in another template structure, and recursively calls itself on that value and the template structure, and places the result from that in the return. However, if there's an error I want that error returned directly.
Similarly for lists I want it to basically do a map of the function again, except in the case of an error which I want returned directly.
My question is what is the best way to handle these errors? Some simple exception handling would be the easiest way, but I feel that it's not the most functional way. I could try and babysit the errors all the way up the chain with tons of if statements, but that also doesn't seem very sporting. Is there something simple I'm missing or is this just an ugly problem?
You might be interested in schematic, which does pretty similar stuff. You can see how it's used in the tests, and the implementation.
Basically I defined an error function, which returns nil for correctly-formatted data, or a string describing the error. Doing it with exceptions instead would make the plumbing easier, but would make it harder to get the detailed error messages like "[person: [first_name: expected string, got integer]]".

Use UUID as action parameters in Play Framework

I'd like to use UUID as action parameters. However, unless I use .toString() on the UUID objects when generating the action URL's, Play seems to serialize the object differently; Something like this: referenceId.sequence=-1&referenceId.hashCode=1728064460&referenceId.version=-1&referenceId.variant=-1&referenceId.timestamp=-1&referenceId.node=-1
However, using toString "works", but when I redirect from one action to another by simply invoking the method directly, there's no way I can call toString, as the method expects a UUID. Therefore it gives me the representation shown above.
Is there any way I can intersect the serialization of a certain type?
aren't you able to just use string in your action parameter? you know that this string is an UUID, so you can always recreate UUID from it. Maybe this is not the solution for you but that's my first thought. As far as I know play serializes objects like that when passing them trough paremeters.
If this does not work for you try finding something here: http://www.playframework.org/documentation/1.2.4/controllers
I found a way to do this, but right now it means hacking a part of the frameworks code itself.
What you basically need is a TypeBinder for binding the value from the String to the UUID
and a small code change in
play/framework/src/play/data/binding/Unbinder.java
if (!isAsAnnotation) {
// We want to use that one so when redirecting it looks ok. We could as well use the DateBinder.ISO8601 but the url looks terrible
if (Calendar.class.isAssignableFrom(src.getClass())) {
result.put(name, new SimpleDateFormat(I18N.getDateFormat()).format(((Calendar) src).getTime()));
} else {
result.put(name, new SimpleDateFormat(I18N.getDateFormat()).format((Date) src));
}
}
}
//here's the changed code
else if (UUID.class.isAssignableFrom(src.getClass()))
{
result.put(name, src.toString());
}
else {
// this code is responsible for the behavior you're seeing right now
Field[] fields = src.getClass().getDeclaredFields();
for (Field field : fields) {
if ((field.getModifiers() & BeanWrapper.notwritableField) != 0) {
// skip fields that cannot be bound by BeanWrapper
continue;
}
I'm working with the framework authors on a fix for this. will come back later with results.
if you need this urgently, apply the change to the code yourself and rebuild the framework by issuing
ant
in the playframework/framework
directory.

Is it meaningful to verifyText() on an element that has just had type() executed on it?

I'm curious about whether the following functional test is possible. I'm working with PHPUnit_Extensions_SeleniumTestCase with Selenium-RC here, but the principle (I think) should apply everywhere.
Suppose I execute the following command on a particular div:
function testInput() {
$locator = $this->get_magic_locator(); // for the sake of abstraction
$this->type( $locator, "Beatles" ); // Selenium API call
$this->verifyText( $locator, "Beatles" ); // Selenium API call
}
Conceptually, I feel that this test should work. I'm entering data into a particular field, and I simply want to verify that the text now exists as entered.
However, the results of my test (the verifyText assertion fails) suggest that the content of the $locator element are empty, even after input.
There was 1 failure:
1) test::testInput
Failed asserting that <string:> matches PCRE pattern "/Beatles/".`
Has anyone else tried anything like this? Should it work? Am I making a simple mistake?
You should use verifyValue(locator,texttoverify) rather than verifyText(locator,value) for validating the textbox values
To answer your initial question ("Is it meaningful ..."), well, maybe. What you're testing at that point is the browser's ability to respond to keystrokes, which would be sort of lame. Unless you've got some JavaScript code wired to some of the field's properties, in which case it might be sort of important.
Standard programmer's answer - "It depends".

Why does resolveBinding() return null even though I setResolveBindings(true) on my ASTParser?

I am writing an Eclipse plug-in that uses JDT AST's ASTParser to parse a method. I am looking within that method for the creation of a particular type of object.
When I find a ClassInstanceCreation, I call getType() on it to see what type is being instantiated. I want to be sure that the fully-resolved type being dealt with there is the one I think it is, so I tell the resultant Type object to resolveBinding(). I get null back even though there are no compilation errors and even though I called setResolveBindings(true) on my ASTParser. I gave my ASTParser (via setSource()) the ICompilationUnit that contains my method, so the parser has access to the entire workspace context.
final IMethod method = ...;
final ASTParser parser = ASTParser.newParser(AST.JLS3);
parser.setResolveBindings(true);
parser.setSource(method.getCompilationUnit());
parser.setSourceRange(method.getSourceRange().getOffset(), method.getSourceRange().getLength());
parser.setKind(ASTParser.K_CLASS_BODY_DECLARATIONS);
final TypeDeclaration astRoot = (TypeDeclaration) parser.createAST(null);
final ClassInstanceCreation classInstanceCreation = walkAstAndFindMyExpression(astRoot);
final Type instantiatedType = classInstanceCreation.getType();
System.out.println("BINDING: " + instantiatedType.resolveBinding());
Why does resolveBinding() return null? How can I get the binding information?
Tucked away at the bottom of the overview of ASTParser.setKind(), carefully hidden from people troubleshooting resolveBinding() and setResolveBindings(), is the statement
Binding information is only computed when kind is K_COMPILATION_UNIT.
(from the online Javadoc)
I don't understand offhand why this would be the case, but it does seem to point pretty clearly at what needs to be different!