Skip to content

Commit

Permalink
Adds tests for filtering/sorting hybrid properties
Browse files Browse the repository at this point in the history
  • Loading branch information
jfinkels committed Feb 18, 2017
1 parent 1b03353 commit 1baea3f
Show file tree
Hide file tree
Showing 2 changed files with 102 additions and 0 deletions.
65 changes: 65 additions & 0 deletions tests/test_fetching.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@

from sqlalchemy import Column
from sqlalchemy import ForeignKey
from sqlalchemy import func
from sqlalchemy import Integer
from sqlalchemy import select
from sqlalchemy import Unicode
from sqlalchemy.ext.associationproxy import association_proxy
from sqlalchemy.ext.hybrid import hybrid_property
from sqlalchemy.orm import backref
from sqlalchemy.orm import relationship

Expand Down Expand Up @@ -54,15 +57,33 @@ class Person(self.Base):
age = Column(Integer)
name = Column(Unicode)

@hybrid_property
def is_minor(self):
if not hasattr(self, 'age') or self.age is None:
return False
return self.age <= 18

class Article(self.Base):
__tablename__ = 'article'
id = Column(Integer, primary_key=True)
author_id = Column(Integer, ForeignKey('person.id'))
author = relationship('Person', backref=backref('articles'))
comments = relationship('Comment')

@hybrid_property
def num_comments(self):
return len(self.comments)

@num_comments.expression
def num_comments(cls):
return select([func.count(self.Comment.id)]).\
where(self.Comment.article_id == cls.id).\
label('numcomments')

class Comment(self.Base):
__tablename__ = 'comment'
id = Column(Integer, primary_key=True)
article_id = Column(Integer, ForeignKey(Article.id))

@classmethod
def query(cls):
Expand Down Expand Up @@ -302,6 +323,50 @@ def test_sorting_null_field(self):
# TODO In Python 2.7 or later, this should be a set literal.
assert set(['1', '4']) == set(person_ids[:2])

def test_sorting_hybrid_property(self):
"""Test for sorting on a hybrid property."""
person1 = self.Person(id=1, age=10)
person2 = self.Person(id=2, age=20)
self.session.add_all([person1, person2])
self.session.commit()

query_string = {'sort': 'is_minor'}
response = self.app.get('/api/person', query_string=query_string)
document = loads(response.data)
people = document['data']
self.assertEqual(['2', '1'], list(map(itemgetter('id'), people)))

query_string = {'sort': '-is_minor'}
response = self.app.get('/api/person', query_string=query_string)
document = loads(response.data)
people = document['data']
self.assertEqual(['1', '2'], list(map(itemgetter('id'), people)))

def test_sorting_hybrid_expression(self):
"""Test for sorting on a hybrid property with a separate expression.
For more information, see GitHub issue #562.
"""
article1 = self.Article(id=1)
article2 = self.Article(id=2)
comment = self.Comment(id=1)
article1.comments = [comment]
self.session.add_all([article1, article2, comment])
self.session.commit()

query_string = {'sort': 'num_comments'}
response = self.app.get('/api/article', query_string=query_string)
document = loads(response.data)
articles = document['data']
self.assertEqual(['2', '1'], list(map(itemgetter('id'), articles)))

query_string = {'sort': '-num_comments'}
response = self.app.get('/api/article', query_string=query_string)
document = loads(response.data)
articles = document['data']
self.assertEqual(['1', '2'], list(map(itemgetter('id'), articles)))


class TestFetchResource(ManagerTestBase):

Expand Down
37 changes: 37 additions & 0 deletions tests/test_filtering.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,10 @@
from sqlalchemy import Column
from sqlalchemy import Date
from sqlalchemy import DateTime
from sqlalchemy import func
from sqlalchemy import ForeignKey
from sqlalchemy import Integer
from sqlalchemy import select
from sqlalchemy import Time
from sqlalchemy import Unicode
from sqlalchemy.ext.associationproxy import association_proxy
Expand Down Expand Up @@ -91,6 +93,16 @@ class Article(self.Base):
author_id = Column(Integer, ForeignKey('person.id'))
author = relationship('Person', backref=backref('articles'))

@hybrid_property
def has_comments(self):
return len(self.comments) > 0

@has_comments.expression
def has_comments(cls):
return select([func.count(self.Comment.id)]).\
where(self.Comment.article_id == cls.id).\
label('num_comments') > 0

class Person(self.Base):
__tablename__ = 'person'
id = Column(Integer, primary_key=True)
Expand Down Expand Up @@ -783,6 +795,31 @@ def test_hybrid_property(self):
person = people[0]
self.assertEqual(person['id'], '1')

def test_hybrid_expression(self):
"""Test for filtering on a hybrid property with a separate expression.
For more information, see GitHub issue #562.
"""
article1 = self.Article(id=1)
article2 = self.Article(id=2)
comment = self.Comment(id=1)
comment.article = article1
self.session.add_all([article1, article2, comment])
self.session.commit()

filters = [{'name': 'has_comments', 'op': '==', 'val': True}]
response = self.search('/api/article', filters)
document = loads(response.data)
articles = document['data']
self.assertEqual(['1'], sorted(article['id'] for article in articles))

filters = [{'name': 'has_comments', 'op': '==', 'val': False}]
response = self.search('/api/article', filters)
document = loads(response.data)
articles = document['data']
self.assertEqual(['2'], sorted(article['id'] for article in articles))


class TestSimpleFiltering(ManagerTestBase):
"""Unit tests for "simple" filter query parameters.
Expand Down

0 comments on commit 1baea3f

Please sign in to comment.