@@ -18,6 +18,7 @@ along with LiveCode. If not see <http://www.gnu.org/licenses/>. */
1818module com.livecode.sort.tests
1919
2020use com.livecode.sort
21+ use com.livecode.__INTERNAL._testlib
2122
2223----------------------------------------------------------------
2324-- Utilities
@@ -68,6 +69,28 @@ handler RandomStringList() returns List
6869 return tList
6970end handler
7071
72+ -- Create a list containing 100 random strings of 1-10 characters, or numbers from 1 to 100
73+ handler RandomMixedList() returns List
74+ variable tStringList as List
75+ variable tNumericList as List
76+ put RandomStringList() into tStringList
77+ put RandomNumericList() into tNumericList
78+
79+ variable tList
80+ put [] into tList
81+
82+ variable tCount
83+ repeat with tCount from 1 up to 100
84+ if any number > 0.5 then
85+ push tStringList[tCount] onto tList
86+ else
87+ push tNumericList[tCount] onto tList
88+ end if
89+ end repeat
90+
91+ return tList
92+ end handler
93+
7194handler IsSorted(in pList as List, in pDescending as Boolean) returns Boolean
7295 if pList is empty then
7396 return true
@@ -90,6 +113,80 @@ handler IsSorted(in pList as List, in pDescending as Boolean) returns Boolean
90113 return tSorted
91114end handler
92115
116+ handler CompareNumericAscending(in pLeft as any, in pRight as any) returns Integer
117+ return CompareNumeric(pLeft, pRight, false)
118+ end handler
119+
120+ handler CompareNumericDescending(in pLeft as any, in pRight as any) returns Integer
121+ return CompareNumeric(pLeft, pRight, true)
122+ end handler
123+
124+ -- Sorts numerically, converting strings to numbers where possible
125+ handler CompareNumeric(in pLeft as any, in pRight as any, in pDescending as Boolean) returns Integer
126+ variable tLeft as optional Number
127+ variable tRight as optional Number
128+
129+ if pLeft is a number then
130+ put pLeft into tLeft
131+ else
132+ put pLeft parsed as number into tLeft
133+ end if
134+
135+ if pRight is a number then
136+ put pRight into tRight
137+ else
138+ put pRight parsed as number into tRight
139+ end if
140+
141+ if tRight is tLeft then
142+ return 0
143+ end if
144+
145+ if tRight is nothing then
146+ return -1
147+ end if
148+
149+ if tLeft is nothing then
150+ return 1
151+ end if
152+
153+ if tLeft < tRight then
154+ if pDescending then
155+ return 1
156+ else
157+ return -1
158+ end if
159+ end if
160+
161+ if pDescending then
162+ return -1
163+ else
164+ return 1
165+ end if
166+ end handler
167+
168+ handler IsSortedUsingHandler(in pList as List, in pHandler as SortCompare) returns Boolean
169+ if pList is empty then
170+ return true
171+ end if
172+
173+ variable tLast
174+ pop front of pList into tLast
175+
176+ variable tSorted
177+ put true into tSorted
178+
179+ variable tIter
180+ repeat for each element tIter in pList
181+ if pHandler(tLast, tIter) > 0 then
182+ put false into tSorted
183+ exit repeat
184+ end if
185+ put tIter into tLast
186+ end repeat
187+ return tSorted
188+ end handler
189+
93190----------------------------------------------------------------
94191-- Tests
95192----------------------------------------------------------------
@@ -202,4 +299,86 @@ public handler TestDescendingText() -- RANDOMIZED
202299 test "sort descending text is stable" when tList is tStable
203300end handler
204301
302+ public handler TestAscendingNumericMixed() -- RANDOMIZED
303+ variable tRandom
304+ repeat forever
305+ put RandomMixedList() into tRandom
306+ if not IsSortedUsingHandler(tRandom, CompareNumericAscending) then
307+ exit repeat
308+ end if
309+ end repeat
310+
311+ variable tList
312+
313+ -- Test sorting
314+ put tRandom into tList
315+ sort tList using handler CompareNumericAscending
316+ test "sort using handler ascending numeric" when IsSortedUsingHandler(tList, CompareNumericAscending)
317+
318+ -- Test sorting stability
319+ variable tStable
320+ put tList into tStable
321+ sort tList using handler CompareNumericAscending
322+ test "sort using handler ascending numeric is stable" when tList is tStable
323+ end handler
324+
325+ public handler TestDescendingNumericMixed() -- RANDOMIZED
326+ variable tRandom
327+ repeat forever
328+ put RandomMixedList() into tRandom
329+ if not IsSortedUsingHandler(tRandom, CompareNumericDescending) then
330+ exit repeat
331+ end if
332+ end repeat
333+
334+ variable tList
335+
336+ -- Test sorting
337+ put tRandom into tList
338+ sort tList using handler CompareNumericDescending
339+ test "sort using handler descending numeric" when IsSortedUsingHandler(tList, CompareNumericDescending)
340+
341+ -- Test sorting stability
342+ variable tStable
343+ put tList into tStable
344+ sort tList using handler CompareNumericDescending
345+ test "sort using handler descending numeric is stable" when tList is tStable
346+ end handler
347+
348+ handler InvalidSortHandler_Args(in pValue as any) returns Integer
349+ return 1
350+ end handler
351+
352+ handler InvalidSortHandler_ReturnType(in pLeft as any, in pRight as any) returns String
353+ return ""
354+ end handler
355+
356+ handler InvalidSortHandler_MissingReturn(in pLeft as any, in pRight as any) returns Integer
357+
358+ end handler
359+
360+ handler TestSortUsingHandler_InvalidArgs()
361+ variable tList as List
362+ put [1,2,3,4] into tList
363+ sort tList using handler InvalidSortHandler_Args
364+ end handler
365+
366+ handler TestSortUsingHandler_InvalidReturnType()
367+ variable tList as List
368+ put [1,2,3,4] into tList
369+ sort tList using handler InvalidSortHandler_ReturnType
370+ end handler
371+
372+ handler TestSortUsingHandler_MissingReturn()
373+ variable tList as List
374+ put [1,2,3,4] into tList
375+ sort tList using handler InvalidSortHandler_MissingReturn
376+ end handler
377+
378+ public handler TestUsingHandlerErrors()
379+ MCUnitTestHandlerThrows(TestSortUsingHandler_InvalidArgs, "handler invalid number of args")
380+ MCUnitTestHandlerThrows(TestSortUsingHandler_InvalidReturnType, "handler invalid return type")
381+ MCUnitTestHandlerThrows(TestSortUsingHandler_MissingReturn, "handler missing return")
382+ end handler
383+
205384end module
0 commit comments