Add "Describe" command, with support for describing both (a) specific table(s) and...
[squelch.git] / src / test / java / net / jaekl / squelch / SquelchTest.java
1 package net.jaekl.squelch;
2
3 import static org.junit.Assert.assertEquals;
4 import static org.junit.Assert.assertFalse;
5 import static org.junit.Assert.assertTrue;
6 import static org.junit.Assert.fail;
7
8 import java.io.ByteArrayOutputStream;
9 import java.io.IOException;
10 import java.io.OutputStreamWriter;
11 import java.io.PrintWriter;
12 import java.nio.charset.StandardCharsets;
13 import java.sql.Connection;
14 import java.sql.SQLException;
15
16 import net.jaekl.squelch.db.DbDriver;
17 import net.jaekl.squelch.db.MsSqlDriver;
18 import net.jaekl.squelch.db.MySqlDriver;
19 import net.jaekl.squelch.db.OracleDriver;
20 import net.jaekl.squelch.db.PostgresqlDriver;
21 import net.jaekl.squelch.sql.ConnectionMock;
22 import net.jaekl.squelch.util.ConsoleInputMock;
23
24 import org.junit.Test;
25
26 public class SquelchTest {
27         private class NoDbMock extends Squelch {
28                 private ConnectionMock m_conn;
29                 
30                 public NoDbMock() {
31                         m_conn = new ConnectionMock();
32                 }
33                 
34                 @Override
35                 Connection getConnection(DbDriver driver, String jdbcUrl) 
36                         throws ClassNotFoundException, SQLException, SquelchException 
37                 {
38                         return m_conn;
39                 }
40                 
41                 public ConnectionMock mock_getConnectionMock() 
42                 {
43                         return m_conn;
44                 }
45         }
46         
47         @Test
48         public void test_getDriverFor_success() throws SquelchException {
49                 Squelch squelch = new Squelch();
50                 
51                 Object[][] data = {
52                                 { "jdbc:sqlserver://HOST:1433;DatabaseName=DATABASE", MsSqlDriver.class },
53                                 { "jdbc:mysql://HOST/DATABASE", MySqlDriver.class },
54                                 { "jdbc:mysql://HOST:5150/DATABASE", MySqlDriver.class },
55                                 { "jdbc:oracle:thin:@//localhost:1521/XE", OracleDriver.class },
56                                 { "jdbc:oracle:thin:@neptune.acme.com:1521:T10A", OracleDriver.class },
57                                 { "jdbc:oracle:thin:@127.0.0.1:1521:T10A", OracleDriver.class },
58                                 { "jdbc:oracle:oci:@TEST", OracleDriver.class },
59                                 { "jdbc:oracle:oci:@192.168.1.1:1521/XE", OracleDriver.class },
60                                 { "jdbc:postgresql://HOST/DATABASE", PostgresqlDriver.class }
61                 };
62                 
63                 for (Object[] datum : data) {
64                         String jdbcUrl = (String)datum[0];
65                         
66                         @SuppressWarnings("unchecked")
67                         Class<? extends DbDriver> expected = (Class<? extends DbDriver>)datum[1];
68                         
69                         DbDriver actual = squelch.getDriverFor(jdbcUrl);
70                         
71                         assertEquals(expected, actual.getClass());
72                 }
73         }
74         
75         @Test
76         public void test_getDriverFor_notFound() 
77         {
78                 String[] data = { null, "bogus:host/user/pass", "The quick brown fox jumps over the lazy dog" };
79                 Squelch squelch = new Squelch();
80                 
81                 for (String datum : data) {
82                         try {
83                                 squelch.getDriverFor(datum);
84                                 fail("Should have thrown a SquelchException");
85                         }
86                         catch (SquelchException exc) {
87                                 ;       // This is the success path.
88                         }
89                 }
90         }
91
92         @Test
93         public void test_isQuit() {
94                 Squelch squelch = new Squelch();
95                 
96                 final String[] AFFIRMATIVE = {
97                                 "QUIT", " QUIT", " QUIT ", "\tQUIT\r\n", "\\q", "  \\q", "QUIT;", "Quit", "qUiT", " qUIt ", "quit ;",
98                                 "exit", "ExIT", "EXIT", "  EXIT ; ", null
99                 };
100                 final String[] NEGATIVE = {
101                                 "Fred", "SELECT * FROM FOO", "describe tablename", "",
102                                 "CREATE TABLE Fred ( foo INTEGER );"
103                 };
104                 
105                 for (String s : AFFIRMATIVE) {
106                         assertTrue("isQuit(\"" + s + "\") should be true.", squelch.isQuit(s));
107                 }
108                 for (String s : NEGATIVE) {
109                         assertFalse("isQuit(\"" + s + "\") should be false.", squelch.isQuit(s));
110                 }
111         }
112         
113         @Test
114         public void test_pumpLines() throws IOException, ClassNotFoundException, SQLException, SquelchException 
115         {
116                 Squelch squelch = new NoDbMock();
117                 String consoleOutput;
118                 
119                 String[] noLines = {};
120                 consoleOutput = runPump(squelch, noLines);
121                 assertEquals("", consoleOutput);
122                 
123                 String[] quitOnly = {"QUIT"};
124                 consoleOutput = runPump(squelch, quitOnly);
125                 assertEquals(Squelch.PROMPT + "QUIT\n", consoleOutput);
126                 
127                 String[] unrecognizedThenQuit = {"This is not a valid command;", "\\q"};
128                 consoleOutput = runPump(squelch, unrecognizedThenQuit);
129                 assertEquals(Squelch.PROMPT + "This is not a valid command;\n"
130                                      + "??? \"This is not a valid command;\"\n"
131                                      + Squelch.PROMPT + "\\q\n",
132                                      consoleOutput);
133         }
134         
135         @Test
136         public void test_pumpLines_withSelect() throws ClassNotFoundException, IOException, SQLException, SquelchException
137         {
138                 NoDbMock squelch = new NoDbMock();
139                 String consoleOutput;
140                 
141                 String[] simpleSelect = { "SELECT * FROM Fred WHERE wife='Wilma';", "QUIT" };
142                 consoleOutput = runPump(squelch, simpleSelect);
143                 assertEquals(  Squelch.PROMPT + simpleSelect[0] + "\n"
144                                          + "No rows returned.\n"
145                                      + Squelch.PROMPT + simpleSelect[1] + "\n", consoleOutput);
146                 
147                 ConnectionMock cm = squelch.mock_getConnectionMock();
148                 assertTrue(cm.mock_queryWasExecuted(simpleSelect[0].substring(0, simpleSelect[0].length() - 1)));
149         }
150         
151         private String runPump(Squelch squelch, String[] lines) throws IOException, ClassNotFoundException, SQLException, SquelchException
152         {
153                 try (
154                                 ByteArrayOutputStream baos = new ByteArrayOutputStream();
155                                 PrintWriter pw = new PrintWriter(new OutputStreamWriter(baos, StandardCharsets.UTF_8))
156                         )
157                 {
158                         ConsoleInputMock cim = new ConsoleInputMock(pw, lines);
159                         squelch.pumpLines(pw, cim);
160                         pw.close();
161                         baos.close();
162                         return baos.toString();
163                 }               
164         }
165 }