Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 26 additions & 1 deletion shotgun_api3/lib/mockgun/mockgun.py
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,27 @@ def find(
# handle the ordering of the recordset
if order:
# order: [{"field_name": "code", "direction": "asc"}, ... ]

def sort_none(k, order_field):
"""
Handle sorting of None consistently.

Note: Doesn't handle [checkbox, serializable, url].
"""
field_type = self._get_field_type(k["type"], order_field)
value = k[order_field]
if value is not None:
return value
elif field_type in ("number", "percent", "duration"):
return 0
elif field_type == "float":
return 0.0
elif field_type in ("text", "entity_type", "date", "list", "status_list"):
return ""
elif field_type == "date_time":
return datetime.datetime(datetime.MINYEAR, 1, 1)
return None

for order_entry in order:
if "field_name" not in order_entry:
raise ValueError("Order clauses must be list of dicts with keys 'field_name' and 'direction'!")
Expand All @@ -305,7 +326,11 @@ def find(
else:
raise ValueError("Unknown ordering direction")

results = sorted(results, key=lambda k: k[order_field], reverse=desc_order)
results = sorted(
results,
key=lambda k: sort_none(k, order_field),
reverse=desc_order,
)

if fields is None:
fields = set(["type", "id"])
Expand Down
64 changes: 61 additions & 3 deletions tests/test_mockgun.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
and can be run on their own by typing "python test_mockgun.py".
"""

import datetime
import re
import os
import unittest
Expand Down Expand Up @@ -402,26 +403,39 @@ def setUp(self):
"Shot",
{
"code": "shot1",
"project": self._prj1_link
"project": self._prj1_link,
"description": "a",
"sg_cut_order": 2
}
)

self._shot2 = self._mockgun.create(
"Shot",
{
"code": "shot2",
"project": self._prj1_link
"project": self._prj1_link,
"sg_cut_order": 1
}
)

self._shot3 = self._mockgun.create(
"Shot",
{
"code": "shot3",
"project": self._prj2_link
"project": self._prj2_link,
"description": "b"
}
)

self._user1 = self._mockgun.create(
"HumanUser", {"login": "user1", "password_strength": 0.2}
)

self._user2 = self._mockgun.create(
"HumanUser",
{"login": "user2", "created_at": datetime.datetime(2025, 1, 1)}
)

def test_simple_filter_operators(self):
"""
Tests a simple use of the filter_operator.
Expand Down Expand Up @@ -452,6 +466,50 @@ def test_simple_filter_operators(self):

self.assertEqual(len(shots), 0)

def test_ordered_filter_operator(self):
"""
Test use of the order feature of filter_operator on supported data types.
"""
find_args = ["Shot", [], ["code"]]

# str field
shots = self._mockgun.find(
*find_args,
order=[{"field_name": "description", "direction": "asc"}]
)
self.assertEqual([s["code"] for s in shots], ["shot2", "shot1", "shot3"])

shots = self._mockgun.find(
*find_args,
order=[{"field_name": "description", "direction": "desc"}]
)
self.assertEqual([s["code"] for s in shots], ["shot3", "shot1", "shot2"])

# int field
shots = self._mockgun.find(
*find_args,
order=[{"field_name": "sg_cut_order", "direction": "asc"}]
)
self.assertEqual([s["code"] for s in shots], ["shot3", "shot2", "shot1"])

# float field
users = self._mockgun.find(
"HumanUser",
[],
["login"],
order=[{"field_name": "password_strength", "direction": "asc"}]
)
self.assertEqual([u["login"] for u in users], ["user2", "user1"])

# date_time field
users = self._mockgun.find(
"HumanUser",
[],
["login"],
order=[{"field_name": "created_at", "direction": "asc"}]
)
self.assertEqual([u["login"] for u in users], ["user1", "user2"])

def test_nested_filter_operators(self):
"""
Tests a the use of the filter_operator nested
Expand Down
Loading