The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

TestBirdFont.vala in /libbirdfont

This file is a part of the Birdfont project.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git
Circle boundaries heads/master
1 /* 2 Copyright (C) 2012, 2014 Johan Mattsson 3 4 This library is free software; you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as 6 published by the Free Software Foundation; either version 3 of the 7 License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 */ 14 15 namespace BirdFont { 16 17 /** Class for executing tests cases. */ 18 class TestBirdFont : GLib.Object { 19 20 const int NOT_STARTED = 0; 21 const int RUNNING = 1; 22 const int PAUSED = 2; 23 const int DONE = 3; 24 25 static int state = NOT_STARTED; 26 27 TestCases tests; 28 29 unowned List<Test> test_cases; 30 unowned List<Test?>? current_case = null; 31 32 List<Test> passed; 33 List<Test> failed; 34 List<Test> skipped; 35 36 List<Test> bechmarks; 37 38 static TestBirdFont? singleton = null; 39 40 bool has_failed = false; 41 bool has_skipped = false; 42 43 static bool slow_test = false; 44 45 public string test_cases_to_run; // name of specific test case or all to run all test cases 46 47 public TestBirdFont () { 48 assert (singleton == null); 49 tests = new TestCases (); 50 test_cases = tests.get_test_functions (); 51 current_case = test_cases.first (); 52 test_cases_to_run = "All"; 53 from_command_line (); 54 } 55 56 public static bool is_slow_test () { 57 return slow_test; 58 } 59 60 public static void set_slow_test (bool s) { 61 slow_test = s; 62 } 63 64 public static void run_tests () { 65 TestBirdFont t = get_singleton (); 66 state = RUNNING; 67 t.run_all_tests (); 68 } 69 70 public static TestBirdFont get_singleton () { 71 if (singleton == null) { 72 singleton = new TestBirdFont (); 73 } 74 75 return (!) singleton; 76 } 77 78 private bool has_test_case (string s) { 79 foreach (var t in test_cases) { 80 if (t.name == s) return true; 81 } 82 83 return s == "" || s == "All"; 84 } 85 86 /** Run only test specified on the command line. */ 87 private void from_command_line () { 88 string? stn = BirdFont.get_argument ("--test"); 89 90 if (stn != null) { 91 string st = (!) stn; 92 93 if (!has_test_case (st)) { 94 stderr.printf (@"Test case \"$st\" does not exist.\n"); 95 stderr.printf ("\nAvailable test cases:\n"); 96 97 foreach (var t in test_cases) { 98 stderr.printf (t.name); 99 stderr.printf ("\n"); 100 } 101 102 Process.exit(1); 103 } 104 105 if (st == "All" || st == "") { 106 return; 107 } else { 108 stderr.printf (@"Run test case \"$st\" \n"); 109 } 110 111 test_cases_to_run = st; 112 } 113 } 114 115 public static void log (string? log_domain, LogLevelFlags log_levels, string message) { 116 Test t = (!)((!)get_singleton ().current_case).data; 117 118 if (log_domain != null) { 119 stderr.printf ("%s: \n", (!) log_domain); 120 } 121 122 stderr.printf ("Testcase \"%s\" failed because:\n", t.name); 123 stderr.printf ("%s\n\n", message); 124 125 get_singleton ().has_failed = true; 126 127 assert (!BirdFont.fatal_wanings); 128 } 129 130 public static void @continue () { 131 int s = AtomicInt.get (ref state); 132 if (s == DONE) { 133 singleton = null; 134 } 135 136 TestBirdFont t = get_singleton (); 137 138 LogLevelFlags levels = LogLevelFlags.LEVEL_ERROR | LogLevelFlags.LEVEL_CRITICAL | LogLevelFlags.LEVEL_WARNING; 139 Log.set_handler (null, levels, log); 140 141 AtomicInt.set (ref state, RUNNING); 142 t.run_all_tests (); 143 } 144 145 public static bool is_running () { 146 int r = AtomicInt.get (ref state); 147 return (r == RUNNING); 148 } 149 150 public static void pause () { 151 AtomicInt.set (ref state, PAUSED); 152 Log.set_handler (null, LogLevelFlags.LEVEL_MASK, Log.default_handler); 153 } 154 155 private static void pad (int t) { 156 for (int i = 0; i < t; i++) { 157 stdout.printf (" "); 158 } 159 } 160 161 public void print_result () { 162 stdout.printf ("\n"); 163 stdout.printf ("Test case results:\n"); 164 165 foreach (Test t in skipped) { 166 stdout.printf ("%s", t.name); 167 pad (40 - t.name.char_count()); 168 stdout.printf ("Skipped\n"); 169 } 170 171 if (skipped.length () > 0) { 172 stdout.printf ("\n"); 173 } 174 175 foreach (Test t in passed) { 176 stdout.printf ("%s", t.name); 177 pad (40 - t.name.char_count()); 178 stdout.printf ("Passed\n"); 179 } 180 181 foreach (Test t in failed) { 182 stdout.printf ("%s", t.name); 183 pad (40 - t.name.char_count()); 184 stdout.printf ("Failed\n"); 185 } 186 187 foreach (Test t in bechmarks) { 188 stdout.printf ("%s", t.name); 189 pad (40 - t.name.char_count()); 190 stdout.printf (@"$(t.get_time ())s\n"); 191 } 192 193 stdout.printf ("\n"); 194 stdout.printf ("Total %u test cases executed, %u passed and %u failed.\n", (passed.length () + failed.length ()), passed.length (), failed.length ()); 195 } 196 197 /** Run tests in main loop. */ 198 public void run_all_tests () { 199 TimeoutSource idle = new TimeoutSource (20); 200 201 idle.set_callback(() => { 202 int s = AtomicInt.get (ref state); 203 204 if (s != RUNNING || current_case == null) { 205 return false; 206 } 207 208 Test test = (!)((!) current_case).data; 209 210 has_failed = false; 211 has_skipped = false; 212 213 if (test_cases_to_run != "All" && test_cases_to_run != test.name) { 214 has_skipped = true; 215 } else { 216 if (test.is_benchmark ()) { 217 test.timer_start (); 218 test.callback (); 219 test.print (); 220 } else { 221 test.callback (); 222 } 223 } 224 225 if (test.is_benchmark ()) { 226 bechmarks.append ((!) test); 227 } else if (has_failed) { 228 failed.append ((!) test); 229 230 if (BirdFont.has_argument ("--exit")) { 231 print_result (); 232 Process.exit (1); 233 } 234 235 } else if (has_skipped) { 236 skipped.append ((!) test); 237 } else { 238 passed.append ((!) test); 239 } 240 241 if (unlikely (current_case == test_cases.last ())) { 242 stdout.printf ("Finished running test suite.\n"); 243 244 AtomicInt.set (ref state, DONE); 245 Log.set_handler (null, LogLevelFlags.LEVEL_MASK, Log.default_handler); 246 247 print_result (); 248 249 if (BirdFont.has_argument ("--exit")) { 250 print_result (); 251 Process.exit ((failed.length () == 0) ? 0 : 1); 252 } 253 return false; 254 } 255 256 current_case = ((!) current_case).next; 257 258 return true; 259 }); 260 261 idle.attach (null); 262 } 263 264 } 265 266 } 267