Home | History | Annotate | Download | only in testing
      1 // Copyright 2008 The RE2 Authors.  All Rights Reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 // Test StringGenerator.
      6 
      7 #include <stdlib.h>
      8 #include <string>
      9 #include <vector>
     10 #include "util/test.h"
     11 #include "re2/testing/string_generator.h"
     12 #include "re2/testing/regexp_generator.h"
     13 
     14 namespace re2 {
     15 
     16 // Returns i to the e.
     17 static int64 IntegerPower(int i, int e) {
     18   int64 p = 1;
     19   while (e-- > 0)
     20     p *= i;
     21   return p;
     22 }
     23 
     24 // Checks that for given settings of the string generator:
     25 //   * it generates strings that are non-decreasing in length.
     26 //   * strings of the same length are sorted in alphabet order.
     27 //   * it doesn't generate the same string twice.
     28 //   * it generates the right number of strings.
     29 //
     30 // If all of these hold, the StringGenerator is behaving.
     31 // Assumes that the alphabet is sorted, so that the generated
     32 // strings can just be compared lexicographically.
     33 static void RunTest(int len, string alphabet, bool donull) {
     34   StringGenerator g(len, Explode(alphabet));
     35 
     36   int n = 0;
     37   int last_l = -1;
     38   string last_s;
     39 
     40   if (donull) {
     41     g.GenerateNULL();
     42     EXPECT_TRUE(g.HasNext());
     43     StringPiece sp = g.Next();
     44     EXPECT_EQ(sp.data(), static_cast<const char*>(NULL));
     45     EXPECT_EQ(sp.size(), 0);
     46   }
     47 
     48   while (g.HasNext()) {
     49     string s = g.Next().as_string();
     50     n++;
     51 
     52     // Check that all characters in s appear in alphabet.
     53     for (const char *p = s.c_str(); *p != '\0'; ) {
     54       Rune r;
     55       p += chartorune(&r, p);
     56       EXPECT_TRUE(utfrune(alphabet.c_str(), r) != NULL);
     57     }
     58 
     59     // Check that string is properly ordered w.r.t. previous string.
     60     int l = utflen(s.c_str());
     61     EXPECT_LE(l, len);
     62     if (last_l < l) {
     63       last_l = l;
     64     } else {
     65       EXPECT_EQ(last_l, l);
     66       EXPECT_LT(last_s, s);
     67     }
     68     last_s = s;
     69   }
     70 
     71   // Check total string count.
     72   int64 m = 0;
     73   int alpha = utflen(alphabet.c_str());
     74   if (alpha == 0)  // Degenerate case.
     75     len = 0;
     76   for (int i = 0; i <= len; i++)
     77     m += IntegerPower(alpha, i);
     78   EXPECT_EQ(n, m);
     79 }
     80 
     81 TEST(StringGenerator, NoLength) {
     82   RunTest(0, "abc", false);
     83 }
     84 
     85 TEST(StringGenerator, NoLengthNoAlphabet) {
     86   RunTest(0, "", false);
     87 }
     88 
     89 TEST(StringGenerator, NoAlphabet) {
     90   RunTest(5, "", false);
     91 }
     92 
     93 TEST(StringGenerator, Simple) {
     94   RunTest(3, "abc", false);
     95 }
     96 
     97 TEST(StringGenerator, UTF8) {
     98   RunTest(4, "abc\xE2\x98\xBA", false);
     99 }
    100 
    101 TEST(StringGenerator, GenNULL) {
    102   RunTest(0, "abc", true);
    103   RunTest(0, "", true);
    104   RunTest(5, "", true);
    105   RunTest(3, "abc", true);
    106   RunTest(4, "abc\xE2\x98\xBA", true);
    107 }
    108 
    109 }  // namespace re2
    110