Underscore isObject() sometimes not work - backbone.js

When I use nodeUnit to write unit tests for Backbone models, something weird happened, the question can be summarized as:
var Player = Backbone.Model.extend({});
var player = new Player({name: 'Jacky'});
Then I update the player name with: player.set('name', 'Scott').
But I found that the name attribute is not updated at all(No validate function for this model), and there are weird attributes like: [0]: n, [1]: a, [2]: m, [3]: e.
It works fine if I changed the update method to player.set({name: 'Scott'}).
I did some quick investigation and found that Backbone.Model.set method depends on Underscore.isObject() method, and the latter is implemented as:
_.isObject = function(obj) {
return obj === Object(obj);
};
I called the isObject() method in nodeUnit test cases, and in the first case it works fine, but in latter cases, it does not work as expected, for example isObject('name') will return true instead of the expected false.
Anyone have any idea what caused this?

Can you make sure that you are using the latest version of Backbone? Backbone in older versions didn't support shortcut version for the set method (.set(key, value)) and allowed only object with attribute/value pairs as a parameter.
(i believe it was added in 0.9)

Related

Use content of a tuple as variable session

I extracted from a previous response an Object of tuple with the following regex :
.check(regex(""""idSc":(.{1,8}),"pasTemps":."codePasTemps":(.),"""").ofType[(String,String)].findAll.saveAs ("OBJECTS1"))
So I get my object :
OBJECTS1 -> List((1657751,2), (1658105,2), (4557378,2), (1657750,1), (916,1), (917,2), (1658068,1), (1658069,2), (4557379,2), (1658082,1), (4557367,1), (4557368,1), (1660865,2), (1660866,2), (1658122,1), (921,1), (922,2), (923,2), (1660875,1), (1660876,2), (1660877,2), (1658300,1), (1658301,1), (1658302,1), (1658309,1), (1658310,1), (2996562,1), (4638455,1))
After that I did a Foreach and need to extract every couple to add them in next requests So we tried :
.foreach("${OBJECTS1}", "couple") {
exec(http("request_foreach47"
.get("/ctr/web/api/seriegraph/bydates/${couple(0)}/${couple(1)}/1552863600000/1554191743799")
.headers(headers_27))
}
But I get the message : named 'couple' does not support index access
I also though that to use 2 regex on the couple to extract both part could work but I haven't found any way to use a regex on a session variable. (Even if its not needed for this case but possible im really interessed to learn how as it could be usefull)
If would be really thankfull if you could provided me help. (Im using Gatling 2 but can,'t use a more recent version as its for work and others scripts have been develloped with Gatling2)
each "couple" is a scala tuple which can't be indexed into like a collection. Fortunately the gatling EL has a function that handles tuples.
so instead of
.get("/ctr/web/api/seriegraph/bydates/${couple(0)}/${couple(1)}/1552863600000/1554191743799")
you can use
.get("/ctr/web/api/seriegraph/bydates/${couple._1}/${couple._2}/1552863600000/1554191743799")

Jasmine - How to Write Test for Array with Named properties and Object

I ran into a strange situation today, thanks to Javascript. I have a Object that look something like this.
$scope.main = [{main : 1},service:true];
Now when I try to expect this inside the jasmine test case for equating the Objects :
expect($scope.main).toEqual([{main : 1},service:true]);
This gives me an error :
Unexpected Token.
Strangely, This is a valid object for Javascript. But Jasmine is not able to accept that.
Is there any way to test this?
Thanks in advance!
EDIT : Attaching a structure screenshot.
Update
I see now based on your screenshot that you are creating the main object in multiple steps. I've shortened it to the following:
var main = [{main: 1}];
main.service = true;
In dev-tools, you are seeing main as something that looks like this: [{main: 1}, service: true].
However, don't be mislead. Dev-tools is showing you a structure that is just meant to be informative. You can't actually create that structure in one line of javascript, because it is invalid. You have to create it in multiple steps, like you have.
This is why when you try to create it in your test in one line, you are getting an Unexpected Token. error. In your test, you have to create the expected object in a similar fashion to how you created your main object. For example:
var expected = [{main: 1}];
expected.service = true;
expect(main).toEqual(expected);

Extending Array in Typescript breaks constructor

while playing around with typescript I ran into then following interesting behavior:
class ExtArray<U> extends Array<U> {
constructor(...args : U[]) {
super(...args);
}
public contains(element : U) : boolean {
var i = this.indexOf(element);
return i !== -1;
}
}
var test : ExtArray<string> = new ExtArray("a", "b", "c");
test.push("y");
console.log(test.length); // 1
console.log(test[0]); // y
console.log(test[1]); // undefined
console.log("Has a: " + test.contains("a")); // Has a: false
console.log("Has y: " + test.contains("y")); // Has y : true
I've added the output of the console.log statements as comments.
See this typescript playground for an executable example and the javascript code.
As you can see it seems as if the elements passed to the constructor are not added to the array.
The section about extending expression in Whats new in Typescript suggests that it should be possible to extend the native Array type like that in typescript 1.6.
Also I didn't find anything in the typescript language reference,
that explains this behavior.
Most of the other questions about extending Arrays I found here are at least one year old and usually talk about a pre-1.0 version of typescript and therefore suggest to set up the prototype chain directly.
I seriously don't see what is going wrong here and I'm starting to suspect a typescript bug.
Or at least some kind of undocumented restriction for extending Arrays.
What goes wrong here?
It's a little easier to understand what's going on if you JSON.stringify() your object:
var test : ExtArray<string> = new ExtArray("a", "b", "c");
test.push("y");
// outputs {"0":"y","length":1}
document.writeln(JSON.stringify(test));
If you instead new-up a native Array, the resulting object is quite a bit different:
var test : Array<string> = new Array("a", "b", "c");
test.push("y");
// outputs ["a","b","c","y"]
document.writeln(JSON.stringify(test));
I agree with you that the documentation seems to imply that the subclass's constructor should behave the way you're expecting. Even stranger, I seem to get inconsistent results when testing whether or not the subclass is an Array using the methods described here:
test.constructor === Array // false
test instanceof Array // true
Array.isArray(test) // false
I would suggest opening an issue on the TypeScript GitHub repository. Even if this is the expected behavior, the official documentation is misleading and should clarify what exactly is expected when native objects are subclassed.

ndb query by KeyProperty

I'm struggling with a KeyProperty query, and can't see what's wrong.
My model is
class MyList(ndb.Model):
user = ndb.KeyProperty(indexed=True)
status = ndb.BooleanProperty(default=True)
items = ndb.StructuredProperty(MyRef, repeated=True, indexed=False)
I create an instance of MyList with the appropriate data and can run the following properly
cls = MyList
lists = cls.query().fetch()
Returns
[MyList(key=Key('MyList', 12), status=True, items=..., user=Key('User', 11))]
But it fails when I try to filter by user, i.e. finding lists where the user equals a particular entity; even when using the one I've just used for insert, or from the previous query result.
key = lists[0].user
lists = cls.query(cls.user=key).fetch()
Returns
[]
But works fine with status=True as the filter, and I can't see what's missing?
I should add it happens in a unit testing environment with the following v3_stub
self.policy = datastore_stub_util.PseudoRandomHRConsistencyPolicy(probability=0)
self.testbed.init_datastore_v3_stub(
require_indexes=True,
root_path="%s/../"%(os.path.dirname(__file__)),
consistency_policy=self.policy
)
user=Key('User', 11) is a key to a different class: User. Not MyList
Perhaps you meant:
user = ndb.KeyProperty(kind='User', indexed=True)
Your code looks fine, but I have noticed some data integrity issues when developing locally with NDB. I copied your model and code, and I also got the empty list at first, but then after a few more attempts, the data is there.
Try it a few times?
edit: possibly related?
google app engine ndb: put() and then query(), there is always one less item

Mongoid - Array assignment

I'm seeing some strange behaviour in Mongoid 2.3.4
class Student
has_and_belongs_to_many: teachers
end
class Teacher
has_and_belongs_to_many: students
end
Now in IRB
s = Student.first
s.teachers
=> []
s.teacher_ids = [Teacher.first.id, Teacher.last.id]
s.teacher_ids
=> [[BSON::ObjectId4f7c3300913417162c000008, BSON::ObjectId4f7c333b913417162c00000d]]
Not sure why this array is nested like that. I expected
[BSON::ObjectId4f7c3300913417162c000008, BSON::ObjectId4f7c333b913417162c00000d]
This breaks multi select fields in Rails, where the mass assignments of ids would happen like shown in IRB.
It may have to do with the fact that you're attempting to set the teachers_ids attribute to an array of Teacher objects.
You could try these as alternatives:
s.teachers = [Teacher.first, Teacher.last]
or
s.teachers << Teacher.first
s.teachers << Teacher.last
Update:
I've just run a little test and can confirm that your method of assignment works fine in Mongoid 2.4.6 (which is just what I happened to have installed) and 2.4.8.
If for some reason you can't upgrade to Mongoid 2.4, you could also try passing the IDs in as String objects instead of as ObjectId, which is how it would be handled if this was being passed in through POST parameters.
s.teacher_ids = [Teacher.first.id.to_s, Teacher.last.id.to_s]

Resources