diff --git a/tests/integration/cqlengine/management/test_management.py b/tests/integration/cqlengine/management/test_management.py index 0a11a554..f8b3f703 100644 --- a/tests/integration/cqlengine/management/test_management.py +++ b/tests/integration/cqlengine/management/test_management.py @@ -420,6 +420,7 @@ class IndexTests(BaseCassEngTestCase): table_meta = management._get_table_metadata(IndexCaseSensitiveModel) self.assertIsNotNone(management._get_index_name_by_column(table_meta, 'second_key')) + @greaterthancass20 def test_sync_indexed_set(self): """ Tests that models that have container types with indices can be synced. diff --git a/tests/integration/cqlengine/operators/test_where_operators.py b/tests/integration/cqlengine/operators/test_where_operators.py index 72ff2f62..f297d248 100644 --- a/tests/integration/cqlengine/operators/test_where_operators.py +++ b/tests/integration/cqlengine/operators/test_where_operators.py @@ -17,6 +17,7 @@ from cassandra.cqlengine.operators import * import six + class TestWhereOperators(TestCase): def test_symbol_lookup(self): @@ -27,6 +28,7 @@ class TestWhereOperators(TestCase): self.assertEqual(op, expected) check_lookup('EQ', EqualsOperator) + check_lookup('NE', NotEqualsOperator) check_lookup('IN', InOperator) check_lookup('GT', GreaterThanOperator) check_lookup('GTE', GreaterThanOrEqualOperator) @@ -37,6 +39,7 @@ class TestWhereOperators(TestCase): def test_operator_rendering(self): """ tests symbols are rendered properly """ self.assertEqual("=", six.text_type(EqualsOperator())) + self.assertEqual("=!", six.text_type(NotEqualsOperator())) self.assertEqual("IN", six.text_type(InOperator())) self.assertEqual(">", six.text_type(GreaterThanOperator())) self.assertEqual(">=", six.text_type(GreaterThanOrEqualOperator())) diff --git a/tests/integration/cqlengine/statements/test_delete_statement.py b/tests/integration/cqlengine/statements/test_delete_statement.py index 2767c7da..aa449fc7 100644 --- a/tests/integration/cqlengine/statements/test_delete_statement.py +++ b/tests/integration/cqlengine/statements/test_delete_statement.py @@ -76,6 +76,10 @@ class DeleteStatementTests(TestCase): ds.add_where(Column(db_field='created_at'), InOperator(), ['0', '10', '20']) self.assertEqual(six.text_type(ds), 'DELETE FROM table WHERE "a" = %(0)s AND "created_at" IN %(1)s', six.text_type(ds)) + ds = DeleteStatement('table', None) + ds.add_where(Column(db_field='a'), NotEqualsOperator(), 'b') + self.assertEqual(six.text_type(ds), 'DELETE FROM table WHERE "a" != %(0)s', six.text_type(ds)) + def test_delete_conditional(self): where = [WhereClause('id', EqualsOperator(), 1)] conditionals = [ConditionalClause('f0', 'value0'), ConditionalClause('f1', 'value1')] diff --git a/tests/integration/cqlengine/statements/test_update_statement.py b/tests/integration/cqlengine/statements/test_update_statement.py index 5679457f..e81263ff 100644 --- a/tests/integration/cqlengine/statements/test_update_statement.py +++ b/tests/integration/cqlengine/statements/test_update_statement.py @@ -39,6 +39,9 @@ class UpdateStatementTests(unittest.TestCase): us.add_where(Column(db_field='a'), EqualsOperator(), 'x') self.assertEqual(six.text_type(us), 'UPDATE table SET "a" = %(0)s, "c" = %(1)s WHERE "a" = %(2)s', six.text_type(us)) + us.add_where(Column(db_field='a'), NotEqualsOperator(), 'y') + self.assertEqual(six.text_type(us), 'UPDATE table SET "a" = %(0)s, "c" = %(1)s WHERE "a" = %(2)s AND "a" != %(3)s', six.text_type(us)) + def test_context(self): us = UpdateStatement('table') us.add_assignment(Column(db_field='a'), 'b') diff --git a/tests/integration/cqlengine/test_lwt_conditional.py b/tests/integration/cqlengine/test_lwt_conditional.py index 2d4e3181..27174156 100644 --- a/tests/integration/cqlengine/test_lwt_conditional.py +++ b/tests/integration/cqlengine/test_lwt_conditional.py @@ -154,6 +154,62 @@ class TestConditional(BaseCassEngTestCase): TestConditionalModel.objects(id=t.id).iff(count=5).delete() self.assertEqual(TestConditionalModel.objects(id=t.id).count(), 0) + def test_delete_lwt_ne(self): + """ + Test to ensure that deletes using IF and not equals are honored correctly + + @since 3.2 + @jira_ticket PYTHON-328 + @expected_result Delete conditional with NE should be honored + + @test_category object_mapper + """ + + # DML path + t = TestConditionalModel.create(text='something', count=5) + self.assertEqual(TestConditionalModel.objects(id=t.id).count(), 1) + with self.assertRaises(LWTException): + t.iff(count__ne=5).delete() + t.iff(count__ne=2).delete() + self.assertEqual(TestConditionalModel.objects(id=t.id).count(), 0) + + # QuerySet path + t = TestConditionalModel.create(text='something', count=5) + self.assertEqual(TestConditionalModel.objects(id=t.id).count(), 1) + with self.assertRaises(LWTException): + TestConditionalModel.objects(id=t.id).iff(count__ne=5).delete() + TestConditionalModel.objects(id=t.id).iff(count__ne=2).delete() + self.assertEqual(TestConditionalModel.objects(id=t.id).count(), 0) + + def test_update_lwt_ne(self): + """ + Test to ensure that update using IF and not equals are honored correctly + + @since 3.2 + @jira_ticket PYTHON-328 + @expected_result update conditional with NE should be honored + + @test_category object_mapper + """ + + # DML path + t = TestConditionalModel.create(text='something', count=5) + self.assertEqual(TestConditionalModel.objects(id=t.id).count(), 1) + with self.assertRaises(LWTException): + t.iff(count__ne=5).update(text='nothing') + t.iff(count__ne=2).update(text='nothing') + self.assertEqual(TestConditionalModel.objects(id=t.id).first().text, 'nothing') + t.delete() + + # QuerySet path + t = TestConditionalModel.create(text='something', count=5) + self.assertEqual(TestConditionalModel.objects(id=t.id).count(), 1) + with self.assertRaises(LWTException): + TestConditionalModel.objects(id=t.id).iff(count__ne=5).update(text='nothing') + TestConditionalModel.objects(id=t.id).iff(count__ne=2).update(text='nothing') + self.assertEqual(TestConditionalModel.objects(id=t.id).first().text, 'nothing') + t.delete() + def test_update_to_none(self): # This test is done because updates to none are split into deletes # for old versions of cassandra. Can be removed when we drop that code