Skip to content

Commit 42a87f2

Browse files
authored
DX: Cleanup tests using Ruff (#44)
1 parent ec873a7 commit 42a87f2

25 files changed

+209
-205
lines changed

.pre-commit-config.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,18 @@ repos:
1515
- id: check-yaml
1616
- id: debug-statements
1717
- id: end-of-file-fixer
18+
- id: mixed-line-ending
19+
- id: no-commit-to-branch
1820
- id: trailing-whitespace
1921

22+
- repo: https://github.com/crate-ci/typos
23+
rev: v1.32.0
24+
hooks:
25+
- id: typos
26+
args: []
27+
types_or:
28+
- python
29+
2030
- repo: https://github.com/asottile/pyupgrade
2131
rev: v3.20.0
2232
hooks:

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -289,8 +289,8 @@ In your model :
289289

290290
``` python
291291
class DbState(models.Model):
292-
id = models.CharField(primary_key=True, max_length=50)
293-
label = models.CharField(max_length=255)
292+
id = models.CharField(primary_key=True)
293+
label = models.CharField()
294294

295295
def __str__(self):
296296
return self.label

django_fsm/models.py

Lines changed: 0 additions & 3 deletions
This file was deleted.

pyproject.toml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,9 +66,8 @@ extend-ignore = [
6666
"B",
6767
"PTH",
6868
"ANN", # Missing type annotation
69+
"S101", # Use of `assert` detected
6970
"RUF012", # Mutable class attributes should be annotated with `typing.ClassVar`
70-
"PT", # Use a regular `assert` instead of unittest-style
71-
"DJ008", # Model does not define `__str__` method
7271
"ARG001", # Unused function argument
7372
"ARG002", # Unused method argument
7473
"TRY002", # Create your own exception
@@ -84,6 +83,10 @@ fixable = [
8483
"RUF100", # Unused `noqa` directive
8584
]
8685

86+
[tool.ruff.lint.extend-per-file-ignores]
87+
"tests/*" = [
88+
"DJ008", # Model does not define `__str__` method
89+
]
8790

8891
[tool.ruff.lint.isort]
8992
force-single-line = true

tests/testapp/models.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def draft(self):
2020
pass
2121

2222
@transition(field=state, source=["new", "draft"], target="dept")
23-
def to_approvement(self):
23+
def submitted(self):
2424
pass
2525

2626
@transition(field=state, source="dept", target="dean")
@@ -53,7 +53,7 @@ def draft(self):
5353
pass
5454

5555
@transition(field=state, source=["new", "draft"], target="dept")
56-
def to_approvement(self):
56+
def submitted(self):
5757
pass
5858

5959
@transition(field=state, source="dept", target="dean")

tests/testapp/tests/test_abstract_inheritance.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -42,20 +42,20 @@ def setUp(self):
4242
self.model = InheritedFromAbstractModel()
4343

4444
def test_known_transition_should_succeed(self):
45-
self.assertTrue(can_proceed(self.model.publish))
45+
assert can_proceed(self.model.publish)
4646
self.model.publish()
47-
self.assertEqual(self.model.state, "published")
47+
assert self.model.state == "published"
4848

49-
self.assertTrue(can_proceed(self.model.stick))
49+
assert can_proceed(self.model.stick)
5050
self.model.stick()
51-
self.assertEqual(self.model.state, "sticked")
51+
assert self.model.state == "sticked"
5252

5353
def test_field_available_transitions_works(self):
5454
self.model.publish()
55-
self.assertEqual(self.model.state, "published")
55+
assert self.model.state == "published"
5656
transitions = self.model.get_available_state_transitions()
57-
self.assertEqual(["sticked"], [data.target for data in transitions])
57+
assert [data.target for data in transitions] == ["sticked"]
5858

5959
def test_field_all_transitions_works(self):
6060
transitions = self.model.get_all_state_transitions()
61-
self.assertEqual({("new", "published"), ("published", "sticked")}, {(data.source, data.target) for data in transitions})
61+
assert {("new", "published"), ("published", "sticked")} == {(data.source, data.target) for data in transitions}

tests/testapp/tests/test_access_deferred_fsm_field.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,9 +29,9 @@ def setUp(self):
2929
self.model = DeferrableModel.objects.only("id").get()
3030

3131
def test_usecase(self):
32-
self.assertEqual(self.model.state, "new")
33-
self.assertTrue(can_proceed(self.model.remove))
32+
assert self.model.state == "new"
33+
assert can_proceed(self.model.remove)
3434
self.model.remove()
3535

36-
self.assertEqual(self.model.state, "removed")
37-
self.assertFalse(can_proceed(self.model.remove))
36+
assert self.model.state == "removed"
37+
assert not can_proceed(self.model.remove)

tests/testapp/tests/test_basic_transitions.py

Lines changed: 45 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import pytest
34
from django.db import models
45
from django.test import TestCase
56

@@ -53,70 +54,74 @@ def setUp(self):
5354
self.model = SimpleBlogPost()
5455

5556
def test_initial_state_instantiated(self):
56-
self.assertEqual(self.model.state, "new")
57+
assert self.model.state == "new"
5758

5859
def test_known_transition_should_succeed(self):
59-
self.assertTrue(can_proceed(self.model.publish))
60+
assert can_proceed(self.model.publish)
6061
self.model.publish()
61-
self.assertEqual(self.model.state, "published")
62+
assert self.model.state == "published"
6263

63-
self.assertTrue(can_proceed(self.model.hide))
64+
assert can_proceed(self.model.hide)
6465
self.model.hide()
65-
self.assertEqual(self.model.state, "hidden")
66+
assert self.model.state == "hidden"
6667

6768
def test_unknown_transition_fails(self):
68-
self.assertFalse(can_proceed(self.model.hide))
69-
self.assertRaises(TransitionNotAllowed, self.model.hide)
69+
assert not can_proceed(self.model.hide)
70+
with pytest.raises(TransitionNotAllowed):
71+
self.model.hide()
7072

7173
def test_state_non_changed_after_fail(self):
72-
self.assertTrue(can_proceed(self.model.remove))
73-
self.assertRaises(Exception, self.model.remove)
74-
self.assertEqual(self.model.state, "new")
74+
assert can_proceed(self.model.remove)
75+
with pytest.raises(Exception, match="Upss"):
76+
self.model.remove()
77+
assert self.model.state == "new"
7578

7679
def test_allowed_null_transition_should_succeed(self):
7780
self.model.publish()
7881
self.model.notify_all()
79-
self.assertEqual(self.model.state, "published")
82+
assert self.model.state == "published"
8083

8184
def test_unknown_null_transition_should_fail(self):
82-
self.assertRaises(TransitionNotAllowed, self.model.notify_all)
83-
self.assertEqual(self.model.state, "new")
85+
with pytest.raises(TransitionNotAllowed):
86+
self.model.notify_all()
87+
assert self.model.state == "new"
8488

8589
def test_multiple_source_support_path_1_works(self):
8690
self.model.publish()
8791
self.model.steal()
88-
self.assertEqual(self.model.state, "stolen")
92+
assert self.model.state == "stolen"
8993

9094
def test_multiple_source_support_path_2_works(self):
9195
self.model.publish()
9296
self.model.hide()
9397
self.model.steal()
94-
self.assertEqual(self.model.state, "stolen")
98+
assert self.model.state == "stolen"
9599

96100
def test_star_shortcut_succeed(self):
97-
self.assertTrue(can_proceed(self.model.moderate))
101+
assert can_proceed(self.model.moderate)
98102
self.model.moderate()
99-
self.assertEqual(self.model.state, "moderated")
103+
assert self.model.state == "moderated"
100104

101105
def test_plus_shortcut_succeeds_for_other_source(self):
102106
"""Tests that the '+' shortcut succeeds for a source
103107
other than the target.
104108
"""
105-
self.assertTrue(can_proceed(self.model.block))
109+
assert can_proceed(self.model.block)
106110
self.model.block()
107-
self.assertEqual(self.model.state, "blocked")
111+
assert self.model.state == "blocked"
108112

109113
def test_plus_shortcut_fails_for_same_source(self):
110114
"""Tests that the '+' shortcut fails if the source
111115
equals the target.
112116
"""
113117
self.model.block()
114-
self.assertFalse(can_proceed(self.model.block))
115-
self.assertRaises(TransitionNotAllowed, self.model.block)
118+
assert not can_proceed(self.model.block)
119+
with pytest.raises(TransitionNotAllowed):
120+
self.model.block()
116121

117122
def test_empty_string_target(self):
118123
self.model.empty()
119-
self.assertEqual(self.model.state, "")
124+
assert self.model.state == ""
120125

121126

122127
class StateSignalsTests(TestCase):
@@ -128,22 +133,23 @@ def setUp(self):
128133
post_transition.connect(self.on_post_transition, sender=SimpleBlogPost)
129134

130135
def on_pre_transition(self, sender, instance, name, source, target, **kwargs):
131-
self.assertEqual(instance.state, source)
136+
assert instance.state == source
132137
self.pre_transition_called = True
133138

134139
def on_post_transition(self, sender, instance, name, source, target, **kwargs):
135-
self.assertEqual(instance.state, target)
140+
assert instance.state == target
136141
self.post_transition_called = True
137142

138143
def test_signals_called_on_valid_transition(self):
139144
self.model.publish()
140-
self.assertTrue(self.pre_transition_called)
141-
self.assertTrue(self.post_transition_called)
145+
assert self.pre_transition_called
146+
assert self.post_transition_called
142147

143148
def test_signals_not_called_on_invalid_transition(self):
144-
self.assertRaises(TransitionNotAllowed, self.model.hide)
145-
self.assertFalse(self.pre_transition_called)
146-
self.assertFalse(self.post_transition_called)
149+
with pytest.raises(TransitionNotAllowed):
150+
self.model.hide()
151+
assert not self.pre_transition_called
152+
assert not self.post_transition_called
147153

148154

149155
class TestFieldTransitionsInspect(TestCase):
@@ -154,8 +160,8 @@ def test_in_operator_for_available_transitions(self):
154160
# store the generator in a list, so we can reuse the generator and do multiple asserts
155161
transitions = list(self.model.get_available_state_transitions())
156162

157-
self.assertIn("publish", transitions)
158-
self.assertNotIn("xyz", transitions)
163+
assert "publish" in transitions
164+
assert "xyz" not in transitions
159165

160166
# inline method for faking the name of the transition
161167
def publish():
@@ -171,13 +177,13 @@ def publish():
171177
custom="",
172178
)
173179

174-
self.assertTrue(obj in transitions)
180+
assert obj in transitions
175181

176182
def test_available_conditions_from_new(self):
177183
transitions = self.model.get_available_state_transitions()
178184
actual = {(transition.source, transition.target) for transition in transitions}
179185
expected = {("*", "moderated"), ("new", "published"), ("new", "removed"), ("*", ""), ("+", "blocked")}
180-
self.assertEqual(actual, expected)
186+
assert actual == expected
181187

182188
def test_available_conditions_from_published(self):
183189
self.model.publish()
@@ -191,37 +197,37 @@ def test_available_conditions_from_published(self):
191197
("*", ""),
192198
("+", "blocked"),
193199
}
194-
self.assertEqual(actual, expected)
200+
assert actual == expected
195201

196202
def test_available_conditions_from_hidden(self):
197203
self.model.publish()
198204
self.model.hide()
199205
transitions = self.model.get_available_state_transitions()
200206
actual = {(transition.source, transition.target) for transition in transitions}
201207
expected = {("*", "moderated"), ("hidden", "stolen"), ("*", ""), ("+", "blocked")}
202-
self.assertEqual(actual, expected)
208+
assert actual == expected
203209

204210
def test_available_conditions_from_stolen(self):
205211
self.model.publish()
206212
self.model.steal()
207213
transitions = self.model.get_available_state_transitions()
208214
actual = {(transition.source, transition.target) for transition in transitions}
209215
expected = {("*", "moderated"), ("*", ""), ("+", "blocked")}
210-
self.assertEqual(actual, expected)
216+
assert actual == expected
211217

212218
def test_available_conditions_from_blocked(self):
213219
self.model.block()
214220
transitions = self.model.get_available_state_transitions()
215221
actual = {(transition.source, transition.target) for transition in transitions}
216222
expected = {("*", "moderated"), ("*", "")}
217-
self.assertEqual(actual, expected)
223+
assert actual == expected
218224

219225
def test_available_conditions_from_empty(self):
220226
self.model.empty()
221227
transitions = self.model.get_available_state_transitions()
222228
actual = {(transition.source, transition.target) for transition in transitions}
223229
expected = {("*", "moderated"), ("*", ""), ("+", "blocked")}
224-
self.assertEqual(actual, expected)
230+
assert actual == expected
225231

226232
def test_all_conditions(self):
227233
transitions = self.model.get_all_state_transitions()
@@ -238,4 +244,4 @@ def test_all_conditions(self):
238244
("*", ""),
239245
("+", "blocked"),
240246
}
241-
self.assertEqual(actual, expected)
247+
assert actual == expected

tests/testapp/tests/test_conditions.py

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
from __future__ import annotations
22

3+
import pytest
34
from django.db import models
45
from django.test import TestCase
56

@@ -36,17 +37,18 @@ def setUp(self):
3637
self.model = BlogPostWithConditions()
3738

3839
def test_initial_staet(self):
39-
self.assertEqual(self.model.state, "new")
40+
assert self.model.state == "new"
4041

4142
def test_known_transition_should_succeed(self):
42-
self.assertTrue(can_proceed(self.model.publish))
43+
assert can_proceed(self.model.publish)
4344
self.model.publish()
44-
self.assertEqual(self.model.state, "published")
45+
assert self.model.state == "published"
4546

4647
def test_unmet_condition(self):
4748
self.model.publish()
48-
self.assertEqual(self.model.state, "published")
49-
self.assertFalse(can_proceed(self.model.destroy))
50-
self.assertRaises(TransitionNotAllowed, self.model.destroy)
49+
assert self.model.state == "published"
50+
assert not can_proceed(self.model.destroy)
51+
with pytest.raises(TransitionNotAllowed):
52+
self.model.destroy()
5153

52-
self.assertTrue(can_proceed(self.model.destroy, check_conditions=False))
54+
assert can_proceed(self.model.destroy, check_conditions=False)

tests/testapp/tests/test_custom_data.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@ def setUp(self):
3131
self.model = BlogPostWithCustomData()
3232

3333
def test_initial_state(self):
34-
self.assertEqual(self.model.state, "new")
34+
assert self.model.state == "new"
3535
transitions = list(self.model.get_available_state_transitions())
36-
self.assertEqual(len(transitions), 1)
37-
self.assertEqual(transitions[0].target, "published")
38-
self.assertDictEqual(transitions[0].custom, {"label": "Publish", "type": "*"})
36+
assert len(transitions) == 1
37+
assert transitions[0].target == "published"
38+
assert transitions[0].custom == {"label": "Publish", "type": "*"}
3939

4040
def test_all_transitions_have_custom_data(self):
4141
transitions = self.model.get_all_state_transitions()
4242
for t in transitions:
43-
self.assertIsNotNone(t.custom["label"])
44-
self.assertIsNotNone(t.custom["type"])
43+
assert t.custom["label"] is not None
44+
assert t.custom["type"] is not None

0 commit comments

Comments
 (0)