Many hyperlinks are disabled.
Use anonymous login
to enable hyperlinks.
Changes In Branch jsunit-port Excluding Merge-Ins
This is equivalent to a diff from 01e4c3bd57 to c8ab5e94db
2011-11-17
| ||
10:24 | Изменения эксперементальной ветки jsunit-port перенесены в trunk check-in: 1224326503 user: kuntashov tags: trunk | |
09:53 | Исправлены незначительные недочеты Leaf check-in: c8ab5e94db user: kuntashov tags: jsunit-port | |
2011-11-16
| ||
05:41 | Добавлена возможность перезагрузки тестов check-in: ef17cf47ba user: kuntashov tags: jsunit-port | |
2011-11-14
| ||
10:04 | Устранен форк check-in: e15e083d91 user: kuntashov tags: trunk | |
2011-11-10
| ||
20:22 | Синхронизировано с trunk check-in: ffed03ffd1 user: kuntashov tags: jsunit-port | |
12:57 | Начал скрипт для быстрого выбора в подсказке о параметрах check-in: 01e4c3bd57 user: orefkov tags: trunk | |
2011-11-07
| ||
14:17 | Мелкие изменения скрипта внешние файлы check-in: fef94c65e2 user: vladnet tags: trunk | |
Added DevTools/testrunner.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 |
$engine JScript $uname TestRunner $dname Менеджер юнит-тестов скриптов $addin SnegopatMainScript $addin global $addin stdlib global.connectGlobals(SelfScript) var jsUnitCore = stdlib.require("jsUnitCore.js"); /* Анонимный обработчик, который мы передаем, позволяет обойти проблему с отловом исключений, брошенных в контексте скрипта-библиотеки. */ jsUnitCore.SetErrorHandler(function (exception) { throw exception; }); OpenTestRunner(); //////////////////////////////////////////////////////////////////////////////////////// //// TestRunner //// function TestRunner() { TestRunner._instance = this; this.errorCount = 0; this.successCount = 0; this.failureCount = 0; this.form = loadScriptForm("scripts\\DevTools\\testrunner.ssf", this) this.form.Открыть(); this.allTests = this.form.ЭлементыФормы.тпДеревоТестов.Значение; this.allTests.Колонки.Добавить("object"); this.loadedTestAddins = []; // Варианты состояний выполнения тестов this.STATE_NOT_RUN = 0; this.STATE_SUCCESS = 1; this.STATE_IGNORE = 2; this.STATE_FAILURE = 3; // Иконки состояний. this.StateIcons = { Gray : this.form.ЭлементыФормы.ПолеКартинкиСерый.Картинка, Green: this.form.ЭлементыФормы.ПолеКартинкиЗеленый.Картинка, Yellow: this.form.ЭлементыФормы.ПолеКартинкиЖелтый.Картинка, Red: this.form.ЭлементыФормы.ПолеКартинкиКрасный.Картинка } } TestRunner.prototype.resetCounters = function() { this.errorCount = 0; this.successCount = 0; this.failureCount = 0; this.updateTotals(); } TestRunner.prototype.updateTotals = function () { this.form.ЭлементыФормы.КоличествоТестовВсего.Значение = this.testsCount; this.form.ЭлементыФормы.КоличествоУспешныхТестов.Значение = this.successCount; this.form.ЭлементыФормы.КоличествоПроваленныхТестов.Значение = this.failureCount; } TestRunner.prototype.initProgressBar = function () { this.switchProgressBar(true); this.form.ЭлементыФормы.ИндикаторВыполнения.МинимальноеЗначение = 0; this.form.ЭлементыФормы.ИндикаторВыполнения.МаксимальноеЗначение = this.testsCount; this.form.ЭлементыФормы.ИндикаторВыполнения.Шаг = 1; this.form.ЭлементыФормы.ИндикаторВыполнения.Значение = 0; } TestRunner.prototype.progressBarDoStep = function () { this.form.ЭлементыФормы.ИндикаторВыполнения.Значение = this.form.ЭлементыФормы.ИндикаторВыполнения.Значение + 1; } TestRunner.prototype.switchProgressBar = function (progressBarVisible) { this.form.ЭлементыФормы.НадписьВсего.Видимость = !progressBarVisible; this.form.ЭлементыФормы.КоличествоТестовВсего.Видимость = !progressBarVisible; this.form.ЭлементыФормы.НадписьУспешно.Видимость = !progressBarVisible; this.form.ЭлементыФормы.КоличествоУспешныхТестов.Видимость = !progressBarVisible; this.form.ЭлементыФормы.НадписьПровалено.Видимость = !progressBarVisible; this.form.ЭлементыФормы.КоличествоПроваленныхТестов.Видимость = !progressBarVisible; this.form.ЭлементыФормы.ИндикаторВыполнения.Видимость = !!progressBarVisible; } TestRunner.prototype.unloadAllTests = function () { this.allTests.Строки.Очистить(); for (var i=0; i<this.loadedTestAddins.length; i++) { if (this.loadedTestAddins[i].uniqueName) addins.unloadAddin(this.loadedTestAddins[i]); } this.loadedTestAddins = []; } TestRunner.prototype.loadTests = function(path) { this.unloadAllTests(); this.testsCount = 0; this.walkFilesAndLoad(path, this.allTests); if (this.allTests.Строки.Количество() == 0) { Message("В каталоге " + path + " тест-кейсов не найдено!"); return; } // Развернем все уровни дерева. for(var i=0; i<this.allTests.Строки.Количество(); i++) this.form.ЭлементыФормы.тпДеревоТестов.Развернуть(this.allTests.Строки.Получить(i), true); this.updateTotals(); } TestRunner.prototype.isTestAddinFile = function(file) { // Имя тестового скрипта должно начинаться с префикса "test" if (!file.Name.match(/^test/i)) return false; // Поддерживаются пока только скрипты. if (!file.Extension.match(/js|vbs/i)) return false; return true; } TestRunner.prototype.walkFilesAndLoad = function(path, parentNode) { var f = v8New("File", path); var files = f.IsFile() ? [ f ] : FindFiles(path, "*", false); for (var i=0; i<files.length; i++) { var Файл = files[i]; if (Файл.ЭтоКаталог()) { var newNode = this.addTestGroup(parentNode, Файл); this.walkFilesAndLoad(Файл.ПолноеИмя, newNode); // Пустые каталоги не показываем в дереве тестов. if (newNode.Rows.Count() == 0) parentNode.Rows.Delete(newNode); } else if (this.isTestAddinFile(Файл)) { try { var testAddin = this.loadTestAddin(Файл.ПолноеИмя); if (testAddin) { var newNode = this.addTestCase(parentNode, testAddin); if (newNode.Rows.Count() == 0) { jsUnitCore.warn("Скрипт не содержит макросов и не будет загружен: " + testAddin.fullPath); parentNode.Rows.Delete(newNode); addins.unloadAddin(testAddin); if(!testAddin.uniqueName.length) delete testAddin; } else { this.loadedTestAddins.push(testAddin); } } } catch (e) { jsUnitCore.warn("Ошибка загрузки скрипта: " + Файл.ПолноеИмя); // TODO: выводить информацию об ошибке подробнее. } } } } TestRunner.prototype.loadTestAddin = function(path) { var fullLoadString = "script:" + path; var testAddin = addins.byFullPath(fullLoadString); if (!testAddin) { // Тест-аддины будем подгружать в группу "Подгружаемые библиотеки". libGroup = SnegopatMainScript.AddinsTreeGroups.LoadedLibs; // Загружаем тестовый аддин. try { testAddin = addins.loadAddin(fullLoadString, libGroup); } catch(e) { jsUnitCore("TestRunner::loadTestAddin: Тестовый скрипт не загружен: " + path); return null; } } return testAddin; } TestRunner.prototype.addTestGroup = function(parentNode, Файл) { var newNode = parentNode.Строки.Добавить(); newNode.НазваниеТеста = Файл.Имя; newNode.ВремяВыполнения = 0; newNode.ПолныйПуть = Файл.ПолноеИмя; newNode.Состояние = this.STATE_NOT_RUN; newNode.object = null; return newNode; } TestRunner.prototype.addTestCase = function(parentNode, testAddin) { var newNode = parentNode.Rows.Add(); newNode.НазваниеТеста = testAddin.uniqueName; newNode.ВремяВыполнения = 0; newNode.ПолныйПуть = testAddin.fullPath; newNode.Состояние = this.STATE_NOT_RUN; newNode.object = testAddin; // Добавим тест-методы. Тест-метод - это макросы с именами вида macrosTestИмяТеста. var macroses = new VBArray(testAddin.macroses()).toArray(); for(var m in macroses) if (macroses[m].match(/^Test/)) this.addTest(newNode, macroses[m], testAddin); return newNode; } TestRunner.prototype.addTest = function(parentNode, testName, testAddin) { var newNode = parentNode.Строки.Добавить(); newNode.НазваниеТеста = testName; newNode.ВремяВыполнения = 0; newNode.ПолныйПуть = testAddin.fullPath; newNode.Состояние = this.STATE_NOT_RUN; newNode.object = new Test(testAddin, testName); this.testsCount++; return newNode; } TestRunner.prototype.runAllTests = function() { for (var i = 0; i < this.allTests.Строки.Количество(); i++) { var ТекущаяСтрока = this.allTests.Строки.Получить(i); var beginTime = new Date(); ТекущаяСтрока.Состояние = this.runTest(ТекущаяСтрока); ТекущаяСтрока.ВремяВыполнения = (new Date() - beginTime) / 1000; } } TestRunner.prototype.runTest = function (СтрокаТестов) { var Состояние = this.STATE_SUCCESS; if (СтрокаТестов.object && jsUnitCore.JsUnit._trueTypeOf(СтрокаТестов.object) == 'Test') { Состояние = this.executeTestFunction(СтрокаТестов); this.progressBarDoStep(); } else { if (СтрокаТестов.Строки.Количество() == 0) return this.STATE_IGNORE; for (var i = 0; i < СтрокаТестов.Строки.Количество(); i++) { var ТекущаяСтрока = СтрокаТестов.Строки.Получить(i); var beginTime = new Date(); ТекущаяСтрока.Состояние = this.runTest(ТекущаяСтрока); ТекущаяСтрока.ВремяВыполнения = (new Date() - beginTime) / 1000; if (ТекущаяСтрока.Состояние != this.STATE_SUCCESS) Состояние = this.STATE_FAILURE; } } return Состояние; } TestRunner.prototype.setTestStatus = function(test, excep) { var message = 'Тест ' + test.fullTestName + ' '; if (excep == null) { test.status = this.STATE_SUCCESS; this.successCount++; message += 'выполнен успешно'; } else { test.exception = excep; if (!excep.isJsUnitFailure) { this.errorCount++; test.status = this.STATE_FAILURE; message += ' остановлен из-за ошибки в нем (exception or error)'; } else { //debugger; this.failureCount++; test.status = this.STATE_FAILURE; message += " провалился (assertion failed)" + (excep.comment ? "\n\t" + excep.comment : "") + (excep.jsUnitMessage ? "\n\t" + excep.jsUnitMessage : ""); } } test.message = message; Message(message); return test.status; } TestRunner.prototype.executeTestFunction = function(СтрокаТеста) { var theTest = СтрокаТеста.object; var testAddin = theTest.addin; var testFunctionName = 'macros' + theTest.testName; var exception = null; var timeBefore = new Date(); try { if (testAddin.object.setUp !== jsUnitCore.JSUNIT_UNDEFINED_VALUE) testAddin.object.setUp(); testAddin.object[testFunctionName].call(null); } catch (e1) { exception = e1; } finally { try { if (testAddin.object.tearDown !== jsUnitCore.JSUNIT_UNDEFINED_VALUE) testAddin.object.tearDown(); } catch (e2) { //Unlike JUnit, only assign a tearDown exception to excep if there is not already an exception from the test body if (exception == null) exception = e2; } } СтрокаТеста.ВремяВыполнения = (new Date() - timeBefore) / 1000; return this.setTestStatus(theTest, exception); } TestRunner.prototype.getDefaultTestsDir = function() { var mainFolder = profileRoot.getValue("Snegopat/MainFolder"); var f = v8New("Файл", mainFolder + "scripts\\Tests"); if (f.Существует() && f.ЭтоКаталог()) return f.ПолноеИмя; return mainFolder; } //////////////////////////////////////////////////////////////////////////////////////// //// ОБРАБОТЧИКИ СОБЫТИЙ ФОРМЫ И ЕЕ ЭЛЕМЕНТОВ. //// TestRunner.prototype.КнопкаЗагрузитьТестыНажатие = function(Элемент) { var ВыборКаталога = v8New("ДиалогВыбораФайла", РежимДиалогаВыбораФайла.ВыборКаталога); ВыборКаталога.ПолноеИмяФайла = ""; ВыборКаталога.Заголовок = "Выберите каталог c тестами"; ВыборКаталога.Каталог = this.getDefaultTestsDir(); if (ВыборКаталога.Выбрать()) { this.form.Путь = ВыборКаталога.Каталог; this.loadTests(ВыборКаталога.Каталог); } } TestRunner.prototype.КнопкаЗагрузитьТестыЗагрузитьТестКейс = function (Элемент) { var ВыборФайла = v8New("ДиалогВыбораФайла", РежимДиалогаВыбораФайла.Открытие); ВыборФайла.Заголовок = "Выберите тестовый скрипт"; ВыборФайла.Каталог = this.getDefaultTestsDir(); if (ВыборФайла.Выбрать()) { this.form.Путь = ВыборФайла.ПолноеИмяФайла; this.loadTests(ВыборФайла.ПолноеИмяФайла); } } TestRunner.prototype.КнопкаПерезагрузитьНажатие = function (Элемент) { if (this.form.Путь == "") { Предупреждение("Сначала загрузите тесты!"); return; } this.switchProgressBar(false); this.resetCounters(); this.loadTests(this.form.Путь); } TestRunner.prototype.КнопкаВыполнитьВсеТестыНажатие = function (Элемент) { this.resetCounters(); this.initProgressBar(); this.runAllTests(); this.updateTotals(); this.switchProgressBar(false); } TestRunner.prototype.КнопкаВыполнитьВыделенныйНажатие = function (Элемент) { Message("Не реализовано"); } TestRunner.prototype.тпДеревоТестовПриВыводеСтроки = function(Элемент, ОформлениеСтроки, ДанныеСтроки) { var Ячейки = ОформлениеСтроки.val.Ячейки; // Устанавливаем иконку состояния выполнения. var Состояние = ДанныеСтроки.val.Состояние; if (Состояние == this.STATE_SUCCESS) Ячейки.НазваниеТеста.УстановитьКартинку(this.StateIcons.Green) else if (Состояние == this.STATE_IGNORE) Ячейки.НазваниеТеста.УстановитьКартинку(this.StateIcons.Yellow) else if (Состояние == this.STATE_FAILURE) Ячейки.НазваниеТеста.УстановитьКартинку(this.StateIcons.Red) else Ячейки.НазваниеТеста.УстановитьКартинку(this.StateIcons.Gray) } TestRunner.prototype.ПриОткрытии = function () { this.resetCounters(); this.switchProgressBar(false); } TestRunner.prototype.ПриЗакрытии = function () { this.unloadAllTests(); } //////////////////////////////////////////////////////////////////////////////////////// //// ВСПОМОГАТЕЛЬНЫЕ ОБЪЕКТЫ И ФУНКЦИИ. //// function FindFiles(path, mask) { // Из snegopat.js. // TODO: Перенести в библиотеку Utils. // На NT-системах порядок выдачи файлов в FindFirstFile/FindNextFile неопределен, те они НЕОБЯЗАТЕЛЬНО // выдаются отсортированными по именам, поэтому на разных машинах могут выдаваться в разном порядке. // Кроме того, каталоги и файлы могут выдаваться вперемешку. // Также в документации к НайтиФайлы нет никакого упоминания о порядке выдачи файлов. // В случае зависимости одного стандартного скрипта от другого (например, snegopatwnd.js при // загрузке сразу обращается к global_context.js) это может привести к проблемам. // Поэтом примем такой порядок загрузки: // Сначала загружаются все подкатологи, отсортированные по имени. // Затем загржаются все файлы, отсортированные по имени. var allFiles = new Array(); var files = new Array(); var filesArray = new Enumerator(globalContext("{22A21030-E1D6-46A0-9465-F0A5427BE011}").НайтиФайлы(path.replace(/\\/g, '/'), "*", false)); for ( ; !filesArray.atEnd(); filesArray.moveNext()) { var file = filesArray.item(); (file.ЭтоКаталог() ? allFiles : files).push(file); } var sortByNames = function (i1, i2) { return i1.Имя.toLowerCase().localeCompare(i2.Имя.toLowerCase()) }; allFiles.sort(sortByNames); files.sort(sortByNames); for (var i=0; i<files.length; i++) allFiles.push(files[i]); return allFiles; } function Test(addin, testName) { this.addin = addin; this.fullTestName = addin.uniqueName + "::" + testName; this.testName = testName; this.exeption = null; this.message = ""; } function OpenTestRunner() { if (!TestRunner._instance) new TestRunner(); return TestRunner._instance; } |
Added DevTools/testrunner.ssf.
cannot compute difference between binary files
Added Libs/jsUnitCore.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 |
$engine JScript $uname jsUnitCore $dname Библиотека юнит-тестирования для JavaScript $addin global /** * @fileoverview * jsUnitCore.js contains the implementation of the core JsUnit functionality: assertions, JsUnitTestSuites, and JsUnit.Failure. * An HTML page is considered to be a JsUnit Test Page if it "includes" jsUnitCore.js, i.e. the following line is present: * <code> * <script type="text/javascript" src="/path/to/jsUnitCore.js"></script> * </code> * @author Edward Hieatt, edward@jsunit.net, http://www.jsunit.net */ /** * Порт библиотеки jsUnitCore.js (http://jsunit.net) для проекта "Снегопат" (http://snegopat.ru). * Автор порта: Александр Кунташов, kuntashov@gmail.com */ var JsUnit = {}; //Snegopat. // Обход проблемы перехвата в вызывающем методе исключений, // брошенных в методе другого скрипта. var _callerErrorHandler = null; function SetErrorHandler(errorHandler) { if (_callerErrorHandler && errorHandler && _callerErrorHandler != errorHandler) { /* Пока поддерживаем только одного подписчика на ошибки. Чтобы исключить случайные выстрелы в ногу, исключим любые другие попытки установки обработчика. */ warn("jsUnitCore.js::GetInsance(): только один скрипт может установить обработчик ошибок!"); } else { _callerErrorHandler = errorHandler; } } function SnegopatThrowException(exception) { if (_callerErrorHandler) _callerErrorHandler.call(null, exception); throw exception; } /////Snegopat. /** * The JsUnit version * @version */ JsUnit.VERSION = 2.2; var JSUNIT_VERSION = JsUnit.VERSION; /** * For convenience, a variable that equals "undefined" */ var JSUNIT_UNDEFINED_VALUE; /** * Whether or not the current test page has been (completely) loaded yet */ var isTestPageLoaded = false; /** * Predicate used for testing JavaScript == (i.e. equality excluding type) */ JsUnit.DOUBLE_EQUALITY_PREDICATE = function(var1, var2) {return var1 == var2;}; /** * Predicate used for testing JavaScript === (i.e. equality including type) */ JsUnit.TRIPLE_EQUALITY_PREDICATE = function(var1, var2) {return var1 === var2;}; /** * Predicate used for testing whether two obects' toStrings are equal */ JsUnit.TO_STRING_EQUALITY_PREDICATE = function(var1, var2) {return var1.toString() === var2.toString();}; /** * Hash of predicates for testing equality by primitive type */ JsUnit.PRIMITIVE_EQUALITY_PREDICATES = { 'String': JsUnit.DOUBLE_EQUALITY_PREDICATE, 'Number': JsUnit.DOUBLE_EQUALITY_PREDICATE, 'Boolean': JsUnit.DOUBLE_EQUALITY_PREDICATE, 'Date': JsUnit.TRIPLE_EQUALITY_PREDICATE, 'RegExp': JsUnit.TO_STRING_EQUALITY_PREDICATE, 'Function': JsUnit.TO_STRING_EQUALITY_PREDICATE } /** * Hack for NS62 bug * @private */ JsUnit._fixTop = function() { var tempTop = top; if (!tempTop) { tempTop = window; while (tempTop.parent) { tempTop = tempTop.parent; if (tempTop.top && tempTop.top.jsUnitTestSuite) { tempTop = tempTop.top; break; } } } try { window.top = tempTop; } catch (e) { } } //Snegopat. //JsUnit._fixTop(); /////Snegopat. /** * @param Any object * @return String - the type of the given object * @private */ JsUnit._trueTypeOf = function(something) { var result = typeof something; try { switch (result) { case 'string': break; case 'boolean': break; case 'number': break; case 'object': case 'function': switch (something.constructor) { case new String().constructor: result = 'String'; break; case new Boolean().constructor: result = 'Boolean'; break; case new Number().constructor: result = 'Number'; break; case new Array().constructor: result = 'Array'; break; case new RegExp().constructor: result = 'RegExp'; break; case new Date().constructor: result = 'Date'; break; case Function: result = 'Function'; break; default: if (something.constructor) { var m = something.constructor.toString().match(/function\s*([^( ]+)\(/); if (m) result = m[1]; else break; } else break; } break; } } finally { result = result.substr(0, 1).toUpperCase() + result.substr(1); return result; } } /** * @private */ JsUnit._displayStringForValue = function(aVar) { var result = '<' + aVar + '>'; if (!(aVar === null || aVar === JSUNIT_UNDEFINED_VALUE)) { result += ' (' + JsUnit._trueTypeOf(aVar) + ')'; } return result; } /** * @private */ JsUnit._argumentsIncludeComments = function(expectedNumberOfNonCommentArgs, args) { return args.length == expectedNumberOfNonCommentArgs + 1; } /** * @private */ JsUnit._commentArg = function(expectedNumberOfNonCommentArgs, args) { if (JsUnit._argumentsIncludeComments(expectedNumberOfNonCommentArgs, args)) return args[0]; return null; } /** * @private */ JsUnit._nonCommentArg = function(desiredNonCommentArgIndex, expectedNumberOfNonCommentArgs, args) { return JsUnit._argumentsIncludeComments(expectedNumberOfNonCommentArgs, args) ? args[desiredNonCommentArgIndex] : args[desiredNonCommentArgIndex - 1]; } /** * @private */ JsUnit._validateArguments = function(expectedNumberOfNonCommentArgs, args) { if (!( args.length == expectedNumberOfNonCommentArgs || (args.length == expectedNumberOfNonCommentArgs + 1 && (typeof(args[0]) == 'string') || args[0] == null))) throw new JsUnit.AssertionArgumentError('Incorrect arguments passed to assert function'); } /** * @private */ JsUnit._checkEquals = function(var1, var2) { return var1 === var2; } /** * @private */ JsUnit._checkNotUndefined = function(aVar) { return aVar !== JSUNIT_UNDEFINED_VALUE; } /** * @private */ JsUnit._checkNotNull = function(aVar) { return aVar !== null; } /** * All assertions ultimately go through this method. * @private */ JsUnit._assert = function(comment, booleanValue, failureMessage) { if (!booleanValue) SnegopatThrowException(new JsUnit.Failure(comment, failureMessage)); //throw new JsUnit.Failure(comment, failureMessage); } /** * Checks that the given boolean value is true. * @param comment optional, displayed in the case of failure * @value value that is expected to be true * @throws JsUnit.Failure if the given value is not true * @throws JsUnitInvalidAssertionArgument if the given value is not a boolean or if an incorrect number of arguments is passed */ function assert() { JsUnit._validateArguments(1, arguments); var booleanValue = JsUnit._nonCommentArg(1, 1, arguments); if (typeof(booleanValue) != 'boolean') SnegopatThrowException(new JsUnit.AssertionArgumentError('Bad argument to assert(boolean)')); //throw new JsUnit.AssertionArgumentError('Bad argument to assert(boolean)'); JsUnit._assert(JsUnit._commentArg(1, arguments), booleanValue === true, 'Call to assert(boolean) with false'); } /** * Synonym for assertTrue * @see #assert */ function assertTrue() { JsUnit._validateArguments(1, arguments); assert(JsUnit._commentArg(1, arguments), JsUnit._nonCommentArg(1, 1, arguments)); } /** * Checks that a boolean value is false. * @param comment optional, displayed in the case of failure * @value value that is expected to be false * @throws JsUnit.Failure if value is not false * @throws JsUnitInvalidAssertionArgument if the given value is not a boolean or if an incorrect number of arguments is passed */ function assertFalse() { JsUnit._validateArguments(1, arguments); var booleanValue = JsUnit._nonCommentArg(1, 1, arguments); if (typeof(booleanValue) != 'boolean') throw new JsUnit.AssertionArgumentError('Bad argument to assertFalse(boolean)'); JsUnit._assert(JsUnit._commentArg(1, arguments), booleanValue === false, 'Call to assertFalse(boolean) with true'); } /** * Checks that two values are equal (using ===) * @param comment optional, displayed in the case of failure * @param expected the expected value * @param actual the actual value * @throws JsUnit.Failure if the values are not equal * @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed */ function assertEquals() { JsUnit._validateArguments(2, arguments); var var1 = JsUnit._nonCommentArg(1, 2, arguments); var var2 = JsUnit._nonCommentArg(2, 2, arguments); JsUnit._assert(JsUnit._commentArg(2, arguments), JsUnit._checkEquals(var1, var2), 'Expected ' + JsUnit._displayStringForValue(var1) + ' but was ' + JsUnit._displayStringForValue(var2)); } /** * Checks that two values are not equal (using !==) * @param comment optional, displayed in the case of failure * @param value1 a value * @param value2 another value * @throws JsUnit.Failure if the values are equal * @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed */ function assertNotEquals() { JsUnit._validateArguments(2, arguments); var var1 = JsUnit._nonCommentArg(1, 2, arguments); var var2 = JsUnit._nonCommentArg(2, 2, arguments); JsUnit._assert(JsUnit._commentArg(2, arguments), var1 !== var2, 'Expected not to be ' + JsUnit._displayStringForValue(var2)); } /** * Checks that a value is null * @param comment optional, displayed in the case of failure * @param value the value * @throws JsUnit.Failure if the value is not null * @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed */ function assertNull() { JsUnit._validateArguments(1, arguments); var aVar = JsUnit._nonCommentArg(1, 1, arguments); JsUnit._assert(JsUnit._commentArg(1, arguments), aVar === null, 'Expected ' + JsUnit._displayStringForValue(null) + ' but was ' + JsUnit._displayStringForValue(aVar)); } /** * Checks that a value is not null * @param comment optional, displayed in the case of failure * @param value the value * @throws JsUnit.Failure if the value is null * @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed */ function assertNotNull() { JsUnit._validateArguments(1, arguments); var aVar = JsUnit._nonCommentArg(1, 1, arguments); JsUnit._assert(JsUnit._commentArg(1, arguments), JsUnit._checkNotNull(aVar), 'Expected not to be ' + JsUnit._displayStringForValue(null)); } /** * Checks that a value is undefined * @param comment optional, displayed in the case of failure * @param value the value * @throws JsUnit.Failure if the value is not undefined * @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed */ function assertUndefined() { JsUnit._validateArguments(1, arguments); var aVar = JsUnit._nonCommentArg(1, 1, arguments); JsUnit._assert(JsUnit._commentArg(1, arguments), aVar === JSUNIT_UNDEFINED_VALUE, 'Expected ' + JsUnit._displayStringForValue(JSUNIT_UNDEFINED_VALUE) + ' but was ' + JsUnit._displayStringForValue(aVar)); } /** * Checks that a value is not undefined * @param comment optional, displayed in the case of failure * @param value the value * @throws JsUnit.Failure if the value is undefined * @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed */ function assertNotUndefined() { JsUnit._validateArguments(1, arguments); var aVar = JsUnit._nonCommentArg(1, 1, arguments); JsUnit._assert(JsUnit._commentArg(1, arguments), JsUnit._checkNotUndefined(aVar), 'Expected not to be ' + JsUnit._displayStringForValue(JSUNIT_UNDEFINED_VALUE)); } /** * Checks that a value is NaN (Not a Number) * @param comment optional, displayed in the case of failure * @param value the value * @throws JsUnit.Failure if the value is a number * @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed */ function assertNaN() { JsUnit._validateArguments(1, arguments); var aVar = JsUnit._nonCommentArg(1, 1, arguments); JsUnit._assert(JsUnit._commentArg(1, arguments), isNaN(aVar), 'Expected NaN'); } /** * Checks that a value is not NaN (i.e. is a number) * @param comment optional, displayed in the case of failure * @param value the value * @throws JsUnit.Failure if the value is not a number * @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed */ function assertNotNaN() { JsUnit._validateArguments(1, arguments); var aVar = JsUnit._nonCommentArg(1, 1, arguments); JsUnit._assert(JsUnit._commentArg(1, arguments), !isNaN(aVar), 'Expected not NaN'); } /** * Checks that an object is equal to another using === for primitives and their object counterparts but also desceding * into collections and calling assertObjectEquals for each element * @param comment optional, displayed in the case of failure * @param value the expected value * @param value the actual value * @throws JsUnit.Failure if the actual value does not equal the expected value * @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed */ function assertObjectEquals() { JsUnit._validateArguments(2, arguments); var var1 = JsUnit._nonCommentArg(1, 2, arguments); var var2 = JsUnit._nonCommentArg(2, 2, arguments); var failureMessage = JsUnit._commentArg(2, arguments) ? JsUnit._commentArg(2, arguments) : ''; if (var1 === var2) return; var isEqual = false; var typeOfVar1 = JsUnit._trueTypeOf(var1); var typeOfVar2 = JsUnit._trueTypeOf(var2); if (typeOfVar1 == typeOfVar2) { var primitiveEqualityPredicate = JsUnit.PRIMITIVE_EQUALITY_PREDICATES[typeOfVar1]; if (primitiveEqualityPredicate) { isEqual = primitiveEqualityPredicate(var1, var2); } else { var expectedKeys = JsUnit.Util.getKeys(var1).sort().join(", "); var actualKeys = JsUnit.Util.getKeys(var2).sort().join(", "); if (expectedKeys != actualKeys) { JsUnit._assert(failureMessage, false, 'Expected keys "' + expectedKeys + '" but found "' + actualKeys + '"'); } for (var i in var1) { assertObjectEquals(failureMessage + ' found nested ' + typeOfVar1 + '@' + i + '\n', var1[i], var2[i]); } isEqual = true; } } JsUnit._assert(failureMessage, isEqual, 'Expected ' + JsUnit._displayStringForValue(var1) + ' but was ' + JsUnit._displayStringForValue(var2)); } /** * Checks that an array is equal to another by checking that both are arrays and then comparing their elements using assertObjectEquals * @param comment optional, displayed in the case of failure * @param value the expected array * @param value the actual array * @throws JsUnit.Failure if the actual value does not equal the expected value * @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed */ function assertArrayEquals() { JsUnit._validateArguments(2, arguments); var array1 = JsUnit._nonCommentArg(1, 2, arguments); var array2 = JsUnit._nonCommentArg(2, 2, arguments); if (JsUnit._trueTypeOf(array1) != 'Array' || JsUnit._trueTypeOf(array2) != 'Array') { throw new JsUnit.AssertionArgumentError('Non-array passed to assertArrayEquals'); } assertObjectEquals(JsUnit._commentArg(2, arguments), JsUnit._nonCommentArg(1, 2, arguments), JsUnit._nonCommentArg(2, 2, arguments)); } /** * Checks that a value evaluates to true in the sense that value == true * @param comment optional, displayed in the case of failure * @param value the value * @throws JsUnit.Failure if the actual value does not evaluate to true * @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed */ function assertEvaluatesToTrue() { JsUnit._validateArguments(1, arguments); var value = JsUnit._nonCommentArg(1, 1, arguments); if (!value) fail(JsUnit._commentArg(1, arguments)); } /** * Checks that a value evaluates to false in the sense that value == false * @param comment optional, displayed in the case of failure * @param value the value * @throws JsUnit.Failure if the actual value does not evaluate to true * @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed */ function assertEvaluatesToFalse() { JsUnit._validateArguments(1, arguments); var value = JsUnit._nonCommentArg(1, 1, arguments); if (value) fail(JsUnit._commentArg(1, arguments)); } /** * Checks that a value is the same as an HTML string by "standardizing" both and comparing the result for equality. * Standardizing is done by temporarily creating a DIV, setting the innerHTML of the DIV to the string, and asking for * the innerHTML back. * @param comment optional, displayed in the case of failure * @param value1 the expected HTML string * @param value2 the actual HTML string * @throws JsUnit.Failure if the standardized actual value does not equal the standardized expected value * @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed */ function assertHTMLEquals() { //Snegopat. JsUnit.error("assertHTMLEquals() не поддерживается в Снегопате."); //JsUnit._validateArguments(2, arguments); //var var1 = JsUnit._nonCommentArg(1, 2, arguments); //var var2 = JsUnit._nonCommentArg(2, 2, arguments); //var var1Standardized = JsUnit.Util.standardizeHTML(var1); //var var2Standardized = JsUnit.Util.standardizeHTML(var2); //JsUnit._assert(JsUnit._commentArg(2, arguments), var1Standardized === var2Standardized, 'Expected ' + JsUnit._displayStringForValue(var1Standardized) + ' but was ' + JsUnit._displayStringForValue(var2Standardized)); /////Snegopat. } /** * Checks that a hash is has the same contents as another by iterating over the expected hash and checking that each * key's value is present in the actual hash and calling assertEquals on the two values, and then checking that there is * no key in the actual hash that isn't present in the expected hash. * @param comment optional, displayed in the case of failure * @param value the expected hash * @param value the actual hash * @throws JsUnit.Failure if the actual hash does not evaluate to true * @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed */ function assertHashEquals() { JsUnit._validateArguments(2, arguments); var var1 = JsUnit._nonCommentArg(1, 2, arguments); var var2 = JsUnit._nonCommentArg(2, 2, arguments); for (var key in var1) { assertNotUndefined("Expected hash had key " + key + " that was not found", var2[key]); assertEquals( "Value for key " + key + " mismatch - expected = " + var1[key] + ", actual = " + var2[key], var1[key], var2[key] ); } for (var key in var2) { assertNotUndefined("Actual hash had key " + key + " that was not expected", var1[key]); } } /** * Checks that two value are within a tolerance of one another * @param comment optional, displayed in the case of failure * @param value1 a value * @param value1 another value * @param tolerance the tolerance * @throws JsUnit.Failure if the two values are not within tolerance of each other * @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments is passed */ function assertRoughlyEquals() { JsUnit._validateArguments(3, arguments); var expected = JsUnit._nonCommentArg(1, 3, arguments); var actual = JsUnit._nonCommentArg(2, 3, arguments); var tolerance = JsUnit._nonCommentArg(3, 3, arguments); assertTrue( "Expected " + expected + ", but got " + actual + " which was more than " + tolerance + " away", Math.abs(expected - actual) < tolerance ); } /** * Checks that a collection contains a value by checking that collection.indexOf(value) is not -1 * @param comment optional, displayed in the case of failure * @param collection the collection * @param value the value * @throws JsUnit.Failure if the collection does not contain the value * @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments are passed */ function assertContains() { JsUnit._validateArguments(2, arguments); var value = JsUnit._nonCommentArg(1, 2, arguments); var collection = JsUnit._nonCommentArg(2, 2, arguments); assertTrue( "Expected '" + collection + "' to contain '" + value + "'", collection.indexOf(value) != -1 ); } /** * Checks that two arrays have the same contents, ignoring the order of the contents * @param comment optional, displayed in the case of failure * @param array1 first array * @param array2 second array * @throws JsUnit.Failure if the two arrays contain different contents * @throws JsUnitInvalidAssertionArgument if an incorrect number of arguments are passed */ function assertArrayEqualsIgnoringOrder() { JsUnit._validateArguments(2, arguments); var var1 = JsUnit._nonCommentArg(1, 2, arguments); var var2 = JsUnit._nonCommentArg(2, 2, arguments); var notEqualsMessage = "Expected arrays " + JsUnit._displayStringForValue(var1) + " and " + JsUnit._displayStringForValue(var2) + " to be equal (ignoring order)"; var notArraysMessage = "Expected arguments " + JsUnit._displayStringForValue(var1) + " and " + JsUnit._displayStringForValue(var2) + " to be arrays"; JsUnit._assert(JsUnit._commentArg(2, arguments), JsUnit._checkNotNull(var1), notEqualsMessage); JsUnit._assert(JsUnit._commentArg(2, arguments), JsUnit._checkNotNull(var2), notEqualsMessage); JsUnit._assert(JsUnit._commentArg(2, arguments), JsUnit._checkNotUndefined(var1.length), notArraysMessage); JsUnit._assert(JsUnit._commentArg(2, arguments), JsUnit._checkNotUndefined(var1.join), notArraysMessage); JsUnit._assert(JsUnit._commentArg(2, arguments), JsUnit._checkNotUndefined(var2.length), notArraysMessage); JsUnit._assert(JsUnit._commentArg(2, arguments), JsUnit._checkNotUndefined(var2.join), notArraysMessage); JsUnit._assert(JsUnit._commentArg(1, arguments), JsUnit._checkEquals(var1.length, var2.length), notEqualsMessage); for (var i = 0; i < var1.length; i++) { var found = false; for (var j = 0; j < var2.length; j++) { try { assertObjectEquals(notEqualsMessage, var1[i], var2[j]); found = true; } catch (ignored) { } } JsUnit._assert(JsUnit._commentArg(2, arguments), found, notEqualsMessage); } } /** * Synonym for assertArrayEqualsIgnoringOrder * @see #assertArrayEqualsIgnoringOrder */ function assertEqualsIgnoringOrder() { JsUnit._validateArguments(2, arguments); assertArrayEqualsIgnoringOrder(JsUnit._commentArg(2, arguments), JsUnit._nonCommentArg(1, 2, arguments), JsUnit._nonCommentArg(2, 2, arguments)); } /** * Causes a failure * @param failureMessage the message for the failure */ function fail(failureMessage) { throw new JsUnit.Failure("Call to fail()", failureMessage); } /** * Causes an error * @param errorMessage the message for the error */ function error(errorMessage) { throw new JsUnitError(errorMessage); } /** * @class * A JsUnit.Failure represents an assertion failure (or a call to fail()) during the execution of a Test Function * @param comment an optional comment about the failure * @param message the reason for the failure */ JsUnit.Failure = function(comment, message) { /** * Declaration that this is a JsUnit.Failure * @ignore */ this.isJsUnitFailure = true; /** * An optional comment about the failure */ this.comment = comment; /** * The reason for the failure */ this.jsUnitMessage = message; /** * The stack trace at the point at which the failure was encountered */ this.stackTrace = JsUnit.Util.getStackTrace(); } /** * @deprecated */ JsUnitFailure = JsUnit.Failure; /** * @class * A JsUnitError represents an error (an exception or a call to error()) during the execution of a Test Function * @param description the reason for the failure */ JsUnit.Error = function(description) { /** * The description of the error */ this.description = description; /** * The stack trace at the point at which the error was encountered */ this.stackTrace = JsUnit.Util.getStackTrace(); } /** * @deprecated */ JsUnitError = JsUnit.Error; /** * @class * A JsUnitAssertionArgumentError represents an invalid call to an assertion function - either an invalid argument type * or an incorrect number of arguments * @param description a description of the argument error */ JsUnit.AssertionArgumentError = function(description) { /** * A description of the argument error */ this.description = description; } function isLoaded() { return isTestPageLoaded; } /** * @private */ function setUp() { } /** * @private */ function tearDown() { } //Snegopat. // TODO: реализовать полноценный трейсер/логгер. function SnegopatTrace(message, value, marker) { var text = message; if (value) text += ': ' + JsUnit._displayStringForValue(value); Message(text, marker); } /////Snegopat. function warn() { SnegopatTrace(arguments[0], arguments[1], mExc1); } function inform() { SnegopatTrace(arguments[0], arguments[1], mInfo); } function info() { SnegopatTrace(arguments[0], arguments[1]); } function debug() { SnegopatTrace(arguments[0], arguments[1], mNone); } /** * @class * A JsUnitTestSuite represents a suite of JsUnit Test Pages. Test Pages and Test Suites can be added to a * JsUnitTestSuite * @constructor */ function JsUnitTestSuite() { /** * Declares that this object is a JsUnitTestSuite */ this.isJsUnitTestSuite = true; /** * @private */ this._testPages = Array(); /** * @private */ this._pageIndex = 0; for (var i = 0; i < arguments.length; i++) { if (arguments[i]._testPages) { this.addTestSuite(arguments[i]); } else { this.addTestPage(arguments[i]); } } } /** * Adds a Test Page to the suite * @param pageName the path to the Test Page */ JsUnitTestSuite.prototype.addTestPage = function (page) { this._testPages[this._testPages.length] = page; } /** * Adds a Test Suite to the suite * @param suite another JsUnitTestSuite object */ JsUnitTestSuite.prototype.addTestSuite = function (suite) { for (var i = 0; i < suite._testPages.length; i++) this.addTestPage(suite._testPages[i]); } /** * Whether the suite contains any Test Pages */ JsUnitTestSuite.prototype.containsTestPages = function () { return this._testPages.length > 0; } /** * Moves the suite on to its next Test Page */ JsUnitTestSuite.prototype.nextPage = function () { return this._testPages[this._pageIndex++]; } /** * Whether the suite has more Test Pages */ JsUnitTestSuite.prototype.hasMorePages = function () { return this._pageIndex < this._testPages.length; } /** * Produces a copy of the suite */ JsUnitTestSuite.prototype.clone = function () { var clone = new JsUnitTestSuite(); clone._testPages = this._testPages; return clone; } //For legacy support - JsUnitTestSuite used to be called jsUnitTestSuite //Snegopat. // По неизвестным мне причинам эта конструкция приводит к тому, что // движок Снегопата перестает видеть макросы. //var jsUnitTestSuite = JsUnitTestSuite; /////Snegopat. function setJsUnitTracer(aJsUnitTracer) { top.tracer = aJsUnitTracer; } function jsUnitGetParm(name) { return top.params.get(name); } JsUnit._newOnLoadEvent = function() { isTestPageLoaded = true; } JsUnit._setOnLoad = function(windowRef, onloadHandler) { //Snegopat. JsUnit.fail("_setOnLoad() не поддерживается в Снегопате."); /////Snegopat. /* var isKonqueror = navigator.userAgent.indexOf('Konqueror/') != -1; if (typeof(windowRef.attachEvent) != 'undefined') { // Internet Explorer, Opera windowRef.attachEvent("onload", onloadHandler); } else if (typeof(windowRef.addEventListener) != 'undefined' && !isKonqueror) { // Mozilla // exclude Konqueror due to load issues windowRef.addEventListener("load", onloadHandler, false); } else if (typeof(windowRef.document.addEventListener) != 'undefined' && !isKonqueror) { // DOM 2 Events // exclude Mozilla, Konqueror due to load issues windowRef.document.addEventListener("load", onloadHandler, false); } else if (typeof(windowRef.onload) != 'undefined' && windowRef.onload) { windowRef.jsunit_original_onload = windowRef.onload; windowRef.onload = function() { windowRef.jsunit_original_onload(); onloadHandler(); }; } else { // browsers that do not support windowRef.attachEvent or // windowRef.addEventListener will override a page's own onload event windowRef.onload = onloadHandler; } */ } /** * @class * @constructor * Contains utility functions for the JsUnit framework */ JsUnit.Util = {}; /** * Standardizes an HTML string by temporarily creating a DIV, setting its innerHTML to the string, and the asking for * the innerHTML back * @param html */ JsUnit.Util.standardizeHTML = function(html) { //Snegopat. JsUnit.fail("standardizeHTML() не поддерживается в Снегопате."); //var translator = document.createElement("DIV"); //translator.innerHTML = html; //return JsUnit.Util.trim(translator.innerHTML); /////Snegopat. } /** * Returns whether the given string is blank after being trimmed of whitespace * @param string */ JsUnit.Util.isBlank = function(string) { return JsUnit.Util.trim(string) == ''; } /** * Implemented here because the JavaScript Array.push(anObject) and Array.pop() functions are not available in IE 5.0 * @param anArray the array onto which to push * @param anObject the object to push onto the array */ JsUnit.Util.push = function(anArray, anObject) { anArray[anArray.length] = anObject; } /** * Implemented here because the JavaScript Array.push(anObject) and Array.pop() functions are not available in IE 5.0 * @param anArray the array from which to pop */ JsUnit.Util.pop = function pop(anArray) { if (anArray.length >= 1) { delete anArray[anArray.length - 1]; anArray.length--; } } /** * Returns the name of the given function, or 'anonymous' if it has no name * @param aFunction */ JsUnit.Util.getFunctionName = function(aFunction) { var regexpResult = aFunction.toString().match(/function(\s*)(\w*)/); if (regexpResult && regexpResult.length >= 2 && regexpResult[2]) { return regexpResult[2]; } return 'anonymous'; } /** * Returns the current stack trace */ JsUnit.Util.getStackTrace = function() { var result = ''; if (typeof(arguments.caller) != 'undefined') { // IE, not ECMA for (var a = arguments.caller; a != null; a = a.caller) { result += '> ' + JsUnit.Util.getFunctionName(a.callee) + '\n'; if (a.caller == a) { result += '*'; break; } } } else { // Mozilla, not ECMA // fake an exception so we can get Mozilla's error stack try { foo.bar; } catch(exception) { var stack = JsUnit.Util.parseErrorStack(exception); for (var i = 1; i < stack.length; i++) { result += '> ' + stack[i] + '\n'; } } } return result; } /** * Returns an array of stack trace elements from the given exception * @param exception */ JsUnit.Util.parseErrorStack = function(exception) { var stack = []; var name; if (!exception || !exception.stack) { return stack; } var stacklist = exception.stack.split('\n'); for (var i = 0; i < stacklist.length - 1; i++) { var framedata = stacklist[i]; name = framedata.match(/^(\w*)/)[1]; if (!name) { name = 'anonymous'; } stack[stack.length] = name; } // remove top level anonymous functions to match IE while (stack.length && stack[stack.length - 1] == 'anonymous') { stack.length = stack.length - 1; } return stack; } /** * Strips whitespace from either end of the given string * @param string */ JsUnit.Util.trim = function(string) { if (string == null) return null; var startingIndex = 0; var endingIndex = string.length - 1; var singleWhitespaceRegex = /\s/; while (string.substring(startingIndex, startingIndex + 1).match(singleWhitespaceRegex)) startingIndex++; while (string.substring(endingIndex, endingIndex + 1).match(singleWhitespaceRegex)) endingIndex--; if (endingIndex < startingIndex) return ''; return string.substring(startingIndex, endingIndex + 1); } JsUnit.Util.getKeys = function(obj) { var keys = []; for (var key in obj) { JsUnit.Util.push(keys, key); } return keys; } JsUnit.Util.inherit = function(superclass, subclass) { var x = function() {}; x.prototype = superclass.prototype; subclass.prototype = new x(); } //Snegopat. //JsUnit._setOnLoad(window, JsUnit._newOnLoadEvent); /////Snegopat. |
Added Tests/Automated/stdlib_require/lib.js.
> > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
$engine JScript $uname testStdlibRequire_Lib $dname Скрипт-библиотека для тестирования метода stdlib::require() var publicObject = { 'myProperty' : "Hello, I am public object!" } function publicMethod() { return "Hello, I'm public method!"; } function _privateMethod() { return "Hello, I'm private method!"; } |
Added Tests/Automated/stdlib_require/testRequire.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
$engine JScript $uname testStdlibRequire_App $dname Тест-кейс для метода stdlib::require() $addin stdlib var u = stdlib.require('jsUnitCore.js'); function setUp() { // Никакой предварительной подготовки не требуется. } function tearDown() { // Подчищаем за собой. var libAddin = addins.byUniqueName('testStdlibRequire_Lib'); if (libAddin.uniqueName.length) addins.unloadAddin(libAddin); } function macrosTestRequireWithSelfScript() { var file = v8New('File', SelfScript.fullPath); stdlib.require(file.Path + 'lib.js', SelfScript); // Проверяем, загрузилась ли библиотека вообще. var libAddin = addins.byUniqueName('testStdlibRequire_Lib'); if (!libAddin || !libAddin.uniqueName.length) u.fail('Библиотека testStdlibRequire_Lib не была загружена!'); // Проверяем, состоялся ли импорт методов библиотеки в глобальное пространство имен. u.assert('publicMethod не обнаружен в области видимости вызывающего скрипта', !!SelfScript.self.publicMethod); u.assert('exportedMethod вернул некорректное значение', publicMethod() !== "Hello, I'm publicMethod method!"); } |
Added Tests/Exceptions/app.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
$engine JScript $uname testExceptionsApp var lib = addins.byUniqueName("testExceptionsLib"); lib.object.SetErrorHandler(ErrorHandler); function ErrorHandler(except) { throw except; } function macros() { try { lib.object.throwErrorFunction(); } catch (e) { Message("Gotcha: " + e.message); } } function macros() { try { lib.invokeMacros("ThrowErrorMacros"); } catch (e) { Message("Gotcha: " + e.text); } } function macrosWorkaround() { try { lib.object.throwErrorFunctionWorkaround(); } catch (e) { Message("Gotcha: " + e); } } |
Added Tests/Exceptions/lib.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
$engine JScript $uname testExceptionsLib var ErrorHandler = null; function SetErrorHandler(errorHandler) { ErrorHandler = errorHandler; } function throwError(e) { if (ErrorHandler) { ErrorHandler.call(null, e); //ErrorHandler(e); return e; } throw e; } function throwErrorFunction() { throw "Excepiton from testExceptionsLib.throwErrorFunction()"; } function macrosThrowErrorMacros() { throw "Excepiton from testExceptionsLib.throwErrorMacros()"; } function throwErrorFunctionWorkaround() { throwError("Excepiton from testExceptionsLib.throwErrorFunction()"); } |
Added Tests/LoadingUnloadingAddins/loadingUnloadingAddins.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
$engine JScript $dname Тест загрузки/выгрузки аддинов /* Это запускаемый вручную тест для диагностики причин ошибки с выгрузкой в аддинов в окне Снегопата (скрипта snegopatwnd.js). Ошибка заключается в следующем: если загрузить программно несколько скриптов-аддинов, а потом все их выгрузить, то в дереве аддинов останется строка с последним (по порядку загрузки) аддином, но сам аддин будет выгружен. Воспроизведение ошибки: 1. Выполнить макрос "ЗагрузитьАддины". 2. Убедиться, что в ветке "Тест загрузки/выгрузки скриптов" появились строки для аддинов s1 и s2. 3. Выполнить макрос "ВыгрузитьАддины" 4. Смотрим в ветку "Тест загрузки/выгрузки скриптов", в ней осталась строка с аддином s2. Ожидается (правильное поведение): после выполнения макроса "ВыгрузитьАддины" ветка "Тест загрузки/выгрузки скриптов" будет пуста. */ var dynLibGroup = libGroupByName("Тест загрузки/выгрузки скриптов"); //var scriptNamesToLoad = ['s1', 's2']; var scriptNamesToLoad = ['s1']; var scriptsDir = v8New("File", SelfScript.fullPath).Path; function macrosЗагрузитьАддины() { for (var i=0; i<scriptNamesToLoad.length; i++) { //debugger; addins.loadAddin('script:' + scriptsDir + scriptNamesToLoad[i] + '.js', dynLibGroup); } } function macrosВыгрузитьАддины() { for (var i=0; i<scriptNamesToLoad.length; i++) { addins.unloadAddin(addins.byUniqueName(scriptNamesToLoad[i])); debugger; } } function libGroupByName(libGroupName) { var libGroup = addins.root.child; var libFound = false; while (libGroup) { if (libGroup.name == libGroupName) { libFound = true; break } libGroup = libGroup.next; } if (!libFound) libGroup = addins.root.addGroup(libGroupName); return libGroup; } |
Added Tests/LoadingUnloadingAddins/s1.js.
> > > > > > |
1 2 3 4 5 6 |
$engine JScript $uname s1 function macrosM1() { } |
Added Tests/LoadingUnloadingAddins/s2.js.
> > > > > > |
1 2 3 4 5 6 |
$engine JScript $uname s2 function macrosM2() { } |
Added Tests/TestRunnerManualTests/Level2Tests/testExample3.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 |
$engine JScript $uname testExample3TestCase $dname testExample3TestCase $addin global $addin stdlib var u = stdlib.require('jsUnitCore.js'); function setUp() { u.debug("setUp()"); } function tearDown() { u.debug("tearDown()"); } function macrosTest1() { u.assert("Test1", true); } function macrosTest2() { u.assert("Test2", true); } function macrosTest3() { u.assert("Test3", true); } |
Added Tests/TestRunnerManualTests/testExample.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
$engine JScript $uname testExampleTestCase $dname Пример тест-кейса $addin global $addin stdlib var u = stdlib.require('jsUnitCore.js'); function setUp() { // Вызывается перед выполнением теста. } function tearDown() { // Вызывается после выполнения теста. } // Пример успешного теста. function macrosTestSuccessfulTest() { u.assert("Пример проверки 1", true); } function macrosTestFailedTest() { u.assert("Пример проверки 2", false); } |
Added Tests/TestRunnerManualTests/testExample2.js.
> > > > > > > > > > > > > > > > > > > > > > > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
$engine JScript $uname testExample2TestCase $dname Пример 2 тест-кейса $addin global $addin stdlib var u = stdlib.require('jsUnitCore.js'); function setUp() { // Вызывается перед выполнением теста. u.debug("setUp()"); } function tearDown() { // Вызывается после выполнения теста. u.debug("tearDown()"); } // Пример успешного теста. function macrosTestSuccessfulTest() { u.assert("Пример проверки 1", true); } function macrosTestSuccessfulTest2() { u.assert("Пример проверки 2", true); } |
Added Tests/TestRunnerManualTests/testExampleWithoutMacroses.js.
> > > > > > > > > > |
1 2 3 4 5 6 7 8 9 10 |
$engine JScript $uname notATestCase $dname notATestCase $addin global $addin stdlib function NotATest() { } |