Index: tests/natools-string_slice_set_tests.adb ================================================================== --- tests/natools-string_slice_set_tests.adb +++ tests/natools-string_slice_set_tests.adb @@ -33,11 +33,10 @@ (Report : in out NT.Reporter'Class; Name : in String; Reported : in out Boolean; Info : in String); -- Report failure if not already reported, and append Info - pragma Unreferenced (Info_Fail); procedure Dump (Report : in out NT.Reporter'Class; Set : in Slice_Sets.Slice_Set); -- Dump the given slice set in Report.Info @@ -102,19 +101,281 @@ -- Test collections -- ---------------------- procedure All_Tests (Report : in out NT.Reporter'Class) is begin + Test_Conversions (Report); + Test_Interval_Arithmetic (Report); Test_Navigation (Report); Test_Tokenization (Report); end All_Tests; ---------------------- -- Individual tests -- ---------------------- + + procedure Test_Conversions (Report : in out NT.Reporter'Class) is + Name : constant String + := "Conversions between slices, slice sets and strings"; + Reported : Boolean := False; + begin + declare + use type String_Slices.Slice; + use type Slice_Sets.Slice_Set; + + Parent_Slice : constant String_Slices.Slice + := String_Slices.To_Slice (Parent_String); + Range_1 : constant String_Slices.String_Range + := (Parent_String'First, 10); + Range_2 : constant String_Slices.String_Range + := (Parent_String'Last - 9, 10); + Range_3 : constant String_Slices.String_Range + := String_Slices.To_Range + (Parent_String'First + 6, Parent_String'Last - 7); + Set : Slice_Sets.Slice_Set; + begin + if not Set.Is_Valid then + Info_Fail (Report, Name, Reported, "Default set is invalid"); + Dump (Report, Set); + end if; + + if not Set.Is_Null then + Info_Fail (Report, Name, Reported, "Default set is not null"); + Dump (Report, Set); + end if; + + if not Set.Is_Empty then + Info_Fail (Report, Name, Reported, "Null set is not empty"); + Dump (Report, Set); + end if; + + if Slice_Sets.To_Slice_Set (String_Slices.Null_Slice) /= Set then + Info_Fail (Report, Name, Reported, + "To_Slice_Set (Null_Slice) /= Null_Set"); + end if; + + if Set.To_Slice /= String_Slices.Null_Slice then + Info_Fail (Report, Name, Reported, + "To_Slice (Null_Set) /= Null_Slice"); + end if; + + if Set.To_String /= "" then + Info_Fail (Report, Name, Reported, "To_String (Null_Set) /= """""); + end if; + + Set := Slice_Sets.To_Slice_Set (Parent_Slice); + Set.Clear; + + if Set.Is_Null then + Info_Fail (Report, Name, Reported, "Cleared set is null"); + end if; + + if not Set.Is_Empty then + Info_Fail (Report, Name, Reported, "Cleared set is not empty"); + Dump (Report, Set); + end if; + + if Set.To_String /= "" then + Info_Fail (Report, Name, Reported, + "To_String (Empty_Set) /= """""); + end if; + + if not String_Slices.Is_Subslice (Set.To_Slice, Parent_Slice) then + Info_Fail (Report, Name, Reported, + "To_Slice (Empty_Set) is not a subslice of parent."); + end if; + + Set.Add_Slice (Range_1); + + if not Set.Is_Valid then + Info_Fail (Report, Name, Reported, "Invalid slice singleton"); + Dump (Report, Set); + end if; + + if Set.Is_Null then + Info_Fail (Report, Name, Reported, "Slice singleton is null"); + end if; + + if Set.Is_Empty then + Info_Fail (Report, Name, Reported, "Slice singleton is empty"); + end if; + + if Set.To_String + /= Parent_String (Range_1.First .. String_Slices.Last (Range_1)) + then + Info_Fail (Report, Name, Reported, + "Found """ & Set.To_String & '"'); + Info_Fail (Report, Name, Reported, "Expected """ + & Parent_String (Range_1.First .. String_Slices.Last (Range_1)) + & '"'); + Dump (Report, Set); + end if; + + if not String_Slices.Is_Subslice (Set.To_Slice, Parent_Slice) then + Info_Fail (Report, Name, Reported, + "To_Slice (Singleton) is not a subslice of parent."); + end if; + + Set.Add_Slice (Range_2); + + if not Set.Is_Valid then + Info_Fail (Report, Name, Reported, "Invalid normal set"); + Dump (Report, Set); + end if; + + if Set.Is_Null then + Info_Fail (Report, Name, Reported, "Normal set is null"); + end if; + + if Set.Is_Empty then + Info_Fail (Report, Name, Reported, "Normal set is empty"); + end if; + + if Set.To_String + /= Parent_String (Range_1.First .. String_Slices.Last (Range_1)) + & Parent_String (Range_2.First .. String_Slices.Last (Range_2)) + then + Info_Fail (Report, Name, Reported, + "Found """ & Set.To_String & '"'); + Info_Fail (Report, Name, Reported, "Expected """ + & Parent_String (Range_1.First .. String_Slices.Last (Range_1)) + & Parent_String (Range_2.First .. String_Slices.Last (Range_2)) + & '"'); + Dump (Report, Set); + end if; + + if String_Slices.Is_Related (Set.To_Slice, Parent_Slice) then + Info_Fail (Report, Name, Reported, + "To_Slice (Complex_Set) related to parent slice"); + Dump (Report, Set); + end if; + + if Set.To_String (Range_3) + /= Parent_String (Range_3.First .. String_Slices.Last (Range_1)) + & Parent_String (Range_2.First .. String_Slices.Last (Range_3)) + then + Info_Fail (Report, Name, Reported, + "Found """ & Set.To_String (Range_3) & '"'); + Info_Fail (Report, Name, Reported, "Expected """ + & Parent_String (Range_3.First .. String_Slices.Last (Range_1)) + & Parent_String (Range_2.First .. String_Slices.Last (Range_3)) + & '"'); + Dump (Report, Set); + end if; + + if Set.To_String (Range_3.First, String_Slices.Last (Range_3)) + /= Parent_String (Range_3.First .. String_Slices.Last (Range_1)) + & Parent_String (Range_2.First .. String_Slices.Last (Range_3)) + then + Info_Fail (Report, Name, Reported, "Found """ + & Set.To_String (Range_3.First, String_Slices.Last (Range_3)) + & '"'); + Info_Fail (Report, Name, Reported, "Expected """ + & Parent_String (Range_3.First .. String_Slices.Last (Range_1)) + & Parent_String (Range_2.First .. String_Slices.Last (Range_3)) + & '"'); + Dump (Report, Set); + end if; + end; + + if not Reported then + Report.Item (Name, NT.Success); + end if; + exception + when Error : others => Report.Report_Exception (Name, Error); + end Test_Conversions; + + procedure Test_Interval_Arithmetic (Report : in out NT.Reporter'Class) is + Name : constant String := "Interval arithmetic"; + Reported : Boolean := False; + + procedure Check_Set + (Parent : in String; + Slices : in Slice_Sets.Slice_Set; + Contents : in Ada.Strings.Maps.Character_Set); + -- Check that slice inclusion is equivalent to character set + + procedure Check_Set + (Parent : in String; + Slices : in Slice_Sets.Slice_Set; + Contents : in Ada.Strings.Maps.Character_Set) + is + Failure : Natural := 0; + begin + for I in Parent'Range loop + if Ada.Strings.Maps.Is_In (Parent (I), Contents) + /= Slices.Is_In (I) + then + Failure := I; + exit; + end if; + end loop; + + if Failure > 0 then + if not Reported then + Report.Item (Name, NT.Fail); + Reported := True; + end if; + + Report.Info ("Expected set: " + & Ada.Strings.Maps.To_Sequence (Contents)); + Dump (Report, Slices); + end if; + end Check_Set; + begin + declare + Parent : constant String (11 .. 36) + := "ABCDEFabc1234567890zyxWXYZ"; + -- 123456789.123456789.123456 + Set : Slice_Sets.Slice_Set := Slice_Sets.To_Slice_Set (Parent); + begin + Set.Clear; + Check_Set (Parent, Set, Ada.Strings.Maps.Null_Set); + + Set.Include_Slice (20, 29); + Check_Set (Parent, Set, Ada.Strings.Maps.To_Set ("0123456789")); + + Set.Include_Slice (20, 25); + Check_Set (Parent, Set, Ada.Strings.Maps.To_Set ("0123456789")); + + Set.Include_Slice (11, 16); + Check_Set (Parent, Set, Ada.Strings.Maps.To_Set ("0123456789ABCDEF")); + + Set.Include_Slice (14, 32); + Check_Set (Parent, Set, + Ada.Strings.Maps.To_Set ("0123456789ABCDEFabczyx")); + + Set.Include_Slice (33, 36); + Check_Set (Parent, Set, Ada.Strings.Maps.To_Set (Parent)); + + Set.Exclude_Slice (20, 29); + Check_Set (Parent, Set, Ada.Strings.Maps.To_Set ("ABCDEFabczyxWXYZ")); + + Set.Include_Slice (27, 34); + Check_Set (Parent, Set, + Ada.Strings.Maps.To_Set ("ABCDEFabc890zyxWXYZ")); + + Set.Exclude_Slice (14, 13); + Check_Set (Parent, Set, + Ada.Strings.Maps.To_Set ("ABCDEFabc890zyxWXYZ")); + + Set.Exclude_Slice (5, 23); + Check_Set (Parent, Set, Ada.Strings.Maps.To_Set ("890zyxWXYZ")); + + Set.Include_Slice (13, 12); + Check_Set (Parent, Set, Ada.Strings.Maps.To_Set ("890zyxWXYZ")); + end; + + if not Reported then + Report.Item (Name, NT.Success); + end if; + exception + when Error : others => Report.Report_Exception (Name, Error); + end Test_Interval_Arithmetic; + procedure Test_Navigation (Report : in out NT.Reporter'Class) is Name : constant String := "External index navigation"; begin declare Index: tests/natools-string_slice_set_tests.ads ================================================================== --- tests/natools-string_slice_set_tests.ads +++ tests/natools-string_slice_set_tests.ads @@ -26,9 +26,11 @@ package NT renames Natools.Tests; procedure All_Tests (Report : in out NT.Reporter'Class); + procedure Test_Conversions (Report : in out NT.Reporter'Class); + procedure Test_Interval_Arithmetic (Report : in out NT.Reporter'Class); procedure Test_Navigation (Report : in out NT.Reporter'Class); procedure Test_Tokenization (Report : in out NT.Reporter'Class); end Natools.String_Slice_Set_Tests;