1

我正在尝试使用简单的Ada.Text_IO.Put. 为简单起见,这是我想测试的一种虚构方法:

procedure Say_Something is
begin
   Put("Something.");
end Say_Something;

在我的 AUnit 测试中,我有:

procedure Test_Put (T : in out Test) is
   pragma Unreferenced (T);
   use Ada.Text_IO;

   Stdout : constant File_Type := Standard_Output;
   Put_File_Name : constant String := "say_something_test.txt";
   Put_File : File_Type;

   Expected : constant String := "Something.";
begin
   --  Create the output file and redirect output
   Create (Put_File, Append_File, Put_File_Name);
   Set_Output (Put_File);

   Say_Something;

   --  Redirect output to stdout and close the file
   Set_Output (Stdout);
   Close (Put_File);

   --  Read file
   declare
      File_Size : constant Natural :=
         Natural (Ada.Directories.Size (Put_File_Name));
         Actual : String (1 .. File_Size);
   begin
      Actual := Read_File (Put_File_Name, File_Size);
      Ada.Directories.Delete_File (Put_File_Name);

      Assert (Expected = Actual,
              "Expected " & '"' & Expected & '"' & ", " &
              "Got "      & '"' & Actual   & '"');
   end;
end Test_Put;

function Read_File (File_Name : String; File_Size : Natural)
   return String is
   subtype File_String is String (1 .. File_Size);
   package File_String_IO is new Ada.Direct_IO (File_String);

   File : File_String_IO.File_Type;
   Contents : File_String;
begin
   File_String_IO.Open (File, File_String_IO.In_File, File_Name);
   File_String_IO.Read (File, Contents);
   File_String_IO.Close (File);

   return Contents;
end Read_File;

不幸的是,结果是:

FAIL Test Vectors.Put
    Expected "Something.", Got "Something.
"

似乎 Ada 自动在文件末尾添加了一个换行符。我意识到我可以将 (CR)LF 添加到我的预期字符串中,如下所示:

Expected : constant String := "Something.";
   & Ada.Characters.Latin_1.CR
   & Ada.Characters.Latin_1.LF;

但是 a) 更改我预期的字符串感觉不对,b) 这将在 Windows 机器上运行,但在 Unix/Linux/Mac 上我必须删除“CR”。换句话说,我的测试运行是否成功取决于平台,而我的代码不是,这很糟糕。

所以我的问题是:如何在附加换行符的情况下写入文件?关于如何测试输出的其他建议也非常受欢迎。

我已经看到了这个相关的问题,但无法从中推断出任何有用的信息,除了我可能会尝试Append_File而不是Out_File模式,这并没有解决我的问题。

4

2 回答 2

5

抱歉我之前的回答,我错过了您正在阅读的文件是您在程序中较早创建的文件。

Ada.Text_IORM (A.10(7-8)) 中,“文件的结尾由行终止符的组合标记,紧跟页终止符,然后是文件终止符”,以及“终止符的实际性质不是由语言定义的,因此取决于实现”......“它们不一定被实现为字符或字符序列”。因此,当您创建时say_something_test.txt,它将始终以“行终止符”结尾,尽管这并不一定意味着它将以 LF 结尾。那是依赖于实现的。唯一可以保证的是,如果您用于Ada.Text_IO创建文件,如果您使用Ada.Text_IO. 但是,如果您想要对写入文件的实际字节进行这种级别的控制,那么Ada.Text_IO真的不适合;你最好使用Ada.Stream_IO.

是否将 CR 和/或 LF 写入文件末尾取决于实现。看起来 GNAT 确实在末尾添加了 LF(可能还有 CR),并且它没有提供Form关闭此行为的方法(例如参数)。至少我没有在手册中看到一个。

如果你真的决定使用Ada.Text_IO写入say_something_test.txtAda.Direct_IO读回它,那么你需要知道文件可能包含也可能不包含 CR/LF,并且输入例程应该检查这些字符并将它们删除,以便该字符串可以与预期值进行比较。

于 2013-11-06T16:16:32.510 回答
1

您将 Text_IO 用于输出,但在将其读回时使用 Direct_IO。您不应该像那样混合它们,因为它们会做不同的事情。在您的简单示例中,所有输出都是测试,因此我建议您在测试中也使用 Text_IO 将其读回。

于 2013-11-06T16:18:15.463 回答