Skip to content

Commit

Permalink
Implemented Entity __eq__ method comparing all fields (SatelliteQE#350)
Browse files Browse the repository at this point in the history
(cherry picked from commit ecf91be)

(cherry picked from commit f231e8c)
  • Loading branch information
renzon committed Mar 9, 2017
1 parent 4a32630 commit a9bbd1b
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 10 deletions.
4 changes: 3 additions & 1 deletion nailgun/entity_fields.py
Expand Up @@ -62,7 +62,9 @@ class Field(object):
"""

def __init__(self, required=False, choices=None, default=_SENTINEL):
def __init__(self, required=False, choices=None, default=_SENTINEL,
unique=False):
self.unique = unique
self.required = required
if choices is not None:
self.choices = choices
Expand Down
35 changes: 26 additions & 9 deletions nailgun/entity_mixins.py
@@ -1,18 +1,19 @@
# -*- encoding: utf-8 -*-
"""Defines a set of mixins that provide tools for interacting with entities."""
import json as std_json
import threading
import time
from collections import Iterable
from datetime import date, datetime
from sys import version_info

from fauxfactory import gen_choice
from inflection import pluralize

from nailgun import client, config, signals
from nailgun.entity_fields import (
IntegerField, OneToManyField, OneToOneField, ListField)
import threading
import time

from sys import version_info
if version_info.major == 2: # pragma: no cover
# pylint:disable=import-error
from urlparse import urljoin
Expand Down Expand Up @@ -387,7 +388,7 @@ def __init__(self, server_config=None, **kwargs):
# `super`, but that's not always the case.
if not hasattr(self, '_fields'):
self._fields = {}
self._fields.setdefault('id', IntegerField())
self._fields.setdefault('id', IntegerField(unique=True))
if not hasattr(self, '_meta'):
self._meta = {}

Expand Down Expand Up @@ -539,18 +540,29 @@ def to_json(self):
"""
return std_json.dumps(self.to_json_dict())

def to_json_dict(self):
"""Create a dct with Entity properties for json encoding.
def to_json_dict(self, filter_fcn = None):
"""Create a dict with Entity properties for json encoding.
It can be overridden by subclasses for each standard serialization
doesn't work. By default it call _to_json_dict on OneToOne fields
and build a list calling the same method on each object on OneToMany
and build a list calling the same method on each OneToMany object's
fields.
Fields can be filtered accordingly to 'filter_fcn'. This callable
receives field's name as first parameter and fields itself as second
parameter. It must return True if field's value should be included on
dict and False otherwise. If not provided field will not be filtered.
:type filter_fcn: callable
:return: dct
"""
filter_fcn = filter_fcn or (lambda name, field: True)
fields, values = self.get_fields(), self.get_values()
filtered_fields = filter(
lambda tpl: filter_fcn(tpl[0], tpl[1]),
fields.items()
)
json_dct = {}
for field_name, field in fields.items():
for field_name, field in filtered_fields:
if field_name in values:
value = values[field_name]
if value is None:
Expand Down Expand Up @@ -578,7 +590,12 @@ def __eq__(self, other):
"""
if other is None:
return False
return self.to_json_dict() == other.to_json_dict()

def filter_unique_fields(_, field):
return not field.unique

return (self.to_json_dict(filter_unique_fields) ==
other.to_json_dict(filter_unique_fields))


class EntityDeleteMixin(object):
Expand Down
6 changes: 6 additions & 0 deletions tests/test_entity_mixins.py
Expand Up @@ -428,6 +428,12 @@ def test_eq(self):
mary_clone.list = [alice_clone]
self.assertEqual(mary, mary_clone)

def test_eq_on_unique_fields(self):
"""Assert __eq__ take only not unique fields into account"""
alice = SampleEntity(self.cfg, id=1, name='Alice')
alice_2 = SampleEntity(self.cfg, id=2, name='Alice')
self.assertEqual(alice, alice_2)

def test_repr_v1(self):
"""Test method ``nailgun.entity_mixins.Entity.__repr__``.
Expand Down

0 comments on commit a9bbd1b

Please sign in to comment.