diff --git a/fakeredis.py b/fakeredis.py index 29e7196..42cc0a7 100644 --- a/fakeredis.py +++ b/fakeredis.py @@ -475,13 +475,16 @@ def setbit(self, name, offset, value): # bit. needed = byte - (len(val) - 1) val += b'\x00' * needed + old_byte = byte_to_int(val[byte]) if value == 1: - new_byte = byte_to_int(val[byte]) | (1 << actual_bitoffset) + new_byte = old_byte | (1 << actual_bitoffset) else: - new_byte = byte_to_int(val[byte]) ^ (1 << actual_bitoffset) + new_byte = old_byte & ~(1 << actual_bitoffset) + old_value = value if old_byte == new_byte else not value reconstructed = bytearray(val) reconstructed[byte] = new_byte self._db[name] = bytes(reconstructed) + return bool(old_value) def setex(self, name, time, value): if isinstance(time, timedelta): diff --git a/test_fakeredis.py b/test_fakeredis.py index c98a34b..e91adb3 100644 --- a/test_fakeredis.py +++ b/test_fakeredis.py @@ -171,6 +171,20 @@ def test_unset_bits(self): self.redis.setbit('foo', 3, 0) self.assertEqual(self.redis.getbit('foo', 3), 0) + def test_get_set_bits(self): + # set bit 5 + self.assertFalse(self.redis.setbit('a', 5, True)) + self.assertTrue(self.redis.getbit('a', 5)) + # unset bit 4 + self.assertFalse(self.redis.setbit('a', 4, False)) + self.assertFalse(self.redis.getbit('a', 4)) + # set bit 4 + self.assertFalse(self.redis.setbit('a', 4, True)) + self.assertTrue(self.redis.getbit('a', 4)) + # set bit 5 again + self.assertTrue(self.redis.setbit('a', 5, True)) + self.assertTrue(self.redis.getbit('a', 5)) + def test_setbits_and_getkeys(self): # The bit operations and the get commands # should play nicely with each other.