Closed ericoporto closed 5 months ago
Note that ags4 test game needs to be recompiled with the editor from latest ags4 branch, in order to fix the object pointers.
Note that ags4 test game needs to be recompiled
Yes, the tests in the CI will fail until a new ags4 version is released I guess, but the attached game in this PR contains tests specifically for the String Split things.
It looks like I am hitting an off by one error in some cases of the String Split but I can't figure it out why/where in the code is wrong yet... Edit: figured, but also a few tests were incorrect.
Managed to find the issue and fix. I also had errors in the previous tests, so I redid those. It seems it's working now, please test!
I think I can squash all Engine
commits now to a single commit too.
In regards to automatic tests, my strong suggestion is to test ALL the elements of the resulting array. Indeed that's more code, but that will ensure that resulting items are valid and no edge case was missed.
This may be done, for example, by a helper function that accepts a resulting array returned from Split, and a manually prepared array; then compares these array lengths and contents element by element.
I added a new auto-test game that now tests all elements and the test passes! :)
Looks like empty arrays also work:
String s = ",";
String r[] = s.Split(",", eStrSplit_RemoveEmpty);
Display("r = %p", r); // prints valid address
Display("r.Length = %d", r.Length); // prints 0
Uhm, probably something else to add for testing! So it can't be done directly through scripting but the machinery in the engine is correct.
After this makes in an ags4 release I can add this to the auto test game.
fix #2458
This is an autotest game (fixed again!) ags4-auto-test-string-split.zip
It adds the following ported from the C# example in the issue (redone!)
``` // String.Split // String.Split { { String s = ",ONE,, TWO,, , THREE,,"; String result[] = s.Split(",", eStrSplit_None); tap.is_int(result.Length, 9, "String.Split: (1,length) by character delimiter without options"); tap.is(result[0], "", "String.Split: (1,element check 0) by character delimiter without options"); tap.is(result[1], "ONE", "String.Split: (1,element check 1) by character delimiter without options"); tap.is(result[2], "", "String.Split: (1,element check 2) by character delimiter without options"); tap.is(result[3], " TWO", "String.Split: (1,element check 3) by character delimiter without options"); tap.is(result[4], "", "String.Split: (1,element check 4) by character delimiter without options"); tap.is(result[5], " ", "String.Split: (1,element check 5) by character delimiter without options"); tap.is(result[6], " THREE", "String.Split: (1,element check 6) by character delimiter without options"); tap.is(result[7], "", "String.Split: (1,element check 7) by character delimiter without options"); tap.is(result[8], "", "String.Split: (1,element check 8) by character delimiter without options"); } { String s = ",ONE,, TWO,, , THREE,,"; String result[] = s.Split(",", eStrSplit_Trim); tap.is_int(result.Length, 9, "String.Split: (2,length) by character delimiter with Trim option"); tap.is(result[0], "", "String.Split: (2,element check 0) by character delimiter with Trim option"); tap.is(result[1], "ONE", "String.Split: (2,element check 1) by character delimiter with Trim option"); tap.is(result[2], "", "String.Split: (2,element check 2) by character delimiter with Trim option"); tap.is(result[3], "TWO", "String.Split: (2,element check 3) by character delimiter with Trim option"); tap.is(result[4], "", "String.Split: (2,element check 4) by character delimiter with Trim option"); tap.is(result[5], "", "String.Split: (2,element check 5) by character delimiter with Trim option"); tap.is(result[6], "THREE", "String.Split: (2,element check 6) by character delimiter with Trim option"); tap.is(result[7], "", "String.Split: (2,element check 7) by character delimiter with Trim option"); tap.is(result[8], "", "String.Split: (2,element check 8) by character delimiter with Trim option"); } { String s = ",ONE,, TWO,, , THREE,,"; String result[] = s.Split(",", eStrSplit_RemoveEmpty); tap.is_int(result.Length, 4, "String.Split: (3,length) by character delimiter with RemoveEmpty option"); tap.is(result[0], "ONE", "String.Split: (3,element check 0) by character delimiter with RemoveEmpty option"); tap.is(result[1], " TWO", "String.Split: (3,element check 1) by character delimiter with RemoveEmpty option"); tap.is(result[2], " ", "String.Split: (3,element check 2) by character delimiter with RemoveEmpty option"); tap.is(result[3], " THREE", "String.Split: (3,element check 3) by character delimiter with RemoveEmpty option"); } { String s = ",ONE,, TWO,, , THREE ,,"; String result[] = s.Split(",", eStrSplit_Trim | eStrSplit_RemoveEmpty); tap.is_int(result.Length, 3, "String.Split: (4,length) by character delimiter with Trim and RemoveEmpty options"); tap.is(result[0], "ONE", "String.Split: (4,element check 0) by character delimiter with Trim and RemoveEmpty options"); tap.is(result[1], "TWO", "String.Split: (4,element check 1) by character delimiter with Trim and RemoveEmpty options"); tap.is(result[2], "THREE", "String.Split: (4,element check 2) by character delimiter with Trim and RemoveEmpty options"); } { String s = "[stop]ONE[stop] [stop]TWO [stop][stop] [stop]THREE[stop][stop] "; String result[] = s.Split("[stop]", eStrSplit_None); tap.is_int(result.Length, 9, "String.Split: (5,length) by string delimiter without options"); tap.is(result[0], "", "String.Split: (5,element check 0) by string delimiter without options"); tap.is(result[1], "ONE", "String.Split: (5,element check 1) by string delimiter without options"); tap.is(result[2], " ", "String.Split: (5,element check 2) by string delimiter without options"); tap.is(result[3], "TWO ", "String.Split: (5,element check 3) by string delimiter without options"); tap.is(result[4], "", "String.Split: (5,element check 4) by string delimiter without options"); tap.is(result[5], " ", "String.Split: (5,element check 5) by string delimiter without options"); tap.is(result[6], "THREE", "String.Split: (5,element check 6) by string delimiter without options"); tap.is(result[7], "", "String.Split: (5,element check 7) by string delimiter without options"); tap.is(result[8], " ", "String.Split: (5,element check 8) by string delimiter without options"); } { String s = "[stop]ONE[stop] [stop]TWO [stop][stop] [stop]THREE[stop][stop] "; String result[] = s.Split("[stop]", eStrSplit_Trim); tap.is_int(result.Length, 9, "String.Split: (6,length) by string delimiter with Trim option"); tap.is(result[0], "", "String.Split: (6,element check 0) by string delimiter with Trim option"); tap.is(result[1], "ONE", "String.Split: (6,element check 1) by string delimiter with Trim option"); tap.is(result[2], "", "String.Split: (6,element check 2) by string delimiter with Trim option"); tap.is(result[3], "TWO", "String.Split: (6,element check 3) by string delimiter with Trim option"); tap.is(result[4], "", "String.Split: (6,element check 4) by string delimiter with Trim option"); tap.is(result[5], "", "String.Split: (6,element check 5) by string delimiter with Trim option"); tap.is(result[6], "THREE", "String.Split: (6,element check 6) by string delimiter with Trim option"); tap.is(result[7], "", "String.Split: (6,element check 7) by string delimiter with Trim option"); tap.is(result[8], "", "String.Split: (6,element check 8) by string delimiter with Trim option"); } { String s = "[stop]ONE[stop] [stop]TWO [stop][stop] [stop]THREE[stop][stop] "; String result[] = s.Split("[stop]", eStrSplit_RemoveEmpty); tap.is_int(result.Length, 6, "String.Split: (7,length) by string delimiter with RemoveEmpty option"); tap.is(result[0], "ONE", "String.Split: (7,element check 0) by string delimiter with RemoveEmpty option"); tap.is(result[1], " ", "String.Split: (7,element check 1) by string delimiter with RemoveEmpty option"); tap.is(result[2], "TWO ", "String.Split: (7,element check 2) by string delimiter with RemoveEmpty option"); tap.is(result[3], " ", "String.Split: (7,element check 3) by string delimiter with RemoveEmpty option"); tap.is(result[4], "THREE", "String.Split: (7,element check 4) by string delimiter with RemoveEmpty option"); tap.is(result[5], " ", "String.Split: (7,element check 5) by string delimiter with RemoveEmpty option"); } { String s = "[stop]ONE[stop] [stop]TWO [stop][stop] [stop]THREE[stop][stop] "; String result[] = s.Split("[stop]", eStrSplit_Trim | eStrSplit_RemoveEmpty); tap.is_int(result.Length, 3, "String.Split: (8,length) by string delimiter with Trim and RemoveEmpty options"); tap.is(result[0], "ONE", "String.Split: (8,element check 0) by string delimiter with Trim and RemoveEmpty options"); tap.is(result[1], "TWO", "String.Split: (8,element check 1) by string delimiter with Trim and RemoveEmpty options"); tap.is(result[2], "THREE", "String.Split: (8,element check 2) by string delimiter with Trim and RemoveEmpty options"); } } ```Tests are passing now