cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From tylerho...@apache.org
Subject cassandra git commit: cqlsh: Add tests for INSERT, UPDATE tab completion
Date Tue, 07 Apr 2015 22:23:53 GMT
Repository: cassandra
Updated Branches:
  refs/heads/cassandra-2.1 cb8cb5f99 -> 879691dd3


cqlsh: Add tests for INSERT, UPDATE tab completion

Patch by Jim Witschey; reviewed by Tyler Hobbs for CASSANDRA-9125


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/879691dd
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/879691dd
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/879691dd

Branch: refs/heads/cassandra-2.1
Commit: 879691dd3546230690835899afb0ff0ce8905eb0
Parents: cb8cb5f
Author: Jim Witschey <jim.witschey@gmail.com>
Authored: Tue Apr 7 17:23:11 2015 -0500
Committer: Tyler Hobbs <tyler@datastax.com>
Committed: Tue Apr 7 17:23:11 2015 -0500

----------------------------------------------------------------------
 CHANGES.txt                                  |   1 +
 pylib/cqlshlib/test/test_cqlsh_completion.py | 299 ++++++++++++++++++++--
 pylib/cqlshlib/test/test_keyspace_init.cql   |  36 ++-
 3 files changed, 290 insertions(+), 46 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/879691dd/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 69f96ba..5cf621d 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 2.1.5
+ * cqlsh: Add tests for INSERT and UPDATE tab completion (CASSANDRA-9125)
  * cqlsh: quote column names when needed in COPY FROM inserts (CASSANDRA-9080)
  * Add generate-idea-files target to build.xml (CASSANDRA-9123)
  * Do not load read meter for offline operations (CASSANDRA-9082)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/879691dd/pylib/cqlshlib/test/test_cqlsh_completion.py
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/test/test_cqlsh_completion.py b/pylib/cqlshlib/test/test_cqlsh_completion.py
index 820414d..2d22a63 100644
--- a/pylib/cqlshlib/test/test_cqlsh_completion.py
+++ b/pylib/cqlshlib/test/test_cqlsh_completion.py
@@ -43,7 +43,61 @@ class CqlshCompletionCase(BaseTestCase):
     def tearDown(self):
         self.cqlsh_runner.__exit__(None, None, None)
 
-    def _trycompletions_inner(self, inputstring, immediate='', choices=(), other_choices_ok=False):
+    def _get_completions(self, inputstring, split_completed_lines=True):
+        """
+        Get results of tab completion in cqlsh. Returns a bare string if a
+        string completes immediately. Otherwise, returns a set of all
+        whitespace-separated tokens in the offered completions by default, or a
+        list of the lines in the offered completions if split_completed_lines is
+        False.
+        """
+        self.cqlsh.send(inputstring)
+        self.cqlsh.send(TAB)
+        immediate = self.cqlsh.read_up_to_timeout(COMPLETION_RESPONSE_TIME)
+        immediate = immediate.replace(' \b', '')
+        self.assertEqual(immediate[:len(inputstring)], inputstring)
+        immediate = immediate[len(inputstring):]
+        immediate = immediate.replace(BEL, '')
+
+        if immediate:
+            return immediate
+
+        self.cqlsh.send(TAB)
+        choice_output = self.cqlsh.read_up_to_timeout(COMPLETION_RESPONSE_TIME)
+        if choice_output == BEL:
+            choice_output = ''
+
+        self.cqlsh.send(CTRL_C) # cancel any current line
+        self.cqlsh.read_to_next_prompt()
+
+        choice_lines = choice_output.splitlines()
+        if choice_lines:
+            # ensure the last line of the completion is the prompt
+            prompt_regex = self.cqlsh.prompt.lstrip() + re.escape(inputstring)
+            msg = ('Double-tab completion '
+                   'does not print prompt for input "{}"'.format(inputstring))
+            self.assertRegexpMatches(choice_lines[-1], prompt_regex, msg=msg)
+
+        choice_lines = [line.strip() for line in choice_lines[:-1]]
+        choice_lines = [line for line in choice_lines if line]
+
+        if split_completed_lines:
+            completed_lines = map(set, (completion_separation_re.split(line.strip())
+                               for line in choice_lines))
+
+            if not completed_lines:
+                return set()
+
+            completed_tokens = set.union(*completed_lines)
+            return completed_tokens - {''}
+        else:
+            return choice_lines
+
+        assert False
+
+    def _trycompletions_inner(self, inputstring, immediate='', choices=(),
+                              other_choices_ok=False,
+                              split_completed_lines=True):
         """
         Test tab completion in cqlsh. Enters in the text in inputstring, then
         simulates a tab keypress to see what is immediately completed (this
@@ -53,37 +107,25 @@ class CqlshCompletionCase(BaseTestCase):
         is simulated in order to get a list of choices, which are expected to
         match the items in 'choices' (order is not important, but case is).
         """
-        self.cqlsh.send(inputstring)
-        self.cqlsh.send(TAB)
-        completed = self.cqlsh.read_up_to_timeout(COMPLETION_RESPONSE_TIME)
-        completed = completed.replace(' \b', '')
-        self.assertEqual(completed[:len(inputstring)], inputstring)
-        completed = completed[len(inputstring):]
-        completed = completed.replace(BEL, '')
-        self.assertEqual(completed, immediate, 'cqlsh completed %r, but we expected %r'
-                                               % (completed, immediate))
+        completed = self._get_completions(inputstring,
+                                         split_completed_lines=split_completed_lines)
+
         if immediate:
+            msg = 'cqlsh completed %r, but we expected %r' % (completed, immediate)
+            self.assertEqual(completed, immediate, msg=msg)
             return
 
-        self.cqlsh.send(TAB)
-        choice_output = self.cqlsh.read_up_to_timeout(COMPLETION_RESPONSE_TIME)
-        if choice_output == BEL:
-            lines = ()
-        else:
-            lines = choice_output.splitlines()
-            self.assertRegexpMatches(lines[-1], self.cqlsh.prompt.lstrip() + re.escape(inputstring))
-        choicesseen = set()
-        for line in lines[:-1]:
-            choicesseen.update(completion_separation_re.split(line.strip()))
-        choicesseen.discard('')
         if other_choices_ok:
-            self.assertEqual(set(choices), choicesseen.intersection(choices))
+            self.assertEqual(set(choices), completed.intersection(choices))
         else:
-            self.assertEqual(set(choices), choicesseen)
+            self.assertEqual(set(choices), set(completed))
 
-    def trycompletions(self, inputstring, immediate='', choices=(), other_choices_ok=False):
+    def trycompletions(self, inputstring, immediate='', choices=(),
+                       other_choices_ok=False, split_completed_lines=True):
         try:
-            self._trycompletions_inner(inputstring, immediate, choices, other_choices_ok)
+            self._trycompletions_inner(inputstring, immediate, choices,
+                                       other_choices_ok=other_choices_ok,
+                                       split_completed_lines=split_completed_lines)
         finally:
             self.cqlsh.send(CTRL_C) # cancel any current line
             self.cqlsh.read_to_next_prompt()
@@ -114,10 +156,213 @@ class TestCqlshCompletion(CqlshCompletionCase):
         pass
 
     def test_complete_in_insert(self):
-        pass
+        self.trycompletions('INSERT INTO  ',
+                            choices=('twenty_rows_table',
+                                     'ascii_with_special_chars',
+                                     'users',
+                                     'has_all_types',
+                                     'system.',
+                                     'system_auth.',
+                                     'empty_composite_table',
+                                     'empty_table',
+                                     'undefined_values_table',
+                                     'dynamic_columns',
+                                     'twenty_rows_composite_table',
+                                     'utf8_with_special_chars',
+                                     'system_traces.',
+                                     'songs'),
+                            other_choices_ok=True)
+        self.trycompletions('INSERT INTO twenty_rows_composite_table',
+                            immediate=' ')
+        self.trycompletions('INSERT INTO twenty_rows_composite_table ',
+                            choices=['(', 'JSON'])
+        self.trycompletions('INSERT INTO twenty_rows_composite_table (a, b ',
+                            choices=(')', ','))
+        self.trycompletions('INSERT INTO twenty_rows_composite_table (a, b, ',
+                            immediate='c ')
+        self.trycompletions('INSERT INTO twenty_rows_composite_table (a, b, c ',
+                            choices=(',', ')'))
+        self.trycompletions('INSERT INTO twenty_rows_composite_table (a, b)',
+                            immediate=' VALUES ( ')
+        self.trycompletions('INSERT INTO twenty_rows_composite_table (a, b, c) VAL',
+                            immediate='UES ( ')
+
+        self.trycompletions(
+            'INSERT INTO twenty_rows_composite_table (a, b, c) VALUES (',
+            ['<value for a (text)>'],
+            split_completed_lines=False)
+
+        self.trycompletions(
+            "INSERT INTO twenty_rows_composite_table (a, b, c) VALUES ('",
+            ['<value for a (text)>'],
+            split_completed_lines=False)
+
+        self.trycompletions(
+            "INSERT INTO twenty_rows_composite_table (a, b, c) VALUES ( 'eggs",
+            ['<value for a (text)>'],
+            split_completed_lines=False)
+
+        self.trycompletions(
+            "INSERT INTO twenty_rows_composite_table (a, b, c) VALUES ('eggs'",
+            immediate=', ')
+
+        self.trycompletions(
+            ("INSERT INTO twenty_rows_composite_table (a, b, c) "
+             "VALUES ( 'eggs',"),
+            ['<value for b (text)>'],
+            split_completed_lines=False)
+
+        self.trycompletions(
+            ("INSERT INTO twenty_rows_composite_table (a, b, c) "
+             "VALUES ( 'eggs', 'sausage', 'spam')"),
+            immediate=' ')
+
+        self.trycompletions(
+            ("INSERT INTO twenty_rows_composite_table (a, b, c) "
+             "VALUES ( 'eggs', 'sausage', 'spam') "),
+            choices=[';', 'USING', 'IF'])
+
+        self.trycompletions(
+            ("INSERT INTO twenty_rows_composite_table (a, b, c) "
+             "VALUES ( 'eggs', 'sausage', 'spam');"),
+            choices=['?', 'ALTER', 'BEGIN', 'CAPTURE', 'CONSISTENCY', 'COPY',
+                     'CREATE', 'DEBUG', 'DELETE', 'DESC', 'DESCRIBE', 'DROP',
+                     'EXPAND', 'GRANT', 'HELP', 'INSERT', 'LIST', 'PAGING',
+                     'REVOKE', 'SELECT', 'SHOW', 'SOURCE', 'TRACING',
+                     'TRUNCATE', 'UPDATE', 'USE', 'exit', 'quit'])
+
+        self.trycompletions(
+            ("INSERT INTO twenty_rows_composite_table (a, b, c) "
+             "VALUES ( 'eggs', 'sausage', 'spam') US"),
+            immediate='ING T')
+
+        self.trycompletions(
+            ("INSERT INTO twenty_rows_composite_table (a, b, c) "
+             "VALUES ( 'eggs', 'sausage', 'spam') USING"),
+            immediate=' T')
+
+        self.trycompletions(
+            ("INSERT INTO twenty_rows_composite_table (a, b, c) "
+             "VALUES ( 'eggs', 'sausage', 'spam') USING T"),
+            choices=['TTL', 'TIMESTAMP'])
+
+        self.trycompletions(
+            ("INSERT INTO twenty_rows_composite_table (a, b, c) "
+             "VALUES ( 'eggs', 'sausage', 'spam') USING TT"),
+            immediate='L ')
+
+        self.trycompletions(
+            ("INSERT INTO twenty_rows_composite_table (a, b, c) "
+             "VALUES ( 'eggs', 'sausage', 'spam') USING TI"),
+            immediate='MESTAMP ')
+
+        self.trycompletions(
+            ("INSERT INTO twenty_rows_composite_table (a, b, c) "
+             "VALUES ( 'eggs', 'sausage', 'spam') USING TIMESTAMP "),
+            choices=['<wholenumber>'])
+
+        self.trycompletions(
+            ("INSERT INTO twenty_rows_composite_table (a, b, c) "
+             "VALUES ( 'eggs', 'sausage', 'spam') USING TTL "),
+            choices=['<wholenumber>'])
+
+        self.trycompletions(
+            ("INSERT INTO twenty_rows_composite_table (a, b, c) "
+             "VALUES ( 'eggs', 'sausage', 'spam') USING TIMESTAMP 0 "),
+            choices=['AND', ';'])
+
+        self.trycompletions(
+            ("INSERT INTO twenty_rows_composite_table (a, b, c) "
+             "VALUES ( 'eggs', 'sausage', 'spam') USING TTL 0 "),
+            choices=['AND', ';'])
+
+        self.trycompletions(
+            ("INSERT INTO twenty_rows_composite_table (a, b, c) "
+             "VALUES ( 'eggs', 'sausage', 'spam') USING TIMESTAMP 0 A"),
+            immediate='ND TTL ')
+
+        self.trycompletions(
+            ("INSERT INTO twenty_rows_composite_table (a, b, c) "
+             "VALUES ( 'eggs', 'sausage', 'spam') USING TTL 0 A"),
+            immediate='ND TIMESTAMP ')
+
+        self.trycompletions(
+            ("INSERT INTO twenty_rows_composite_table (a, b, c) "
+             "VALUES ( 'eggs', 'sausage', 'spam') USING TTL 0 AND TIMESTAMP "),
+            choices=['<wholenumber>'])
+
+        self.trycompletions(
+            ("INSERT INTO twenty_rows_composite_table (a, b, c) "
+             "VALUES ( 'eggs', 'sausage', 'spam') USING TTL 0 AND TIMESTAMP 0 "),
+            choices=['AND', ';'])
+
+        self.trycompletions(
+            ("INSERT INTO twenty_rows_composite_table (a, b, c) "
+             "VALUES ( 'eggs', 'sausage', 'spam') USING TTL 0 AND TIMESTAMP 0 AND "),
+            choices=[])
+
 
     def test_complete_in_update(self):
-        pass
+        self.trycompletions("UPD", immediate="ATE ")
+        self.trycompletions("UPDATE ",
+                            choices=['twenty_rows_table', 'system_auth.',
+                                     'users', 'has_all_types', 'system.',
+                                     'ascii_with_special_chars',
+                                     'empty_composite_table', 'empty_table',
+                                     'undefined_values_table',
+                                     'dynamic_columns',
+                                     'twenty_rows_composite_table',
+                                     'utf8_with_special_chars', 'ks.',
+                                     'system_traces.', 'songs'],
+                            other_choices_ok=True)
+
+        self.trycompletions("UPDATE empty_table ", choices=['USING', 'SET'])
+
+        self.trycompletions("UPDATE empty_table S",
+                            immediate='ET lonelycol = ')
+        self.trycompletions("UPDATE empty_table SET lon",
+                            immediate='elycol = ')
+        self.trycompletions("UPDATE empty_table SET lonelycol",
+                            immediate=' = ')
+
+        self.trycompletions("UPDATE empty_table U", immediate='SING T')
+        self.trycompletions("UPDATE empty_table USING T",
+                            choices=["TTL", "TIMESTAMP"])
+
+        self.trycompletions("UPDATE empty_table SET lonelycol = ",
+                            choices=['<term (text)>'],
+                            split_completed_lines=False)
+
+        self.trycompletions("UPDATE empty_table SET lonelycol = 'eg",
+                            choices=['<term (text)>'],
+                            split_completed_lines=False)
+        self.trycompletions("UPDATE empty_table SET lonelycol = 'eggs'",
+                            choices=[',', 'WHERE'])
+        self.trycompletions("UPDATE empty_table SET lonelycol = 'eggs' WHERE ",
+                            choices=['TOKEN(', '<identifier>', '<quotedName>'])
+        self.trycompletions("UPDATE empty_table SET lonelycol = 'eggs' WHERE ",
+                            choices=['TOKEN(', '<identifier>', '<quotedName>'])
+
+        self.trycompletions("UPDATE empty_table SET lonelycol = 'eggs' WHERE lonel",
+                            choices=['<quotedName>', '<identifier>'])
+        self.trycompletions("UPDATE empty_table SET lonelycol = 'eggs' WHERE lonelykey ",
+                            choices=['=', '<=', '>=', '>', '<', 'CONTAINS', 'IN',
'['])
+        self.trycompletions("UPDATE empty_table SET lonelycol = 'eggs' WHERE lonelykey =
0.0 ",
+                            choices=['AND', 'IF', ';'])
+        self.trycompletions("UPDATE empty_table SET lonelycol = 'eggs' WHERE lonelykey =
0.0 AND ",
+                            choices=['TOKEN(', '<identifier>', '<quotedName>'])
+
+        self.trycompletions("UPDATE empty_table SET lonelycol = 'eggs' WHERE TOKEN(lonelykey
",
+                            choices=[',', ')'])
+        self.trycompletions("UPDATE empty_table SET lonelycol = 'eggs' WHERE TOKEN(lonelykey)
",
+                            choices=['=', '<=', '>=', '<', '>'])
+        self.trycompletions("UPDATE empty_table SET lonelycol = 'eggs' WHERE TOKEN(lonelykey)
<= TOKEN(13) ",
+                            choices=[';', 'AND', 'IF'])
+        self.trycompletions("UPDATE empty_table SET lonelycol = 'eggs' WHERE TOKEN(lonelykey)
<= TOKEN(13) IF ",
+                            choices=['EXISTS', '<quotedName>', '<identifier>'])
+
+        self.trycompletions("UPDATE empty_table SET lonelycol = 'eggs' WHERE TOKEN(lonelykey)
<= TOKEN(13) IF EXISTS ",
+                            choices=['>=', '!=', '<=', 'IN', '[', ';', '=', '<',
'>'])
 
     def test_complete_in_delete(self):
         pass

http://git-wip-us.apache.org/repos/asf/cassandra/blob/879691dd/pylib/cqlshlib/test/test_keyspace_init.cql
----------------------------------------------------------------------
diff --git a/pylib/cqlshlib/test/test_keyspace_init.cql b/pylib/cqlshlib/test/test_keyspace_init.cql
index 1d1e5aa..542721a 100644
--- a/pylib/cqlshlib/test/test_keyspace_init.cql
+++ b/pylib/cqlshlib/test/test_keyspace_init.cql
@@ -5,12 +5,10 @@ CREATE TABLE has_all_types (
     bigintcol bigint,
     blobcol blob,
     booleancol boolean,
-    datecol date,
     decimalcol decimal,
     doublecol double,
     floatcol float,
     textcol text,
-    timecol time,
     timestampcol timestamp,
     uuidcol uuid,
     varcharcol varchar,
@@ -18,34 +16,34 @@ CREATE TABLE has_all_types (
 ) WITH compression = {'sstable_compression':'LZ4Compressor'};
 
 INSERT INTO has_all_types (num, intcol, asciicol, bigintcol, blobcol, booleancol,
-                           datecol, decimalcol, doublecol, floatcol, textcol,
-                           timecol, timestampcol, uuidcol, varcharcol, varintcol)
+                           decimalcol, doublecol, floatcol, textcol,
+                           timestampcol, uuidcol, varcharcol, varintcol)
 VALUES (0, -12, 'abcdefg', 1234567890123456789, 0x000102030405fffefd, true,
-        '2001-07-13', 19952.11882, 1.0, -2.1, 'Voilá!',
-        '23:12:15.889445123', '2012-05-14 12:53:20+0000', bd1924e1-6af8-44ae-b5e1-f24131dbd460,
'"', 10000000000000000000000000);
+        19952.11882, 1.0, -2.1, 'Voilá!',
+        '2012-05-14 12:53:20+0000', bd1924e1-6af8-44ae-b5e1-f24131dbd460, '"', 10000000000000000000000000);
 
 INSERT INTO has_all_types (num, intcol, asciicol, bigintcol, blobcol, booleancol,
-                           datecol, decimalcol, doublecol, floatcol, textcol,
-                           timecol, timestampcol, uuidcol, varcharcol, varintcol)
+                           decimalcol, doublecol, floatcol, textcol,
+                           timestampcol, uuidcol, varcharcol, varintcol)
 VALUES (1, 2147483647, '__!''$#@!~"', 9223372036854775807, 0xffffffffffffffffff, true,
-        '2012-11-30', 0.00000000000001, 9999999.999, 99999.99, '∭Ƕ⑮ฑ➳❏''',
-	'00:01:59.998994', '1900-01-01+0000', ffffffff-ffff-ffff-ffff-ffffffffffff, 'newline->
+        0.00000000000001, 9999999.999, 99999.99, '∭Ƕ⑮ฑ➳❏''',
+        '1900-01-01+0000', ffffffff-ffff-ffff-ffff-ffffffffffff, 'newline->
 <-', 9);
 
 INSERT INTO has_all_types (num, intcol, asciicol, bigintcol, blobcol, booleancol,
-                           datecol, decimalcol, doublecol, floatcol, textcol,
-                           timecol, timestampcol, uuidcol, varcharcol, varintcol)
+                           decimalcol, doublecol, floatcol, textcol,
+                           timestampcol, uuidcol, varcharcol, varintcol)
 VALUES (2, 0, '', 0, 0x, false,
-        0, 0.0, 0.0, 0.0, '',
-        '0:0:0.1', 0, 00000000-0000-0000-0000-000000000000, '', 0);
+        0.0, 0.0, 0.0, '',
+        0, 00000000-0000-0000-0000-000000000000, '', 0);
 
 INSERT INTO has_all_types (num, intcol, asciicol, bigintcol, blobcol, booleancol,
-                           datecol, decimalcol, doublecol, floatcol, textcol,
-                           timecol, timestampcol, uuidcol, varcharcol, varintcol)
+                           decimalcol, doublecol, floatcol, textcol,
+                           timestampcol, uuidcol, varcharcol, varintcol)
 VALUES (3, -2147483648, '''''''', -9223372036854775808, 0x80, false,
-        '9999-12-31', 10.0000000000000, -1004.10, 100000000.9, '龍馭鬱',
-	'23:59:59.999999999', '2038-01-19T03:14-1200', ffffffff-ffff-1fff-8fff-ffffffffffff,
-	'''', -10000000000000000000000000);
+        10.0000000000000, -1004.10, 100000000.9, '龍馭鬱',
+        '2038-01-19T03:14-1200', ffffffff-ffff-1fff-8fff-ffffffffffff,
+	    '''', -10000000000000000000000000);
 
 INSERT INTO has_all_types (num, intcol, asciicol, bigintcol, blobcol, booleancol,
                            decimalcol, doublecol, floatcol, textcol,


Mime
View raw message