Skip to content

Commit

Permalink
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
tests: Use direct values instead of raw SQL
Browse files Browse the repository at this point in the history
Supersedes #11.

In order to prevent (-1) from being masked by BitField.get_prep_value
and converted to 15 (0xf), the test code uses a direct SQL statement.
Its implementation has a few peculiarities that may be undesirable:

- It uses an Django internal API, the Field.column attribute.  Granted,
  this package already uses a lot of internal APIs, and Field.column
  is highly unlikely to change.  However, in general using less internal
  APIs is better for future compatibility.

- Using low-level API misses a lot of code paths that could have been
  tested.

- Neither db_table nor db_column is escaped.  In case we later
  incorporate tests involving pathological SQL object identifiers, we
  have to further use quote_name, which is not exactly public API
  either.

Instead, we use models.Value() with an explicit output_field, which
still avoids BitField.get_prep_value and inserts the value directly.

Further, directly assign to __dict__ so that the BitFieldCreator
descriptor's __set__ method is bypassed and the value is assigned
unchanged.
iamahuman committed Jan 18, 2021

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent e2b295c commit ea34e02
Showing 1 changed file with 7 additions and 6 deletions.
13 changes: 7 additions & 6 deletions bitfield/tests/tests.py
Original file line number Diff line number Diff line change
@@ -2,7 +2,7 @@

import pickle

from django.db import connection, models
from django.db import models
from django.db.models import F
from django.test import TestCase

@@ -155,11 +155,12 @@ def test_regression_1425(self):
self.assertTrue(instance.flags.FLAG_2)
self.assertTrue(instance.flags.FLAG_3)

cursor = connection.cursor()
flags_field = BitFieldTestModel._meta.get_field('flags')
flags_db_column = flags_field.db_column or flags_field.name
cursor.execute("INSERT INTO %s (%s) VALUES (-1)" % (BitFieldTestModel._meta.db_table, flags_db_column))
# There should only be the one row we inserted through the cursor.
# Bypass BitField.to_python and insert (-1) directly.
instance = BitFieldTestModel()
instance.__dict__['flags'] = models.Value(-1, output_field=models.IntegerField())
instance.save()

# There should only be the one row we inserted with a direct value.
instance = BitFieldTestModel.objects.get(flags=-1)
self.assertTrue(instance.flags.FLAG_0)
self.assertTrue(instance.flags.FLAG_1)

0 comments on commit ea34e02

Please sign in to comment.