J'utilise noeud, moka et chai pour mon application. Je souhaite tester que la propriété de données de résultats renvoyée est le même "type d'objet" que l'un de mes objets de modèle. (Très semblable à l'instance de chai). Je veux juste confirmer que les deux objets ont les mêmes ensembles de noms de propriété. les valeurs réelles des propriétés ne m'intéressent pas spécifiquement.
Disons que j'ai la personne modèle comme ci-dessous. Je souhaite vérifier que mes résultats.data ont toutes les mêmes propriétés que le modèle attendu. Donc, dans ce cas, une personne qui a un prénom et un nom.
Donc si results.data.lastName
et results.data.firstName
_ les deux existent, alors il devrait retourner vrai. Si l'un ou l'autre n'existe pas, il devrait retourner false. Un bonus serait si results.data a des propriétés supplémentaires comme results.data.surname, alors il renverrait false car le nom de famille n'existe pas dans Person.
le modèle
function Person(data) {
var self = this;
self.firstName = "unknown";
self.lastName = "unknown";
if (typeof data != "undefined") {
self.firstName = data.firstName;
self.lastName = data.lastName;
}
}
Vous pouvez sérialiser des données simples pour vérifier l’égalité:
data1 = {firstName: 'John', lastName: 'Smith'};
data2 = {firstName: 'Jane', lastName: 'Smith'};
JSON.stringify(data1) === JSON.stringify(data2)
Cela vous donnera quelque chose comme
'{firstName:"John",lastName:"Smith"}' === '{firstName:"Jane",lastName:"Smith"}'
En tant que fonction...
function compare(a, b) {
return JSON.stringify(a) === JSON.stringify(b);
}
compare(data1, data2);
Si vous utilisez le chai comme vous le dites, consultez http://chaijs.com/api/bdd/#equal-section
Si vous voulez juste vérifier les clés ...
function compareKeys(a, b) {
var aKeys = Object.keys(a).sort();
var bKeys = Object.keys(b).sort();
return JSON.stringify(aKeys) === JSON.stringify(bKeys);
}
devrait le faire.
2 Voici une version courte ES6 variadic:
function objectsHaveSameKeys(...objects) {
const allKeys = objects.reduce((keys, object) => keys.concat(Object.keys(object)), []);
const union = new Set(allKeys);
return objects.every(object => union.size === Object.keys(object).length);
}
Un peu test de performance (MacBook Pro - Intel Core i7 cadencé à 2,8 GHz, Node 5.5.0):
var x = {};
var y = {};
for (var i = 0; i < 5000000; ++i) {
x[i] = i;
y[i] = i;
}
Résultats:
objectsHaveSameKeys(x, y) // took 4996 milliseconds
compareKeys(x, y) // took 14880 milliseconds
hasSameProps(x,y) // after 10 minutes I stopped execution
Si vous voulez vérifier si les deux objets ont le même nom de propriétés, procédez comme suit:
function hasSameProps( obj1, obj2 ) {
return Object.keys( obj1 ).every( function( prop ) {
return obj2.hasOwnProperty( prop );
});
}
var obj1 = { prop1: 'hello', prop2: 'world', prop3: [1,2,3,4,5] },
obj2 = { prop1: 'hello', prop2: 'world', prop3: [1,2,3,4,5] };
console.log(hasSameProps(obj1, obj2));
De cette manière, vous ne pouvez vérifier que les propriétés itérables et accessibles des deux objets.
EDIT - 2013.04.26:
La fonction précédente peut être réécrite de la manière suivante:
function hasSameProps( obj1, obj2 ) {
var obj1Props = Object.keys( obj1 ),
obj2Props = Object.keys( obj2 );
if ( obj1Props.length == obj2Props.length ) {
return obj1Props.every( function( prop ) {
return obj2Props.indexOf( prop ) >= 0;
});
}
return false;
}
De cette façon, nous vérifions que les deux objets ont le même nombre de propriétés (sinon, ils n'ont pas les mêmes propriétés et nous devons renvoyer un false logique), puis, si le nombre correspond, nous allons vérifier s'ils ont les mêmes propriétés. Propriétés.
Bonus
Une amélioration possible pourrait consister à introduire également une vérification de type pour appliquer la correspondance sur chaque propriété.
Si vous voulez une validation approfondie comme @speculees, voici une réponse en utilisant deep-keys
(divulgation: je suis en quelque sorte un mainteneur de ce petit paquet)
// obj1 should have all of obj2's properties
var deepKeys = require('deep-keys');
var _ = require('underscore');
assert(0 === _.difference(deepKeys(obj2), deepKeys(obj1)).length);
// obj1 should have exactly obj2's properties
var deepKeys = require('deep-keys');
var _ = require('lodash');
assert(0 === _.xor(deepKeys(obj2), deepKeys(obj1)).length);
ou avec chai
:
var expect = require('chai').expect;
var deepKeys = require('deep-keys');
// obj1 should have all of obj2's properties
expect(deepKeys(obj1)).to.include.members(deepKeys(obj2));
// obj1 should have exactly obj2's properties
expect(deepKeys(obj1)).to.have.members(deepKeys(obj2));