95 lines
3.3 KiB
C++
95 lines
3.3 KiB
C++
// Copyright 2008 The RE2 Authors. All Rights Reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
// Random testing of regular expression matching.
|
|
|
|
#include <stdio.h>
|
|
#include "util/test.h"
|
|
#include "re2/testing/exhaustive_tester.h"
|
|
|
|
DEFINE_int32(regexpseed, 404, "Random regexp seed.");
|
|
DEFINE_int32(regexpcount, 100, "How many random regexps to generate.");
|
|
DEFINE_int32(stringseed, 200, "Random string seed.");
|
|
DEFINE_int32(stringcount, 100, "How many random strings to generate.");
|
|
|
|
namespace re2 {
|
|
|
|
// Runs a random test on the given parameters.
|
|
// (Always uses the same random seeds for reproducibility.
|
|
// Can give different seeds on command line.)
|
|
static void RandomTest(int maxatoms, int maxops,
|
|
const vector<string>& alphabet,
|
|
const vector<string>& ops,
|
|
int maxstrlen, const vector<string>& stralphabet,
|
|
const string& wrapper) {
|
|
// Limit to smaller test cases in debug mode,
|
|
// because everything is so much slower.
|
|
if (DEBUG_MODE) {
|
|
maxatoms--;
|
|
maxops--;
|
|
maxstrlen /= 2;
|
|
}
|
|
|
|
ExhaustiveTester t(maxatoms, maxops, alphabet, ops,
|
|
maxstrlen, stralphabet, wrapper, "");
|
|
t.RandomStrings(FLAGS_stringseed, FLAGS_stringcount);
|
|
t.GenerateRandom(FLAGS_regexpseed, FLAGS_regexpcount);
|
|
printf("%d regexps, %d tests, %d failures [%d/%d str]\n",
|
|
t.regexps(), t.tests(), t.failures(), maxstrlen, (int)stralphabet.size());
|
|
EXPECT_EQ(0, t.failures());
|
|
}
|
|
|
|
// Tests random small regexps involving literals and egrep operators.
|
|
TEST(Random, SmallEgrepLiterals) {
|
|
RandomTest(5, 5, Explode("abc."), RegexpGenerator::EgrepOps(),
|
|
15, Explode("abc"),
|
|
"");
|
|
}
|
|
|
|
// Tests random bigger regexps involving literals and egrep operators.
|
|
TEST(Random, BigEgrepLiterals) {
|
|
RandomTest(10, 10, Explode("abc."), RegexpGenerator::EgrepOps(),
|
|
15, Explode("abc"),
|
|
"");
|
|
}
|
|
|
|
// Tests random small regexps involving literals, capturing parens,
|
|
// and egrep operators.
|
|
TEST(Random, SmallEgrepCaptures) {
|
|
RandomTest(5, 5, Split(" ", "a (b) ."), RegexpGenerator::EgrepOps(),
|
|
15, Explode("abc"),
|
|
"");
|
|
}
|
|
|
|
// Tests random bigger regexps involving literals, capturing parens,
|
|
// and egrep operators.
|
|
TEST(Random, BigEgrepCaptures) {
|
|
RandomTest(10, 10, Split(" ", "a (b) ."), RegexpGenerator::EgrepOps(),
|
|
15, Explode("abc"),
|
|
"");
|
|
}
|
|
|
|
// Tests random large complicated expressions, using all the possible
|
|
// operators, some literals, some parenthesized literals, and predefined
|
|
// character classes like \d. (Adding larger character classes would
|
|
// make for too many possibilities.)
|
|
TEST(Random, Complicated) {
|
|
vector<string> ops = Split(" ",
|
|
"%s%s %s|%s %s* %s*? %s+ %s+? %s? %s?? "
|
|
"%s{0} %s{0,} %s{1} %s{1,} %s{0,1} %s{0,2} %s{1,2} "
|
|
"%s{2} %s{2,} %s{3,4} %s{4,5}");
|
|
|
|
// Use (?:\b) and (?:\B) instead of \b and \B,
|
|
// because PCRE rejects \b* but accepts (?:\b)*.
|
|
// Ditto ^ and $.
|
|
vector<string> atoms = Split(" ",
|
|
". (?:^) (?:$) \\a \\f \\n \\r \\t \\v "
|
|
"\\d \\D \\s \\S \\w \\W (?:\\b) (?:\\B) "
|
|
"a (a) b c - \\\\");
|
|
vector<string> alphabet = Explode("abc123\001\002\003\t\r\n\v\f\a");
|
|
RandomTest(10, 10, atoms, ops, 20, alphabet, "");
|
|
}
|
|
|
|
} // namespace re2
|
|
|