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.
Related
I'm looking to perform custom assertions on fields in JSON loaded from file.
I understand that we have fuzzy matching, but I'd like to perform something more custom e.g. have a function which parses a date as a LocalDateTime:
public class DateUtil {
public static boolean matchesMyDateFormat(String dateStr) {
try {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
LocalDateTime.parse(dateStr, formatter);
} catch (DateTimeParseException e) {
return false;
}
return true;
}
}
This would be called by the following:
* def matchesMyDateFormat =
"""
function fn(dateX){
return Java.type('com.karate.DateUtil').matchesMyDateFormat(dateX);
}
"""
* def expected = read('expected.json')
* def actual = read('actual.json')
* match expected == actual
Where expected.json looks like this:
{
"date1" : "#? matchesMyDateFormat(_)"
}
NB this is specifically for JSON loaded from file and not on JSON which is specified in the feature file itself (e.g. like for isValidTime() here: https://github.com/intuit/karate/blob/master/karate-junit4/src/test/java/com/intuit/karate/junit4/demos/schema-like.feature).
Few reasons for wishing to do it this way:
Some of the payloads I need to assert have a lot of date fields coming back, with different formats. Asserting like the above would tie in nicely with Karate's excellent way of validating schema. Doing this in the feature files, however, would require a lot of code, i.e. a line of code for each date (I realize match each could be used - but even this would get complex, depending on the nesting of the fields.)
I would be able to add this function to my common utils feature file, so it can be re-used throughout the project's expected response schema.
Beyond this I'd be looking to do other things, like check that one date occurs before another (but I'd want to do this using various types in Java, e.g. taking time zone into consideration).
I'd also be looking for the format matching method to take in another param, which lets the tester specify a custom format string.
NB: I've read through the docs and the other SO answers related to date assertions and believe this is a slightly different ask.
Is the above possible to do in Karate at the moment?
You can add functions in karate-config.js which will be "global". For example:
var config = {};
config.isValidDate = read('classpath:is-valid-date.js');
return config;
Now you can use isValidDate(_) in any feature. Note that JS functions can take multiple arguments, e.g:
* match foo == { bar: "#? isValidDate(_, 'MYFORMAT')" }
In 0.9.6.RC4 we made improvements so that you can move complex conditional logic and even match operations into re-usable JS files: https://github.com/intuit/karate/issues/1202
Be warned, doing a lot of this may lead to un-readable tests: https://stackoverflow.com/a/54126724/143475
One hint, you can use karate.forEach() to extract all date-fields into an array and then a single match each may work.
Finally, if you still feel there is "too much code in your feature files", I don't know, maybe you need to consult a magician.
What I was trying was in fact a valid use-case (as is the alternative solution kindly suggested by Peter Thomas in his answer).
The reason my particular variation wasn't working was this error:
07:22:50.421 assertion failed: path: $.date1, actual: '#? matchesMyDateFormat(_)', expected: '2020-06-10T14:44:57.060Z', reason: not equal
I noticed with a fresh pair of eyes that I should flip the match statement from:
* match expected == actual
To:
* match actual == expected
This way is required in order for Karate to work its magic and call the custom function in expected.json.
How can I check if a riot tag has already been loaded and compiled (in-browser with script tag), in order to avoid doing it again, programmatically.
In other words, what should I use instead of doesTagExist function in my simplified code, below?
if (!doesTagExist('my-tag')) {
riot.compile('/path/to/my-tag', function() {
riot.mount('dom-node', 'my-tag');
});
} else {
riot.mount('dom-node', 'my-tag');
}
had same problem. After bit of research I think you can't get it directly. Implementation is stored inside __TAG_IMPL which is not accessible from outside. You can however access selector for all implemented tags via riot.util.tags.selectTags(), which returns comma separated list of selectors i.e. datepicker,[data-is="datepicker"].
Oneliner for convenience
riot.util.tags.selectTags().search(/(^|,)my-tag($|,)/g) >= 0
or depending on your purity inclination
riot.util.tags.selectTags().search('"my-tag"')
Note, that first version is future-proof, if riot decides to start using single commas in selector.
I want to inject some functions to Backboardd, because of some reasons, I can not use plist to restrict it, so I want to use "if" to determine whether it's inside Backboardd.I know in 'Logos' I can use like that:
%ctor{
if (%c(SpringBoard)) {
}
}
But without Logos, can I do it like below?It doesn't work.
MSInitialize {
if (objc_getClass("Backboardd")) {
CFMessagePortRef local = CFMessagePortCreateLocal(NULL, CFSTR(MACH_PORT_NAME), messageCallBack, NULL, NULL);
CFRunLoopSourceRef source = CFMessagePortCreateRunLoopSource(NULL, local, 0);
CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
}
}
In general, you need to find some obj-c class that is unique to what you are hooking. Ideally, it should be class defined inside that binary, not imported from a framework. For example, in SpringBoard there is SpringBoard class that can only be found inside SpringBoard's binary. If objc_getClass("SpringBoard") returns non NULL value then you're inside the SpringBoard.
Now, backboardd. What I'm doing in cases like that is copying binary on my PC and obtaining the list of all classes inside that binary using class-dump or IDA. In case of backboardd, good candidate would be BKApplication. So
if (objc_getClass("BKApplication")) {
...
}
would do the job. There is no Backboardd class in backboardd.
And just for the future, use more popular tags for the questions like that. You have a better chance of getting an answer if you use jailbreak or iphone-privateapi tags.
Custom parameters in a CDE/CTools dashboard are great for defaulting initial values of parameters, e.g. setting a date parameter to today. i.e. the parameter looks like:
function() {
// some code
return val
}
However there is an issue with them. The first time you access a "custom parameter" in code, it is a function not a string. So you have to use:
paramName()
To get its value.
Once the end user selects a value then you have to use
paramName
This is really awkward in complicated dashboards with lots of prompts. Is there a better way this can be done? (Perhaps there is something in javascript I'm missing to help here?)
OK, there is a solution, but I dont like it!
First; Move all the init code into named procedures e.g.
function monthInit() {
return "june";
}
Then in the custom parameter for month, just say:
monthInit();
That way the custom parameter is always a string, and never starts off as a function.
Not ideal though because then all your init code is in a separate bit of js.
Is there a simple way to check the type of an object? I need something along the following lines:
MyObject^ mo = gcnew MyObject();
Object^ o = mo;
if( o->GetType() == MyObject )
{
// Do somethine with the object
}
else
{
// Try something else
}
At the moment I'm using nested try-catch blocks looking for System::InvalidCastExceptions which feels ugly but works. I was going to try and profile something like the code above to see if it's any faster/slower/readable but can't work out the syntax to even try.
In case anyone's wondering, this comes from having a single queue entering a thread which supplied data to work on. Occasionally I want to change settings and passing them in via the data queue is a simple way of doing so.
You can use MyObject::typeid in C++/CLI the same way as typeof(MyObject) is used in C#. Code below shamelessly copied from your question and modified ...
MyObject^ mo = gcnew MyObject();
Object^ o = mo;
if( o->GetType() == MyObject::typeid )
{
// Do somethine with the object
}
else
{
// Try something else
}
You should check out How to: Implement is and as C# Keywords in C++:
This topic shows how to implement the functionality of the is and as C# keywords in Visual C++.
edit: I will leave this here. But this answer is for C++. Probably not even slightly related to doing this for the CLI.
You need to compile with RTTI(Run Time Type Information) on. Then look at the wikipedia article http://en.wikipedia.org/wiki/Run-time_type_information and search google for RTTI. Should work for you.
On the other hand you might want to have a virtual base class for all your data classes with a member variable that describes what type it is.