Qobjectの比較
djangoのQobjectの比較する関数を書いた。Qobjectは順序不同になるので、比較がめんどうだった。
(他に楽に比較する方法があるのかもしれないけれど)
- 別にnoseの関数を使う必要はないけれど。
from django.conf import settings settings.configure() from django.db.models import Q from nose.tools import eq_, ok_ from itertools import izip def q_equal(q1, q2): if hasattr(q1, "connector") and hasattr(q2, "connector"): if q1.connector == q2.connector: for x, y in izip(sorted(q1.children, key=str), sorted(q2.children, key=str)): if not q_equal(x, y): return False return True else: return q1 == q2 def q_eq(q1, q2): try: ok_(q_equal(q1, q2)) except AssertionError, e: print("a:%s" % q1) print("b:%s" % q2) raise e def test_success_simple(): q_eq(Q(x="foo"), Q(x="foo")) def test_fail_simple(): q_eq(Q(x="foo"), Q(x="bar")) def test_success_2elements(): q_eq(Q(x="foo")& Q(y="bar"), Q(y="bar") & Q(x="foo")) def test_success_3elements(): qobj0 = Q(x="foo") & Q(y="bar") & Q(z="boo") qobj1 = Q(y="bar") & Q(z="boo") & Q(x="foo") q_eq(qobj0, qobj1) def test_fail_3elements(): qobj0 = Q(x="foo") & Q(y="bar") & Q(z="boo") qobj1 = Q(y="bar") | Q(z="boo") & Q(x="foo") q_eq(qobj0, qobj1)
AssertaionErrorが出たときのdiffの表示が適当過ぎるような気もするけれど。
実行結果
5つテストして、2つ失敗するテスト.
$ nosetest compare_qobject.py correct: nosetest -> nosetests [nyae]? y y ====================================================================== FAIL: compare_qobject.test_fail_simple ---------------------------------------------------------------------- Traceback (most recent call last): File "/usr/local/lib/python2.6/dist-packages/nose/case.py", line 187, in runTest self.test(*self.arg) File "/home/podhmo/compare_qobject.py", line 31, in test_fail_simple q_eq(Q(x="foo"), Q(x="bar")) File "/home/podhmo/compare_qobject.py", line 24, in q_eq raise e AssertionError: -------------------- >> begin captured stdout << --------------------- a:(AND: ('x', 'foo')) b:(AND: ('x', 'bar')) --------------------- >> end captured stdout << ---------------------- ====================================================================== FAIL: compare_qobject.test_fail_3elements ---------------------------------------------------------------------- Traceback (most recent call last): File "/usr/local/lib/python2.6/dist-packages/nose/case.py", line 187, in runTest self.test(*self.arg) File "/home/podhmo/compare_qobject.py", line 44, in test_fail_3elements q_eq(qobj0, qobj1) File "/home/podhmo/compare_qobject.py", line 24, in q_eq raise e AssertionError: -------------------- >> begin captured stdout << --------------------- a:(AND: ('x', 'foo'), ('y', 'bar'), ('z', 'boo')) b:(OR: ('y', 'bar'), (AND: ('z', 'boo'), ('x', 'foo'))) --------------------- >> end captured stdout << ---------------------- ---------------------------------------------------------------------- Ran 5 tests in 0.002s FAILED (failures=2)