GCC Code Coverage Report
Directory: . Exec Total Coverage
File: test/unit/main/interactive_shell_black.cpp Lines: 62 62 100.0 %
Date: 2021-08-06 Branches: 46 104 44.2 %

Line Exec Source
1
/******************************************************************************
2
 * Top contributors (to current version):
3
 *   Aina Niemetz, Christopher L. Conway, Andrew Reynolds
4
 *
5
 * This file is part of the cvc5 project.
6
 *
7
 * Copyright (c) 2009-2021 by the authors listed in the file AUTHORS
8
 * in the top-level source directory and their institutional affiliations.
9
 * All rights reserved.  See the file COPYING in the top-level source
10
 * directory for licensing information.
11
 * ****************************************************************************
12
 *
13
 * Black box testing of cvc5::InteractiveShell.
14
 */
15
16
#include <sstream>
17
#include <vector>
18
19
#include "api/cpp/cvc5.h"
20
#include "expr/symbol_manager.h"
21
#include "main/interactive_shell.h"
22
#include "options/base_options.h"
23
#include "options/language.h"
24
#include "options/options.h"
25
#include "parser/parser_builder.h"
26
#include "smt/command.h"
27
#include "test.h"
28
29
namespace cvc5 {
30
namespace test {
31
32
24
class TestMainBlackInteractiveShell : public TestInternal
33
{
34
 protected:
35
12
  void SetUp() override
36
  {
37
12
    TestInternal::SetUp();
38
39
12
    d_sin = std::make_unique<std::stringstream>();
40
12
    d_stdin = std::cin.rdbuf();
41
12
    std::cin.rdbuf(d_sin->rdbuf());
42
43
12
    d_sout = std::make_unique<std::stringstream>();
44
12
    d_stdout = std::cout.rdbuf();
45
12
    std::cout.rdbuf(d_sout->rdbuf());
46
47
12
    d_solver.reset(new cvc5::api::Solver());
48
12
    d_solver->setOption("input-language", "cvc");
49
12
    d_symman.reset(new SymbolManager(d_solver.get()));
50
12
  }
51
52
12
  void TearDown() override
53
  {
54
12
    std::cin.rdbuf(d_stdin);
55
12
    d_sin.reset(nullptr);
56
12
    std::cout.rdbuf(d_stdout);
57
12
    d_sout.reset(nullptr);
58
    // ensure that symbol manager is destroyed before solver
59
12
    d_symman.reset(nullptr);
60
12
    d_solver.reset(nullptr);
61
12
  }
62
63
  /**
64
   * Read up to maxCommands+1 from the shell and throw an assertion error if
65
   * it's fewer than minCommands and more than maxCommands.  Note that an
66
   * empty string followed by EOF may be returned as an empty command, and
67
   * not NULL (subsequent calls to readCommand() should return NULL). E.g.,
68
   * "CHECKSAT;\n" may return two commands: the CHECKSAT, followed by an
69
   * empty command, followed by NULL.
70
   */
71
12
  void countCommands(InteractiveShell& shell,
72
                     uint32_t minCommands,
73
                     uint32_t maxCommands)
74
  {
75
    Command* cmd;
76
12
    uint32_t n = 0;
77
40
    while (n <= maxCommands && (cmd = shell.readCommand()) != NULL)
78
    {
79
14
      ++n;
80
14
      delete cmd;
81
    }
82
12
    ASSERT_LE(n, maxCommands);
83
12
    ASSERT_GE(n, minCommands);
84
  }
85
86
  std::unique_ptr<std::stringstream> d_sin;
87
  std::unique_ptr<std::stringstream> d_sout;
88
  std::unique_ptr<SymbolManager> d_symman;
89
  std::unique_ptr<cvc5::api::Solver> d_solver;
90
91
  std::streambuf* d_stdin;
92
  std::streambuf* d_stdout;
93
};
94
95
15
TEST_F(TestMainBlackInteractiveShell, assert_true)
96
{
97
2
  *d_sin << "ASSERT TRUE;\n" << std::flush;
98
4
  InteractiveShell shell(d_solver.get(), d_symman.get());
99
2
  countCommands(shell, 1, 1);
100
2
}
101
102
15
TEST_F(TestMainBlackInteractiveShell, query_false)
103
{
104
2
  *d_sin << "QUERY FALSE;\n" << std::flush;
105
4
  InteractiveShell shell(d_solver.get(), d_symman.get());
106
2
  countCommands(shell, 1, 1);
107
2
}
108
109
15
TEST_F(TestMainBlackInteractiveShell, def_use1)
110
{
111
4
  InteractiveShell shell(d_solver.get(), d_symman.get());
112
2
  *d_sin << "x : REAL; ASSERT x > 0;\n" << std::flush;
113
  /* readCommand may return a sequence, so we can't say for sure
114
     whether it will return 1 or 2... */
115
2
  countCommands(shell, 1, 2);
116
2
}
117
118
15
TEST_F(TestMainBlackInteractiveShell, def_use2)
119
{
120
4
  InteractiveShell shell(d_solver.get(), d_symman.get());
121
  /* readCommand may return a sequence, see above. */
122
2
  *d_sin << "x : REAL;\n" << std::flush;
123
2
  Command* tmp = shell.readCommand();
124
2
  *d_sin << "ASSERT x > 0;\n" << std::flush;
125
2
  countCommands(shell, 1, 1);
126
2
  delete tmp;
127
2
}
128
129
15
TEST_F(TestMainBlackInteractiveShell, empty_line)
130
{
131
4
  InteractiveShell shell(d_solver.get(), d_symman.get());
132
2
  *d_sin << std::flush;
133
2
  countCommands(shell, 0, 0);
134
2
}
135
136
15
TEST_F(TestMainBlackInteractiveShell, repeated_empty_lines)
137
{
138
2
  *d_sin << "\n\n\n";
139
4
  InteractiveShell shell(d_solver.get(), d_symman.get());
140
  /* Might return up to four empties, might return nothing */
141
2
  countCommands(shell, 0, 3);
142
2
}
143
}  // namespace test
144
21
}  // namespace cvc5