--
--  Copyright (C) 2024, AdaCore
--  SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
--

with Ada.Strings.Unbounded;    use Ada.Strings.Unbounded;
with Ada.Text_IO;              use Ada.Text_IO;
with Ada.Text_IO.Unbounded_IO; use Ada.Text_IO.Unbounded_IO;

with GNATCOLL.Traces;

with Prettier_Ada.Documents;          use Prettier_Ada.Documents;
with Prettier_Ada.Documents.Builders; use Prettier_Ada.Documents.Builders;
with Prettier_Ada.Documents.Json;     use Prettier_Ada.Documents.Json;

--  Test program to build a Document_Type using the
--  Prettier_Ada.Documents.Builders package, serialize it into JSON and formats
--  it.

procedure Builders_Tester is

   procedure Test_Align;
   --  Builds a Document_Type using the Align builder

   procedure Test_Alignment_Table;
   --  Builds multiple Document_Type objects using the Alignment_Table builder

   procedure Test_Alignment_Table_Separator;
   --  Builds multiple Document_Type objects using the
   --  Alignment_Table_Separator builder

   procedure Test_Break_Parent;
   --  Builds a Document_Type using the Break_Parent builder

   procedure Test_Continuation_Line_Indent;
   --  Builds a Document_Type using the Continuation_Line_Indent builder

   procedure Test_Cursor;
   --  Builds a Document_Type using the Cursor builder

   procedure Test_Fill;
   --  Builds a Document_Type using the Fill builder

   procedure Test_Group;
   --  Builds a Document_Type using the Group builder

   procedure Test_Conditional_Group;
   --  Builds a Document_Type using the Conditional_Group builder

   procedure Test_Hard_Line;
   --  Builds a Document_Type using the Hard_Line builder

   procedure Test_Hard_Line_Without_Break_Parent;
   --  Builds a Document_Type using the Hard_Line_Without_Break_Parent builder

   procedure Test_If_Break;
   --  Builds a Document_Type using the If_Break builder

   procedure Test_Indent;
   --  Builds a Document_Type using the Indent builder

   procedure Test_Indent_If_Break;
   --  Builds a Document_Type using the Indent_If_Break builder

   procedure Test_Join;
   --  Builds a Document_Type using the Join builder

   procedure Test_Label;
   --  Builds a Document_Type using the Label builder

   procedure Test_Line_Suffix;
   --  Builds a Document_Type using the Line_Suffix builder

   procedure Test_Line_Suffix_Boundary;
   --  Builds a Document_Type using the Line_Suffix_Boundary builder

   procedure Test_List;
   --  Builds a Document_Type using the List builder

   procedure Test_Literal_Line;
   --  Builds a Document_Type using the Literal_Line builder

   procedure Test_Literal_Line_Without_Break_Parent;
   --  Builds a Document_Type using the
   --  Literal_Line_Without_Break_Parent builder.

   procedure Test_String_Literal;
   --  Builds a Document_Type using the String_Literal aspect

   procedure Test_Text;
   --  Builds a Document_Type using the Text builder

   procedure Test_Trim;
   --  Builds a Document_Type using the Trim builder

   -----------------
   --  Test_Align --
   -----------------

   procedure Test_Align is
      Document_1 : constant Document_Type :=
        Align ((Width, 2), Fill (List (["A", Line, "B"])));
      Document_2 : constant Document_Type :=
        Align ((Width, 2), Fill (["A", Line, "B"]));
      Document_3 : constant Document_Type :=
        Indent
          (List
             (["begin",
               Hard_Line,
               "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
               "(",
               Align
                 ((Kind => Inner_Root),
                  Fill
                    (["BBBBBBBBBBBBBBBBBBBB,",
                      Line,
                      "CCCCCCCCCCCCCCCCCCCC"])),
               ")"]));

   begin
      Put_Line ("=== Align ===");
      Put_Line ("> Align Document 1 JSON:");
      Put_Line (Serialize (Document_1));
      Put_Line ("> Align Document 1 Formatted:");
      Put_Line (Format (Document_1));
      Put_Line ("> Align Document 2 JSON:");
      Put_Line (Serialize (Document_2));
      Put_Line ("> Align Document 2 Formatted:");
      Put_Line (Format (Document_2));
      Put_Line ("> Align Document 3 JSON:");
      Put_Line (Serialize (Document_3));
      Put_Line ("> Align Document 3 Formatted:");
      Put_Line (Format (Document_3));
      Put_Line ("> Align Document 3 Formatted with Tabs:");
      Put_Line
        (Format
           (Document_3,
            (Width       => 79,
             Indentation =>
               (Kind         => Tabs,
                Width        => 3,
                Continuation => 2,
                Offset       => (Spaces => 0, Tabs => 0)),
             End_Of_Line => LF)));
      New_Line;
   end Test_Align;

   --------------------------
   -- Test_Alignment_Table --
   --------------------------

   procedure Test_Alignment_Table
   is
      function "+" (Source : String) return Document_Type
      is (Alignment_Table_Separator (To_Unbounded_String (Source)));
      --  Converts Source into a Table_Separator command

      function Build_Table return Document_Type;
      --  Creates a compex testing table

      ------------------
      --  Build_Table --
      ------------------

      function Build_Table return Document_Type
      is
         Group_1 : constant Symbol_Type := New_Symbol;
         Group_2 : constant Symbol_Type := New_Symbol;
         Group_3 : constant Symbol_Type := New_Symbol;
         Group_4 : constant Symbol_Type := New_Symbol;

         Table : constant Document_Type :=
           Alignment_Table
             ([[Hard_Line_Without_Break_Parent,
                -- This line break tests that trailing spaces before a table
                -- are removed
                "A ",
                +":",
                Group (Indent (List ([Line, "B "])), Group_1),
                +":=",
                If_Break
                  (Indent (Indent (Group ([Line, "C", ";"]))),
                   Indent (Group ([Line, "C", ";"])),
                   (Group_Id => Group_1))],
               ["AA ",
                +":",
                Group (Indent (List ([Line, "BB "])), Group_2),
                +":=",
                If_Break
                  (Indent (Indent (Group ([Line, "CC", ";"]))),
                   Indent (Group ([Line, "CC", ";"])),
                   (Group_Id => Group_2))],
               ["AAA ",
                +":",
                Group (Indent (List ([Line, "BBBBBBBBB;"])), Group_3)],
                --   BBBBBBBBB tests that it does not affect other separators
               ["AAAA ",
                +":",
                Group (Indent (List ([Line, "BBBB "])), Group_4),
                +":=",
                If_Break
                  (Indent (Indent (Group ([Line, "CCCC", ";"]))),
                   Indent (Group ([Line, "CCCC", ";"])),
                   (Group_Id => Group_4))]]);

         Table_Wrapper : constant Document_Type :=
           Group
             (["record",
               Indent
                 (List
                    ([Hard_Line_Without_Break_Parent,
                      Table])),
               Hard_Line_Without_Break_Parent,
               "end record"]);

      begin
         return Table_Wrapper;
      end Build_Table;

      Alignment_Table_1 : constant Document_Type := Build_Table;
      Alignment_Table_2 : constant Document_Type := Build_Table;
      Alignment_Table_3 : constant Document_Type :=
        Group
          (Alignment_Table
             (Rows =>
                [["with Prettier_Ada.Documents;",
                  List ([List ([+""])]),
                  Group ([Line, "use Prettier_Ada.Documents;"])],
                 ["with Prettier_Ada.Documents.Builders;",
                  List ([+""]),
                  Group ([Line, "use Prettier_Ada.Documents;"])]],
              Must_Break => True));

   begin
      Put_Line ("=== Alignment_Table ===");

      --  Test table alignment without line breaks

      Put_Line ("> Alignment_Table_1 Document JSON:");
      Put_Line (Serialize (Alignment_Table_1));
      Put_Line ("> Alignment_Table_1 Document Formatted:");
      Put_Line (Format (Alignment_Table_1));

      --  Test table alignment with all line breaks

      Put_Line ("> Alignment_Table_2 Document JSON:");
      Put_Line (Serialize (Alignment_Table_2));
      Put_Line ("> Alignment_Table_2 Document Formatted:");
      Put_Line
         (Format
            (Alignment_Table_2,
             (Width       => 1,
              Indentation =>
                (Kind         => Spaces,
                 Width        => 2,
                 Continuation => 2,
                 Offset       => (Spaces => 0, Tabs => 0)),
              End_Of_Line => LF)));

      --  Test that lists are flattened inside table rows

      Put_Line ("> Alignment_Table_3 Document JSON:");
      Put_Line (Serialize (Alignment_Table_3));
      Put_Line ("> Alignment_Table_3 Document Formatted:");
      Put_Line (Format (Alignment_Table_3));
      New_Line;
   end Test_Alignment_Table;

   ------------------------------------
   -- Test_Alignment_Table_Separator --
   ------------------------------------

   procedure Test_Alignment_Table_Separator
   is
      Document : constant Document_Type :=
        List
          (["A",
            " ",
            Alignment_Table_Separator (To_Unbounded_String (":")),
            " ",
            "B",
            " ",
            Alignment_Table_Separator (To_Unbounded_String (":=")),
            " ",
            "C",
            ";"]);

   begin
      Put_Line ("=== Alignment_Table_Separator ===");
      Put_Line ("> Alignment_Table_Separator Document JSON:");
      Put_Line (Serialize (Document));
      Put_Line ("> Alignment_Table_Separator Document Formatted:");
      Put_Line (Format (Document));
      New_Line;
   end Test_Alignment_Table_Separator;

   ------------------------
   --  Test_Break_Parent --
   ------------------------

   procedure Test_Break_Parent is
      Document : constant Document_Type :=
        Group (List (["A", Line, "B", Break_Parent]));

   begin
      Put_Line ("=== Break_Parent ===");
      Put_Line ("> Break_Parent Document JSON:");
      Put_Line (Serialize (Document));
      Put_Line ("> Break_Parent Document Formatted:");
      Put_Line (Format (Document));
      New_Line;
   end Test_Break_Parent;

   ------------------------------------
   --  Test_Continuation_Line_Indent --
   ------------------------------------

   procedure Test_Continuation_Line_Indent is
      Document : constant Document_Type :=
        Group
          ([Indent
              (List
                 (["begin",
                   Hard_Line,
                   Group
                     (Continuation_Line_Indent
                        (["Foobar", Line, "(Baz);"]))])),
            Hard_Line,
            "end"]);
   begin
      Put_Line ("=== Continuation_Line_Indent ===");
      Put_Line ("> Continuation_Line_Indent Document JSON:");
      Put_Line (Serialize (Document));
      Put_Line ("> Continuation_Line_Indent Document Formatted:");
      Put_Line
        (Format
           (Document,
            (Width       => 1,
             Indentation =>
               (Kind         => Spaces,
                Width        => 3,
                Continuation => 2,
                Offset       => (Spaces => 0, Tabs => 0)),
             End_Of_Line => LF)));
      New_Line;
   end Test_Continuation_Line_Indent;

   ------------------
   --  Test_Cursor --
   ------------------

   procedure Test_Cursor is
      Document : constant Document_Type :=
        Group (List (["A", Cursor, "B"]));

   begin
      Put_Line ("=== Cursor ===");
      Put_Line ("> Cursor Document JSON:");
      Put_Line (Serialize (Document));
      Put_Line ("> Cursor Document Formatted:");
      Put_Line (Format (Document));
      New_Line;
   end Test_Cursor;

   ----------------
   --  Test_Fill --
   ----------------

   procedure Test_Fill is
      --  Fill always expects a list of documents, even if there's just one
      --  document. Therefore, test that if it's constructed with a document
      --  that it's not a list, it implicitly wraps into one.
      Document_1 : constant Document_Type :=
        Fill (List (["AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"]));
      Document_2 : constant Document_Type :=
        Fill ("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA");
      Document_3 : constant Document_Type :=
        Fill
          (List
             (["AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
               Line,
               "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"]));
      Document_4 : constant Document_Type :=
        Fill
          (["AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
            Line,
            "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"]);

   begin
      Put_Line ("=== Fill ===");
      Put_Line ("> Fill Document 1 JSON:");
      Put_Line (Serialize (Document_1));
      Put_Line ("> Fill Document 1 Formatted:");
      Put_Line (Format (Document_1));
      Put_Line ("> Fill Document 2 JSON:");
      Put_Line (Serialize (Document_2));
      Put_Line ("> Fill Document 2 Formatted:");
      Put_Line (Format (Document_2));
      Put_Line ("> Fill Document 3 JSON:");
      Put_Line (Serialize (Document_3));
      Put_Line ("> Fill Document 3 Formatted:");
      Put_Line (Format (Document_3));
      Put_Line ("> Fill Document 4 JSON:");
      Put_Line (Serialize (Document_4));
      Put_Line ("> Fill Document 4 Formatted:");
      Put_Line (Format (Document_4));
      New_Line;
   end Test_Fill;

   -----------------
   --  Test_Group --
   -----------------

   procedure Test_Group is
      Document_1 : constant Document_Type :=
        Group
          (List
             (["AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
               Line,
               "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
               Line,
               "C"]));
      Document_2 : constant Document_Type :=
        Group
          (List
             (["AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
               Line,
               "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
               Line,
               "C"]),
           New_Symbol,
           True);
      Document_3 : constant Document_Type :=
        Group
          (["AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
            Line,
            "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
            Line,
            "C"]);
      Document_4 : constant Document_Type :=
        Group
          (["AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
            Line,
            "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
            Line,
            "C"],
           New_Symbol,
           True);

   begin
      Put_Line ("=== Group ===");
      Put_Line ("> Group Document 1 JSON:");
      Put_Line (Serialize (Document_1));
      Put_Line ("> Group Document 1 Formatted:");
      Put_Line (Format (Document_1));
      Put_Line ("> Group Document 2 JSON:");
      Put_Line (Serialize (Document_2));
      Put_Line ("> Group Document 2 Formatted:");
      Put_Line (Format (Document_2));
      Put_Line ("> Group Document 3 JSON:");
      Put_Line (Serialize (Document_3));
      Put_Line ("> Group Document 3 Formatted:");
      Put_Line (Format (Document_3));
      Put_Line ("> Group Document 4 JSON:");
      Put_Line (Serialize (Document_4));
      Put_Line ("> Group Document 4 Formatted:");
      Put_Line (Format (Document_4));
      New_Line;
   end Test_Group;

   -----------------------------
   --  Test_Conditional_Group --
   -----------------------------

   procedure Test_Conditional_Group is
      Document_1 : constant Document_Type :=
        Conditional_Group
          (["AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
            "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB"]);
      Document_2 : constant Document_Type :=
        Conditional_Group
          ([Text
              (To_Unbounded_String ("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA")
               & "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
               & "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
               & "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"
               & "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA"),
            List (["BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", Line, "CCCCC"])],
            New_Symbol,
            True);
      --  We expect the second alternative to be printed since the first one
      --  does not fit.

   begin
      Put_Line ("=== Conditional_Group ===");
      Put_Line ("> Conditional_Group Document 1 JSON:");
      Put_Line (Serialize (Document_1));
      Put_Line ("> Conditional_Group Document 1 Formatted:");
      Put_Line (Format (Document_1));
      Put_Line ("> Conditional_Group Document 2 JSON:");
      Put_Line (Serialize (Document_2));
      Put_Line ("> Conditional_Group Document 2 Formatted:");
      Put_Line (Format (Document_2));
      New_Line;
   end Test_Conditional_Group;

   ---------------------
   --  Test_Hard_Line --
   ---------------------

   procedure Test_Hard_Line is
      Document : constant Document_Type :=
        Indent (Group (List (["A", Hard_Line, "B", Line, "C"])));

   begin
      Put_Line ("=== Hard_Line ===");
      Put_Line ("> Hard_Line Document JSON:");
      Put_Line (Serialize (Document));
      Put_Line ("> Hard_Line Document Formatted:");
      Put_Line (Format (Document));
      New_Line;
   end Test_Hard_Line;

   ------------------------------------------
   --  Test_Hard_Line_Without_Break_Parent --
   ------------------------------------------

   procedure Test_Hard_Line_Without_Break_Parent is
      Document : constant Document_Type :=
        Group (List (["A", Hard_Line_Without_Break_Parent, "B", Line, "C"]));

   begin
      Put_Line ("=== Hard_Line_Without_Break_Parent ===");
      Put_Line ("> Hard_Line_Without_Break_Parent Document JSON:");
      Put_Line (Serialize (Document));
      Put_Line ("> Hard_Line_Without_Break_Parent Document Formatted:");
      Put_Line (Format (Document));
      New_Line;
   end Test_Hard_Line_Without_Break_Parent;

   --------------------
   --  Test_If_Break --
   --------------------

   procedure Test_If_Break is
      Document_1 : constant Document_Type :=
        Group
          (List
             (["AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
               Line,
               "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB",
               Line,
               If_Break ("C", "D")]));
      Document_2 : constant Document_Type :=
        Group
          (List
             (["AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA",
               Line,
               "BBBBBBBBBBBBBBBBBBBB",
               Line,
               If_Break ("C", "D")]));

   begin
      Put_Line ("=== If_Break ===");
      Put_Line ("> If_Break Document 1 JSON:");
      Put_Line (Serialize (Document_1));
      Put_Line ("> If_Break Document 1 Formatted:");
      Put_Line (Format (Document_1));
      Put_Line ("> If_Break Document 2 JSON:");
      Put_Line (Serialize (Document_2));
      Put_Line ("> If_Break Document 2 Formatted:");
      Put_Line (Format (Document_2));
      New_Line;
   end Test_If_Break;

   ---------------------
   --  Test_Indent --
   ---------------------

   procedure Test_Indent is
      Document : constant Document_Type :=
        Indent (List (["A", Line, "B", Line, "C"]));

   begin
      Put_Line ("=== Indent ===");
      Put_Line ("> Indent Document JSON:");
      Put_Line (Serialize (Document));
      Put_Line ("> Indent Document Formatted:");
      Put_Line (Format (Document));
      New_Line;
   end Test_Indent;

   ---------------------------
   --  Test_Indent_If_Break --
   ---------------------------

   procedure Test_Indent_If_Break is
      Document : constant Document_Type :=
        Indent_If_Break (Group (List (["A", Hard_Line, "B"])));

   begin
      Put_Line ("=== Indent_If_Break ===");
      Put_Line ("> Indent_If_Break Document JSON:");
      Put_Line (Serialize (Document));
      Put_Line ("> Indent_If_Break Document Formatted:");
      Put_Line (Format (Document));
      New_Line;
   end Test_Indent_If_Break;

   ---------------
   -- Test_Join --
   ---------------

   procedure Test_Join is
      Document : constant Document_Type := Join (Hard_Line, ["A", "B"]);

   begin
      Put_Line ("=== Join ===");
      Put_Line ("> Join Document JSON:");
      Put_Line (Serialize (Document));
      Put_Line ("> Join Document Formatted:");
      Put_Line (Format (Document));
      New_Line;
   end Test_Join;

   ----------------
   -- Test_Label --
   ----------------

   procedure Test_Label is
      Document : constant Document_Type :=
        Label (To_Unbounded_String ("A"), "B");

   begin
      Put_Line ("=== Label ===");
      Put_Line ("> Label Document JSON:");
      Put_Line (Serialize (Document));
      Put_Line ("> Label Document Formatted:");
      Put_Line (Format (Document));
      New_Line;
   end Test_Label;

   ----------------------
   -- Test_Line_Suffix --
   ----------------------

   procedure Test_Line_Suffix is
      Document : constant Document_Type :=
        List (["A", Line_Suffix (" -- comment"), ";", Hard_Line]);

   begin
      Put_Line ("=== Line_Suffix ===");
      Put_Line ("> Line_Suffix Document JSON:");
      Put_Line (Serialize (Document));
      Put_Line ("> Line_Suffix Document Formatted:");
      Put_Line (Format (Document));
      New_Line;
   end Test_Line_Suffix;

   -------------------------------
   -- Test_Line_Suffix_Boundary --
   -------------------------------

   procedure Test_Line_Suffix_Boundary is
      Document : constant Document_Type :=
        List
          (["if",
            Line_Suffix (" -- comment"),
            Line_Suffix_Boundary, "then",
            Hard_Line]);

   begin
      Put_Line ("=== Line_Suffix ===");
      Put_Line ("> Line_Suffix Document JSON:");
      Put_Line (Serialize (Document));
      Put_Line ("> Line_Suffix Document Formatted:");
      Put_Line (Format (Document));
      New_Line;
   end Test_Line_Suffix_Boundary;

   ---------------
   -- Test_List --
   ---------------

   procedure Test_List is
      Document : constant Document_Type := List (["A", "B"]);

   begin
      Put_Line ("=== List ===");
      Put_Line ("> List Document JSON:");
      Put_Line (Serialize (Document));
      Put_Line ("> List Document Formatted:");
      Put_Line (Format (Document));
      New_Line;
   end Test_List;

   -----------------------
   -- Test_Literal_Line --
   -----------------------

   procedure Test_Literal_Line is
      Document : constant Document_Type :=
        Indent (Group (List (["A   ", Literal_Line, "B", Line, "C"])));

   begin
      Put_Line ("=== Literal_Line ===");
      Put_Line ("> Literal_Line Document JSON:");
      Put_Line (Serialize (Document));
      Put_Line ("> Literal_Line Document Formatted:");
      Put_Line (Format (Document));
      New_Line;
   end Test_Literal_Line;

   --------------------------------------------
   -- Test_Literal_Line_Without_Break_Parent --
   --------------------------------------------

   procedure Test_Literal_Line_Without_Break_Parent is
      Document : constant Document_Type :=
        Indent
          (Group
             (["A   ",
               Literal_Line_Without_Break_Parent,
               "B",
               Line,
               "C"]));

   begin
      Put_Line ("=== Literal_Line_Without_Break_Parent ===");
      Put_Line ("> Literal_Line_Without_Break_Parent Document JSON:");
      Put_Line (Serialize (Document));
      Put_Line ("> Literal_Line_Without_Break_Parent Document Formatted:");
      Put_Line (Format (Document));
      New_Line;
   end Test_Literal_Line_Without_Break_Parent;

   -------------------------
   -- Test_String_Literal --
   -------------------------

   procedure Test_String_Literal is
      Document : constant Document_Type := "A";

   begin
      Put_Line ("=== String_Literal ===");
      Put_Line ("> String_Literal Document JSON:");
      Put_Line (Serialize (Document));
      Put_Line ("> String_Literal Document Formatted:");
      Put_Line (Format (Document));
      New_Line;
   end Test_String_Literal;

   ---------------
   -- Test_Text --
   ---------------

   procedure Test_Text is
      Document : constant Document_Type := Text (To_Unbounded_String ("A"));

   begin
      Put_Line ("=== Text ===");
      Put_Line ("> Text Document JSON:");
      Put_Line (Serialize (Document));
      Put_Line ("> Text Document Formatted:");
      Put_Line (Format (Document));
      New_Line;
   end Test_Text;

   ---------------
   -- Test_Trim --
   ---------------

   procedure Test_Trim is
      Document : constant Document_Type :=
        Indent (List (["A", Hard_Line, Trim, "B"]));

   begin
      Put_Line ("=== Trim ===");
      Put_Line ("> Trim Document JSON:");
      Put_Line (Serialize (Document));
      Put_Line ("> Trim Document Formatted:");
      Put_Line (Format (Document));
      New_Line;
   end Test_Trim;

begin
   GNATCOLL.Traces.Parse_Config_File;

   --  Run all the test procedures
   Test_Align;
   Test_Alignment_Table;
   Test_Alignment_Table_Separator;
   Test_Break_Parent;
   Test_Continuation_Line_Indent;
   Test_Cursor;
   Test_Fill;
   Test_Group;
   Test_Conditional_Group;
   Test_Hard_Line;
   Test_Hard_Line_Without_Break_Parent;
   Test_If_Break;
   Test_Indent;
   Test_Indent_If_Break;
   Test_Join;
   Test_Label;
   Test_Line_Suffix;
   Test_Line_Suffix_Boundary;
   Test_List;
   Test_Literal_Line;
   Test_Literal_Line_Without_Break_Parent;
   Test_String_Literal;
   Test_Text;
   Test_Trim;
end Builders_Tester;
