1// Copyright 2008 the V8 project authors. All rights reserved. 2// Redistribution and use in source and binary forms, with or without 3// modification, are permitted provided that the following conditions are 4// met: 5// 6// * Redistributions of source code must retain the above copyright 7// notice, this list of conditions and the following disclaimer. 8// * Redistributions in binary form must reproduce the above 9// copyright notice, this list of conditions and the following 10// disclaimer in the documentation and/or other materials provided 11// with the distribution. 12// * Neither the name of Google Inc. nor the names of its 13// contributors may be used to endorse or promote products derived 14// from this software without specific prior written permission. 15// 16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28#include "cctest.h" 29#include <stdio.h> 30#include <stdlib.h> 31#include <string.h> 32 33 34CcTest* CcTest::last_ = NULL; 35 36// The windows compiler doesn't like to use `strdup`, and claims it's a 37// deprecated name. 38// For simplicity just implement it ourselves. 39static char* Strdup(const char* str) { 40 size_t len = strlen(str); 41 char* result = reinterpret_cast<char*>(malloc(len + 1)); 42 memcpy(result, str, len + 1); 43 return result; 44} 45 46CcTest::CcTest(TestFunction* callback, const char* test_file, 47 const char* test_name, const char* test_dependency, 48 bool test_is_enabled) 49 : callback_(callback), name_(test_name), dependency_(test_dependency), 50 prev_(last_) { 51 // Find the base name of this test (const_cast required on Windows). 52 char *basename = strrchr(const_cast<char *>(test_file), '/'); 53 if (!basename) { 54 basename = strrchr(const_cast<char *>(test_file), '\\'); 55 } 56 if (!basename) { 57 basename = Strdup(test_file); 58 } else { 59 basename = Strdup(basename + 1); 60 } 61 // Drop the extension, if there is one. 62 char *extension = strrchr(basename, '.'); 63 if (extension) *extension = 0; 64 // Install this test in the list of tests 65 file_ = basename; 66 enabled_ = test_is_enabled; 67 prev_ = last_; 68 last_ = this; 69} 70 71 72static void PrintTestList(CcTest* current) { 73 if (current == NULL) return; 74 PrintTestList(current->prev()); 75 if (current->dependency() != NULL) { 76 printf("%s/%s<%s\n", 77 current->file(), current->name(), current->dependency()); 78 } else { 79 printf("%s/%s<\n", current->file(), current->name()); 80 } 81} 82 83 84int main(int argc, char* argv[]) { 85 int tests_run = 0; 86 bool print_run_count = true; 87 if (argc == 1) { 88 // Just run all the tests. 89 CcTest* test = CcTest::last(); 90 while (test != NULL) { 91 if (test->enabled()) { 92 test->Run(); 93 tests_run++; 94 } 95 test = test->prev(); 96 } 97 } 98 for (int i = 1; i < argc; i++) { 99 char* arg = argv[i]; 100 if (strcmp(arg, "--list") == 0) { 101 PrintTestList(CcTest::last()); 102 print_run_count = false; 103 104 } else { 105 char* arg_copy = Strdup(arg); 106 char* testname = strchr(arg_copy, '/'); 107 if (testname) { 108 // Split the string in two by nulling the slash and then run 109 // exact matches. 110 *testname = 0; 111 char* file = arg_copy; 112 char* name = testname + 1; 113 CcTest* test = CcTest::last(); 114 while (test != NULL) { 115 if (test->enabled() 116 && strcmp(test->file(), file) == 0 117 && strcmp(test->name(), name) == 0) { 118 test->Run(); 119 tests_run++; 120 } 121 test = test->prev(); 122 } 123 124 } else { 125 // Run all tests with the specified file or test name. 126 char* file_or_name = arg_copy; 127 CcTest* test = CcTest::last(); 128 while (test != NULL) { 129 if (test->enabled() 130 && (strcmp(test->file(), file_or_name) == 0 131 || strcmp(test->name(), file_or_name) == 0)) { 132 test->Run(); 133 tests_run++; 134 } 135 test = test->prev(); 136 } 137 } 138 free(arg_copy); 139 } 140 } 141 if (print_run_count && tests_run != 1) 142 printf("Ran %i tests.\n", tests_run); 143 return 0; 144} 145