@magnit-ce/code-tests 0.0.1 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -24,6 +24,7 @@ __export(code_tests_exports, {
24
24
  AFTEREACH: () => AFTEREACH,
25
25
  BEFOREALL: () => BEFOREALL,
26
26
  BEFOREEACH: () => BEFOREEACH,
27
+ CodeTestEventType: () => CodeTestEventType,
27
28
  CodeTests: () => CodeTests,
28
29
  CodeTestsElement: () => CodeTestsElement,
29
30
  expect: () => expect
@@ -264,9 +265,10 @@ summary::before
264
265
  {
265
266
  border: var(--border-success);
266
267
  background: var(--surface-success)
267
- url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24"><path fill="%232e943a" d="M20.285 2l-11.285 11.567-5.286-5.011-3.714 3.716 9 8.728 15-15.285z"/></svg>');
268
+ url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="%232e943a" d="M20.285 2l-11.285 11.567-5.286-5.011-3.714 3.716 9 8.728 15-15.285z"/></svg>');
268
269
  background-repeat: no-repeat;
269
270
  background-position: center;
271
+ background-size: 16px 16px;
270
272
  }
271
273
  .test.fail .result-icon
272
274
  ,.hook.fail .result-icon
@@ -469,7 +471,27 @@ function expect(value) {
469
471
  return CodeTests.expect(value);
470
472
  }
471
473
 
474
+ // node_modules/.pnpm/ce-part-utils@0.0.0/node_modules/ce-part-utils/dist/ce-part-utils.js
475
+ var DEFAULT_ELEMENT_SELECTOR = ":not(slot,defs,g,rect,path,circle,ellipse,line,polygon,text,tspan,use,svg image,svg title,desc,template,template *)";
476
+ function assignClassAndIdToPart(shadowRoot) {
477
+ const identifiedElements = [...shadowRoot.querySelectorAll(`${DEFAULT_ELEMENT_SELECTOR}[id]`)];
478
+ for (let i = 0; i < identifiedElements.length; i++) {
479
+ identifiedElements[i].part.add(identifiedElements[i].id);
480
+ }
481
+ const classedElements = [...shadowRoot.querySelectorAll(`${DEFAULT_ELEMENT_SELECTOR}[class]`)];
482
+ for (let i = 0; i < classedElements.length; i++) {
483
+ classedElements[i].part.add(...classedElements[i].classList);
484
+ }
485
+ }
486
+
472
487
  // src/code-tests.ts
488
+ var CodeTestEventType = /* @__PURE__ */ ((CodeTestEventType2) => {
489
+ CodeTestEventType2["BeforeAll"] = "beforeall";
490
+ CodeTestEventType2["AfterAll"] = "afterall";
491
+ CodeTestEventType2["BeforeTest"] = "beforetest";
492
+ CodeTestEventType2["AfterTest"] = "aftertest";
493
+ return CodeTestEventType2;
494
+ })(CodeTestEventType || {});
473
495
  var NOTESTDEFINED = Symbol("No Test Defined");
474
496
  var COMPONENT_STYLESHEET = new CSSStyleSheet();
475
497
  COMPONENT_STYLESHEET.replaceSync(code_tests_default);
@@ -510,6 +532,7 @@ var CodeTestsElement = class extends HTMLElement {
510
532
  return;
511
533
  }
512
534
  this.loadTests(testsPath);
535
+ assignClassAndIdToPart(this.shadowRoot);
513
536
  }
514
537
  disconnectedCallback() {
515
538
  this.removeEventListener("click", this.#boundClickHandler);
@@ -539,9 +562,11 @@ var CodeTestsElement = class extends HTMLElement {
539
562
  this.#runTest(testId, test);
540
563
  }
541
564
  async loadTests(path) {
542
- this.classList.remove("has-before-hook");
543
- this.classList.remove("has-after-hook");
544
565
  try {
566
+ this.getElement("tests").innerHTML = "";
567
+ this.#tests.clear();
568
+ this.classList.remove("has-before-hook");
569
+ this.classList.remove("has-after-hook");
545
570
  const lastSlashIndexInCurrentPath = window.location.href.lastIndexOf("/");
546
571
  const currentPathHasExtension = window.location.href.substring(lastSlashIndexInCurrentPath).indexOf(".") != -1;
547
572
  const currentPath = currentPathHasExtension == true ? window.location.href.substring(0, lastSlashIndexInCurrentPath + 1) : window.location.href;
@@ -638,6 +663,7 @@ var CodeTestsElement = class extends HTMLElement {
638
663
  }
639
664
  }
640
665
  async runTests() {
666
+ this.dispatchEvent(new CustomEvent("beforeall" /* BeforeAll */, { bubbles: true, composed: true }));
641
667
  this.#continueRunningTests = true;
642
668
  this.classList.add("running");
643
669
  this.toggleAttribute("success", false);
@@ -647,17 +673,15 @@ var CodeTestsElement = class extends HTMLElement {
647
673
  if (beforeHooks != null) {
648
674
  let hookResult;
649
675
  try {
650
- const hookElement = this.getElement(`before-all-details`);
651
- hookElement.toggleAttribute("success", false);
652
- hookElement.classList.add("running");
653
- hookElement.part.add("running");
654
- hookElement.classList.remove("success", "fail");
655
- hookElement.part.remove("success", "fail");
676
+ const beforeAllHookElement = this.getElement(`before-all-details`);
677
+ beforeAllHookElement.classList.add("running");
678
+ beforeAllHookElement.part.add("running");
656
679
  for (const [hook, ids] of beforeHooks) {
657
680
  hookResult = await hook();
658
681
  this.#handleHookResult(hookResult, true, "before");
659
682
  }
660
- hookElement.part.remove("running");
683
+ beforeAllHookElement.part.remove("running");
684
+ beforeAllHookElement.classList.remove("running");
661
685
  } catch (error) {
662
686
  this.#handleHookResult(hookResult, false, "before", error);
663
687
  console.error(error);
@@ -686,17 +710,15 @@ var CodeTestsElement = class extends HTMLElement {
686
710
  if (afterHooks != null) {
687
711
  let hookResult;
688
712
  try {
689
- const hookElement = this.getElement(`after-all-details`);
690
- hookElement.toggleAttribute("success", false);
691
- hookElement.classList.add("running");
692
- hookElement.part.add("running");
693
- hookElement.classList.remove("success", "fail");
694
- hookElement.part.remove("success", "fail");
713
+ const afterAllHookElement = this.getElement(`after-all-details`);
714
+ afterAllHookElement.classList.add("running");
715
+ afterAllHookElement.part.add("running");
695
716
  for (const [hook, ids] of afterHooks) {
696
717
  hookResult = await hook();
697
718
  this.#handleHookResult(hookResult, true, "after");
698
719
  }
699
- hookElement.part.remove("running");
720
+ afterAllHookElement.part.remove("running");
721
+ afterAllHookElement.classList.remove("running");
700
722
  } catch (error) {
701
723
  this.#handleHookResult(hookResult, false, "after", error);
702
724
  console.error(error);
@@ -707,6 +729,8 @@ var CodeTestsElement = class extends HTMLElement {
707
729
  const failedTests = this.shadowRoot.querySelectorAll('[success="false"]');
708
730
  this.setAttribute("success", failedTests.length == 0 ? "true" : "false");
709
731
  this.classList.remove("running");
732
+ this.part.remove("running");
733
+ this.dispatchEvent(new CustomEvent("afterall" /* AfterAll */, { bubbles: true, composed: true }));
710
734
  }
711
735
  #clearTestStatuses() {
712
736
  for (const [testId, test] of this.#tests) {
@@ -719,6 +743,14 @@ var CodeTestsElement = class extends HTMLElement {
719
743
  testElement.classList.remove("success", "fail");
720
744
  testElement.part.remove("success", "fail");
721
745
  }
746
+ const beforeAllHookElement = this.getElement(`before-all-details`);
747
+ beforeAllHookElement.toggleAttribute("success", false);
748
+ beforeAllHookElement.classList.remove("success", "fail");
749
+ beforeAllHookElement.part.remove("success", "fail");
750
+ const afterAllHookElement = this.getElement(`after-all-details`);
751
+ afterAllHookElement.toggleAttribute("success", false);
752
+ afterAllHookElement.classList.remove("success", "fail");
753
+ afterAllHookElement.part.remove("success", "fail");
722
754
  }
723
755
  async #runTest(testId, test) {
724
756
  const testElement = this.getElement("tests").querySelector(`[data-test-id="${testId}"]`);
@@ -731,6 +763,11 @@ var CodeTestsElement = class extends HTMLElement {
731
763
  testElement.part.add("running");
732
764
  testElement.classList.remove("success", "fail");
733
765
  testElement.part.remove("success", "fail");
766
+ const iconElement = testElement.querySelector(".result-icon");
767
+ iconElement?.classList.remove("success", "fail");
768
+ iconElement?.part.remove("success", "fail");
769
+ iconElement?.classList.add("running");
770
+ iconElement?.part.add("running");
734
771
  const errorMessageElement = testElement.querySelector(".error-message");
735
772
  if (errorMessageElement != null) {
736
773
  errorMessageElement.textContent = "";
@@ -744,34 +781,37 @@ var CodeTestsElement = class extends HTMLElement {
744
781
  let afterResult = NOTESTDEFINED;
745
782
  let testType;
746
783
  try {
747
- const beforeHooks = this.#hooks.get(BEFOREEACH);
748
- if (beforeHooks != null) {
749
- for (const [hook, ids] of beforeHooks) {
750
- if (ids.has(testId)) {
751
- beforeResult = await hook();
752
- break;
784
+ const allowTest = this.dispatchEvent(new CustomEvent("beforetest" /* BeforeTest */, { bubbles: true, cancelable: true, composed: true, detail: { testElement } }));
785
+ if (allowTest == true) {
786
+ const beforeHooks = this.#hooks.get(BEFOREEACH);
787
+ if (beforeHooks != null) {
788
+ for (const [hook, ids] of beforeHooks) {
789
+ if (ids.has(testId)) {
790
+ beforeResult = await hook();
791
+ break;
792
+ }
753
793
  }
754
794
  }
755
- }
756
- testResult = await test();
757
- const afterHooks = this.#hooks.get(AFTEREACH);
758
- if (afterHooks != null) {
759
- for (const [hook, ids] of afterHooks) {
760
- if (ids.has(testId)) {
761
- afterResult = await hook();
762
- break;
795
+ testResult = await test();
796
+ const afterHooks = this.#hooks.get(AFTEREACH);
797
+ if (afterHooks != null) {
798
+ for (const [hook, ids] of afterHooks) {
799
+ if (ids.has(testId)) {
800
+ afterResult = await hook();
801
+ break;
802
+ }
763
803
  }
764
804
  }
765
- }
766
- testType = "before";
767
- if (beforeResult != NOTESTDEFINED) {
768
- this.#handleTestResult(testElement, beforeResult, true, void 0, testType);
769
- }
770
- testType = void 0;
771
- this.#handleTestResult(testElement, testResult, true, void 0, testType);
772
- testType = "after";
773
- if (afterResult != NOTESTDEFINED) {
774
- this.#handleTestResult(testElement, afterResult, true, void 0, testType);
805
+ testType = "before";
806
+ if (beforeResult != NOTESTDEFINED) {
807
+ this.#handleTestResult(testElement, beforeResult, true, void 0, testType);
808
+ }
809
+ testType = void 0;
810
+ this.#handleTestResult(testElement, testResult, true, void 0, testType);
811
+ testType = "after";
812
+ if (afterResult != NOTESTDEFINED) {
813
+ this.#handleTestResult(testElement, afterResult, true, void 0, testType);
814
+ }
775
815
  }
776
816
  } catch (error) {
777
817
  this.#handleTestResult(testElement, testResult, false, error, testType);
@@ -779,6 +819,10 @@ var CodeTestsElement = class extends HTMLElement {
779
819
  this.#continueRunningTests = false;
780
820
  } finally {
781
821
  testElement?.classList.remove("running");
822
+ testElement?.part.remove("running");
823
+ iconElement?.classList.remove("running");
824
+ iconElement?.part.remove("running");
825
+ this.dispatchEvent(new CustomEvent("aftertest" /* AfterTest */, { bubbles: true, cancelable: true, composed: true, detail: { testElement } }));
782
826
  }
783
827
  }
784
828
  #handleTestResult(testElement, result, finishedTest, error, beforeOrAfter) {
@@ -861,12 +905,16 @@ Result:${objectResult.value}`,
861
905
  const testElement = document.createElement("li");
862
906
  testElement.dataset.testId = testId;
863
907
  testElement.classList.add("test");
908
+ testElement.part.add("test");
864
909
  const detailsElement = document.createElement("details");
865
910
  detailsElement.classList.add("test-details");
911
+ detailsElement.part.add("test-details");
866
912
  const summaryElement = document.createElement("summary");
867
913
  summaryElement.classList.add("test-summary");
914
+ summaryElement.part.add("test-summary");
868
915
  const resultIcon = document.createElement("div");
869
916
  resultIcon.classList.add("result-icon");
917
+ resultIcon.part.add("result-icon");
870
918
  summaryElement.append(resultIcon);
871
919
  const descriptionElement = document.createElement("span");
872
920
  descriptionElement.classList.add("description", "test-description");
@@ -874,15 +922,19 @@ Result:${objectResult.value}`,
874
922
  summaryElement.append(descriptionElement);
875
923
  const runButton = document.createElement("button");
876
924
  runButton.classList.add("run", "test-run");
925
+ runButton.part.add("run", "test-run");
877
926
  runButton.textContent = "Run Test";
878
927
  runButton.title = "Run Test";
879
928
  summaryElement.append(runButton);
880
929
  const beforeResultElement = document.createElement("div");
881
930
  beforeResultElement.classList.add("before-result", "test-before-result");
931
+ beforeResultElement.part.add("before-result", "test-before-result");
882
932
  const resultElement = document.createElement("div");
883
933
  resultElement.classList.add("result", "test-result");
934
+ resultElement.part.add("result", "test-result");
884
935
  const afterResultElement = document.createElement("div");
885
936
  afterResultElement.classList.add("after-result", "test-after-result");
937
+ afterResultElement.part.add("after-result", "test-after-result");
886
938
  detailsElement.append(summaryElement);
887
939
  detailsElement.append(beforeResultElement);
888
940
  detailsElement.append(resultElement);
@@ -896,6 +948,11 @@ Result:${objectResult.value}`,
896
948
  testElement.part.toggle("success", success);
897
949
  testElement.classList.toggle("fail", !success);
898
950
  testElement.part.toggle("fail", !success);
951
+ const iconElement = testElement.querySelector(".result-icon");
952
+ iconElement?.classList.toggle("success", success);
953
+ iconElement?.part.toggle("success", success);
954
+ iconElement?.classList.toggle("fail", !success);
955
+ iconElement?.part.toggle("fail", !success);
899
956
  const resultElement = testElement.querySelector(`.${beforeOrAfter == void 0 ? "result" : beforeOrAfter == "before" ? "before-result" : "after-result"}`);
900
957
  if (resultElement == null) {
901
958
  this.#addProcessError(`Unable to find result element`);
@@ -906,9 +963,13 @@ Result:${objectResult.value}`,
906
963
  }
907
964
  #createDefaultResult(message, success, beforeOrAfter) {
908
965
  const codeElement = document.createElement("code");
966
+ codeElement.classList.add("code");
967
+ codeElement.part.add("code");
909
968
  const preElement = document.createElement("pre");
910
969
  preElement.textContent = message;
911
- preElement.classList.add(success == true ? "success-message" : "error-message");
970
+ const className = success == true ? "success-message" : "error-message";
971
+ preElement.classList.add("pre", className);
972
+ preElement.part.add("pre", className);
912
973
  codeElement.appendChild(preElement);
913
974
  return codeElement;
914
975
  }
@@ -930,8 +991,14 @@ ${error.message}`;
930
991
  console.error(error);
931
992
  }
932
993
  const errorElement = document.createElement("li");
994
+ errorElement.classList.add("error", "process-error");
995
+ errorElement.part.add("error", "process-error");
933
996
  const codeElement = document.createElement("code");
997
+ codeElement.classList.add("code", "process-error-code");
998
+ codeElement.part.add("code", "process-error-code");
934
999
  const preElement = document.createElement("pre");
1000
+ preElement.classList.add("pre", "process-error-pre");
1001
+ preElement.part.add("pre", "process-error-pre");
935
1002
  preElement.textContent = message;
936
1003
  codeElement.append(preElement);
937
1004
  errorElement.append(codeElement);
@@ -993,6 +1060,7 @@ if (customElements.get(COMPONENT_TAG_NAME) == null) {
993
1060
  AFTEREACH,
994
1061
  BEFOREALL,
995
1062
  BEFOREEACH,
1063
+ CodeTestEventType,
996
1064
  CodeTests,
997
1065
  CodeTestsElement,
998
1066
  expect
@@ -18,6 +18,12 @@ declare class CodeTests {
18
18
  declare function expect(value: any): TestPromise<any>;
19
19
 
20
20
  type CodeTestsProperties = {};
21
+ declare enum CodeTestEventType {
22
+ BeforeAll = "beforeall",
23
+ AfterAll = "afterall",
24
+ BeforeTest = "beforetest",
25
+ AfterTest = "aftertest"
26
+ }
21
27
  declare class CodeTestsElement extends HTMLElement {
22
28
  #private;
23
29
  componentParts: Map<string, HTMLElement>;
@@ -33,4 +39,4 @@ declare class CodeTestsElement extends HTMLElement {
33
39
  attributeChangedCallback(attributeName: string, oldValue: string, newValue: string): void;
34
40
  }
35
41
 
36
- export { AFTERALL, AFTEREACH, BEFOREALL, BEFOREEACH, CodeTests, CodeTestsElement, type CodeTestsProperties, expect };
42
+ export { AFTERALL, AFTEREACH, BEFOREALL, BEFOREEACH, CodeTestEventType, CodeTests, CodeTestsElement, type CodeTestsProperties, expect };
@@ -18,6 +18,12 @@ declare class CodeTests {
18
18
  declare function expect(value: any): TestPromise<any>;
19
19
 
20
20
  type CodeTestsProperties = {};
21
+ declare enum CodeTestEventType {
22
+ BeforeAll = "beforeall",
23
+ AfterAll = "afterall",
24
+ BeforeTest = "beforetest",
25
+ AfterTest = "aftertest"
26
+ }
21
27
  declare class CodeTestsElement extends HTMLElement {
22
28
  #private;
23
29
  componentParts: Map<string, HTMLElement>;
@@ -33,4 +39,4 @@ declare class CodeTestsElement extends HTMLElement {
33
39
  attributeChangedCallback(attributeName: string, oldValue: string, newValue: string): void;
34
40
  }
35
41
 
36
- export { AFTERALL, AFTEREACH, BEFOREALL, BEFOREEACH, CodeTests, CodeTestsElement, type CodeTestsProperties, expect };
42
+ export { AFTERALL, AFTEREACH, BEFOREALL, BEFOREEACH, CodeTestEventType, CodeTests, CodeTestsElement, type CodeTestsProperties, expect };
@@ -232,9 +232,10 @@ summary::before
232
232
  {
233
233
  border: var(--border-success);
234
234
  background: var(--surface-success)
235
- url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24"><path fill="%232e943a" d="M20.285 2l-11.285 11.567-5.286-5.011-3.714 3.716 9 8.728 15-15.285z"/></svg>');
235
+ url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="%232e943a" d="M20.285 2l-11.285 11.567-5.286-5.011-3.714 3.716 9 8.728 15-15.285z"/></svg>');
236
236
  background-repeat: no-repeat;
237
237
  background-position: center;
238
+ background-size: 16px 16px;
238
239
  }
239
240
  .test.fail .result-icon
240
241
  ,.hook.fail .result-icon
@@ -437,7 +438,27 @@ function expect(value) {
437
438
  return CodeTests.expect(value);
438
439
  }
439
440
 
441
+ // node_modules/.pnpm/ce-part-utils@0.0.0/node_modules/ce-part-utils/dist/ce-part-utils.js
442
+ var DEFAULT_ELEMENT_SELECTOR = ":not(slot,defs,g,rect,path,circle,ellipse,line,polygon,text,tspan,use,svg image,svg title,desc,template,template *)";
443
+ function assignClassAndIdToPart(shadowRoot) {
444
+ const identifiedElements = [...shadowRoot.querySelectorAll(`${DEFAULT_ELEMENT_SELECTOR}[id]`)];
445
+ for (let i = 0; i < identifiedElements.length; i++) {
446
+ identifiedElements[i].part.add(identifiedElements[i].id);
447
+ }
448
+ const classedElements = [...shadowRoot.querySelectorAll(`${DEFAULT_ELEMENT_SELECTOR}[class]`)];
449
+ for (let i = 0; i < classedElements.length; i++) {
450
+ classedElements[i].part.add(...classedElements[i].classList);
451
+ }
452
+ }
453
+
440
454
  // src/code-tests.ts
455
+ var CodeTestEventType = /* @__PURE__ */ ((CodeTestEventType2) => {
456
+ CodeTestEventType2["BeforeAll"] = "beforeall";
457
+ CodeTestEventType2["AfterAll"] = "afterall";
458
+ CodeTestEventType2["BeforeTest"] = "beforetest";
459
+ CodeTestEventType2["AfterTest"] = "aftertest";
460
+ return CodeTestEventType2;
461
+ })(CodeTestEventType || {});
441
462
  var NOTESTDEFINED = Symbol("No Test Defined");
442
463
  var COMPONENT_STYLESHEET = new CSSStyleSheet();
443
464
  COMPONENT_STYLESHEET.replaceSync(code_tests_default);
@@ -478,6 +499,7 @@ var CodeTestsElement = class extends HTMLElement {
478
499
  return;
479
500
  }
480
501
  this.loadTests(testsPath);
502
+ assignClassAndIdToPart(this.shadowRoot);
481
503
  }
482
504
  disconnectedCallback() {
483
505
  this.removeEventListener("click", this.#boundClickHandler);
@@ -507,9 +529,11 @@ var CodeTestsElement = class extends HTMLElement {
507
529
  this.#runTest(testId, test);
508
530
  }
509
531
  async loadTests(path) {
510
- this.classList.remove("has-before-hook");
511
- this.classList.remove("has-after-hook");
512
532
  try {
533
+ this.getElement("tests").innerHTML = "";
534
+ this.#tests.clear();
535
+ this.classList.remove("has-before-hook");
536
+ this.classList.remove("has-after-hook");
513
537
  const lastSlashIndexInCurrentPath = window.location.href.lastIndexOf("/");
514
538
  const currentPathHasExtension = window.location.href.substring(lastSlashIndexInCurrentPath).indexOf(".") != -1;
515
539
  const currentPath = currentPathHasExtension == true ? window.location.href.substring(0, lastSlashIndexInCurrentPath + 1) : window.location.href;
@@ -606,6 +630,7 @@ var CodeTestsElement = class extends HTMLElement {
606
630
  }
607
631
  }
608
632
  async runTests() {
633
+ this.dispatchEvent(new CustomEvent("beforeall" /* BeforeAll */, { bubbles: true, composed: true }));
609
634
  this.#continueRunningTests = true;
610
635
  this.classList.add("running");
611
636
  this.toggleAttribute("success", false);
@@ -615,17 +640,15 @@ var CodeTestsElement = class extends HTMLElement {
615
640
  if (beforeHooks != null) {
616
641
  let hookResult;
617
642
  try {
618
- const hookElement = this.getElement(`before-all-details`);
619
- hookElement.toggleAttribute("success", false);
620
- hookElement.classList.add("running");
621
- hookElement.part.add("running");
622
- hookElement.classList.remove("success", "fail");
623
- hookElement.part.remove("success", "fail");
643
+ const beforeAllHookElement = this.getElement(`before-all-details`);
644
+ beforeAllHookElement.classList.add("running");
645
+ beforeAllHookElement.part.add("running");
624
646
  for (const [hook, ids] of beforeHooks) {
625
647
  hookResult = await hook();
626
648
  this.#handleHookResult(hookResult, true, "before");
627
649
  }
628
- hookElement.part.remove("running");
650
+ beforeAllHookElement.part.remove("running");
651
+ beforeAllHookElement.classList.remove("running");
629
652
  } catch (error) {
630
653
  this.#handleHookResult(hookResult, false, "before", error);
631
654
  console.error(error);
@@ -654,17 +677,15 @@ var CodeTestsElement = class extends HTMLElement {
654
677
  if (afterHooks != null) {
655
678
  let hookResult;
656
679
  try {
657
- const hookElement = this.getElement(`after-all-details`);
658
- hookElement.toggleAttribute("success", false);
659
- hookElement.classList.add("running");
660
- hookElement.part.add("running");
661
- hookElement.classList.remove("success", "fail");
662
- hookElement.part.remove("success", "fail");
680
+ const afterAllHookElement = this.getElement(`after-all-details`);
681
+ afterAllHookElement.classList.add("running");
682
+ afterAllHookElement.part.add("running");
663
683
  for (const [hook, ids] of afterHooks) {
664
684
  hookResult = await hook();
665
685
  this.#handleHookResult(hookResult, true, "after");
666
686
  }
667
- hookElement.part.remove("running");
687
+ afterAllHookElement.part.remove("running");
688
+ afterAllHookElement.classList.remove("running");
668
689
  } catch (error) {
669
690
  this.#handleHookResult(hookResult, false, "after", error);
670
691
  console.error(error);
@@ -675,6 +696,8 @@ var CodeTestsElement = class extends HTMLElement {
675
696
  const failedTests = this.shadowRoot.querySelectorAll('[success="false"]');
676
697
  this.setAttribute("success", failedTests.length == 0 ? "true" : "false");
677
698
  this.classList.remove("running");
699
+ this.part.remove("running");
700
+ this.dispatchEvent(new CustomEvent("afterall" /* AfterAll */, { bubbles: true, composed: true }));
678
701
  }
679
702
  #clearTestStatuses() {
680
703
  for (const [testId, test] of this.#tests) {
@@ -687,6 +710,14 @@ var CodeTestsElement = class extends HTMLElement {
687
710
  testElement.classList.remove("success", "fail");
688
711
  testElement.part.remove("success", "fail");
689
712
  }
713
+ const beforeAllHookElement = this.getElement(`before-all-details`);
714
+ beforeAllHookElement.toggleAttribute("success", false);
715
+ beforeAllHookElement.classList.remove("success", "fail");
716
+ beforeAllHookElement.part.remove("success", "fail");
717
+ const afterAllHookElement = this.getElement(`after-all-details`);
718
+ afterAllHookElement.toggleAttribute("success", false);
719
+ afterAllHookElement.classList.remove("success", "fail");
720
+ afterAllHookElement.part.remove("success", "fail");
690
721
  }
691
722
  async #runTest(testId, test) {
692
723
  const testElement = this.getElement("tests").querySelector(`[data-test-id="${testId}"]`);
@@ -699,6 +730,11 @@ var CodeTestsElement = class extends HTMLElement {
699
730
  testElement.part.add("running");
700
731
  testElement.classList.remove("success", "fail");
701
732
  testElement.part.remove("success", "fail");
733
+ const iconElement = testElement.querySelector(".result-icon");
734
+ iconElement?.classList.remove("success", "fail");
735
+ iconElement?.part.remove("success", "fail");
736
+ iconElement?.classList.add("running");
737
+ iconElement?.part.add("running");
702
738
  const errorMessageElement = testElement.querySelector(".error-message");
703
739
  if (errorMessageElement != null) {
704
740
  errorMessageElement.textContent = "";
@@ -712,34 +748,37 @@ var CodeTestsElement = class extends HTMLElement {
712
748
  let afterResult = NOTESTDEFINED;
713
749
  let testType;
714
750
  try {
715
- const beforeHooks = this.#hooks.get(BEFOREEACH);
716
- if (beforeHooks != null) {
717
- for (const [hook, ids] of beforeHooks) {
718
- if (ids.has(testId)) {
719
- beforeResult = await hook();
720
- break;
751
+ const allowTest = this.dispatchEvent(new CustomEvent("beforetest" /* BeforeTest */, { bubbles: true, cancelable: true, composed: true, detail: { testElement } }));
752
+ if (allowTest == true) {
753
+ const beforeHooks = this.#hooks.get(BEFOREEACH);
754
+ if (beforeHooks != null) {
755
+ for (const [hook, ids] of beforeHooks) {
756
+ if (ids.has(testId)) {
757
+ beforeResult = await hook();
758
+ break;
759
+ }
721
760
  }
722
761
  }
723
- }
724
- testResult = await test();
725
- const afterHooks = this.#hooks.get(AFTEREACH);
726
- if (afterHooks != null) {
727
- for (const [hook, ids] of afterHooks) {
728
- if (ids.has(testId)) {
729
- afterResult = await hook();
730
- break;
762
+ testResult = await test();
763
+ const afterHooks = this.#hooks.get(AFTEREACH);
764
+ if (afterHooks != null) {
765
+ for (const [hook, ids] of afterHooks) {
766
+ if (ids.has(testId)) {
767
+ afterResult = await hook();
768
+ break;
769
+ }
731
770
  }
732
771
  }
733
- }
734
- testType = "before";
735
- if (beforeResult != NOTESTDEFINED) {
736
- this.#handleTestResult(testElement, beforeResult, true, void 0, testType);
737
- }
738
- testType = void 0;
739
- this.#handleTestResult(testElement, testResult, true, void 0, testType);
740
- testType = "after";
741
- if (afterResult != NOTESTDEFINED) {
742
- this.#handleTestResult(testElement, afterResult, true, void 0, testType);
772
+ testType = "before";
773
+ if (beforeResult != NOTESTDEFINED) {
774
+ this.#handleTestResult(testElement, beforeResult, true, void 0, testType);
775
+ }
776
+ testType = void 0;
777
+ this.#handleTestResult(testElement, testResult, true, void 0, testType);
778
+ testType = "after";
779
+ if (afterResult != NOTESTDEFINED) {
780
+ this.#handleTestResult(testElement, afterResult, true, void 0, testType);
781
+ }
743
782
  }
744
783
  } catch (error) {
745
784
  this.#handleTestResult(testElement, testResult, false, error, testType);
@@ -747,6 +786,10 @@ var CodeTestsElement = class extends HTMLElement {
747
786
  this.#continueRunningTests = false;
748
787
  } finally {
749
788
  testElement?.classList.remove("running");
789
+ testElement?.part.remove("running");
790
+ iconElement?.classList.remove("running");
791
+ iconElement?.part.remove("running");
792
+ this.dispatchEvent(new CustomEvent("aftertest" /* AfterTest */, { bubbles: true, cancelable: true, composed: true, detail: { testElement } }));
750
793
  }
751
794
  }
752
795
  #handleTestResult(testElement, result, finishedTest, error, beforeOrAfter) {
@@ -829,12 +872,16 @@ Result:${objectResult.value}`,
829
872
  const testElement = document.createElement("li");
830
873
  testElement.dataset.testId = testId;
831
874
  testElement.classList.add("test");
875
+ testElement.part.add("test");
832
876
  const detailsElement = document.createElement("details");
833
877
  detailsElement.classList.add("test-details");
878
+ detailsElement.part.add("test-details");
834
879
  const summaryElement = document.createElement("summary");
835
880
  summaryElement.classList.add("test-summary");
881
+ summaryElement.part.add("test-summary");
836
882
  const resultIcon = document.createElement("div");
837
883
  resultIcon.classList.add("result-icon");
884
+ resultIcon.part.add("result-icon");
838
885
  summaryElement.append(resultIcon);
839
886
  const descriptionElement = document.createElement("span");
840
887
  descriptionElement.classList.add("description", "test-description");
@@ -842,15 +889,19 @@ Result:${objectResult.value}`,
842
889
  summaryElement.append(descriptionElement);
843
890
  const runButton = document.createElement("button");
844
891
  runButton.classList.add("run", "test-run");
892
+ runButton.part.add("run", "test-run");
845
893
  runButton.textContent = "Run Test";
846
894
  runButton.title = "Run Test";
847
895
  summaryElement.append(runButton);
848
896
  const beforeResultElement = document.createElement("div");
849
897
  beforeResultElement.classList.add("before-result", "test-before-result");
898
+ beforeResultElement.part.add("before-result", "test-before-result");
850
899
  const resultElement = document.createElement("div");
851
900
  resultElement.classList.add("result", "test-result");
901
+ resultElement.part.add("result", "test-result");
852
902
  const afterResultElement = document.createElement("div");
853
903
  afterResultElement.classList.add("after-result", "test-after-result");
904
+ afterResultElement.part.add("after-result", "test-after-result");
854
905
  detailsElement.append(summaryElement);
855
906
  detailsElement.append(beforeResultElement);
856
907
  detailsElement.append(resultElement);
@@ -864,6 +915,11 @@ Result:${objectResult.value}`,
864
915
  testElement.part.toggle("success", success);
865
916
  testElement.classList.toggle("fail", !success);
866
917
  testElement.part.toggle("fail", !success);
918
+ const iconElement = testElement.querySelector(".result-icon");
919
+ iconElement?.classList.toggle("success", success);
920
+ iconElement?.part.toggle("success", success);
921
+ iconElement?.classList.toggle("fail", !success);
922
+ iconElement?.part.toggle("fail", !success);
867
923
  const resultElement = testElement.querySelector(`.${beforeOrAfter == void 0 ? "result" : beforeOrAfter == "before" ? "before-result" : "after-result"}`);
868
924
  if (resultElement == null) {
869
925
  this.#addProcessError(`Unable to find result element`);
@@ -874,9 +930,13 @@ Result:${objectResult.value}`,
874
930
  }
875
931
  #createDefaultResult(message, success, beforeOrAfter) {
876
932
  const codeElement = document.createElement("code");
933
+ codeElement.classList.add("code");
934
+ codeElement.part.add("code");
877
935
  const preElement = document.createElement("pre");
878
936
  preElement.textContent = message;
879
- preElement.classList.add(success == true ? "success-message" : "error-message");
937
+ const className = success == true ? "success-message" : "error-message";
938
+ preElement.classList.add("pre", className);
939
+ preElement.part.add("pre", className);
880
940
  codeElement.appendChild(preElement);
881
941
  return codeElement;
882
942
  }
@@ -898,8 +958,14 @@ ${error.message}`;
898
958
  console.error(error);
899
959
  }
900
960
  const errorElement = document.createElement("li");
961
+ errorElement.classList.add("error", "process-error");
962
+ errorElement.part.add("error", "process-error");
901
963
  const codeElement = document.createElement("code");
964
+ codeElement.classList.add("code", "process-error-code");
965
+ codeElement.part.add("code", "process-error-code");
902
966
  const preElement = document.createElement("pre");
967
+ preElement.classList.add("pre", "process-error-pre");
968
+ preElement.part.add("pre", "process-error-pre");
903
969
  preElement.textContent = message;
904
970
  codeElement.append(preElement);
905
971
  errorElement.append(codeElement);
@@ -960,6 +1026,7 @@ export {
960
1026
  AFTEREACH,
961
1027
  BEFOREALL,
962
1028
  BEFOREEACH,
1029
+ CodeTestEventType,
963
1030
  CodeTests,
964
1031
  CodeTestsElement,
965
1032
  expect
@@ -1,4 +1,4 @@
1
- var H=`:host
1
+ var S=`:host
2
2
  {
3
3
  /*** gray ***/
4
4
  --uchu-light-gray-raw: 95.57% 0.003 286.35;
@@ -231,9 +231,10 @@ summary::before
231
231
  {
232
232
  border: var(--border-success);
233
233
  background: var(--surface-success)
234
- url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24"><path fill="%232e943a" d="M20.285 2l-11.285 11.567-5.286-5.011-3.714 3.716 9 8.728 15-15.285z"/></svg>');
234
+ url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="%232e943a" d="M20.285 2l-11.285 11.567-5.286-5.011-3.714 3.716 9 8.728 15-15.285z"/></svg>');
235
235
  background-repeat: no-repeat;
236
236
  background-position: center;
237
+ background-size: 16px 16px;
237
238
  }
238
239
  .test.fail .result-icon
239
240
  ,.hook.fail .result-icon
@@ -355,7 +356,7 @@ pre
355
356
  {
356
357
  from { transform: rotate(0deg); }
357
358
  to { transform: rotate(360deg); }
358
- }`;var F=`<slot name="header">
359
+ }`;var H=`<slot name="header">
359
360
  <header id="header">
360
361
  <span id="title"><slot name="title"><span id="title-text">Tests</span></slot></span>
361
362
  <slot name="play-button">
@@ -382,15 +383,15 @@ pre
382
383
  <span id="after-all-description" class="description">Results from After All Hook</span>
383
384
  </summary>
384
385
  <div id="after-all-results" class="results"></div>
385
- </details>`;var w=class extends Promise{async toBeDefined(e){if(await this==null)throw new Error(`${e??"Value"} is undefined`)}async toBe(e,s=!1){let t=await this;if((s==!0?t===e:t==e)==!1)throw new Error(` Value is not equal.
386
- Expected: ${e}
387
- Result: ${t}`)}async toContainText(e){let s=await this}async toHaveAttribute(e){let s=await this;if(!(s instanceof HTMLElement))throw new Error("Unable to check for attribute on non-HTMLElement target");if(s.getAttribute(e))throw new Error("Taret does not have attribute")}},b=Symbol("beforeAll"),y=Symbol("beforeEach"),E=Symbol("afterAll"),k=Symbol("afterEach"),R=class{static timeoutMS=500;static#e;static#h;static expect(e){return new w(async(t,a)=>{if(e instanceof Promise){let r=await e;t(r);return}t(e)})}static expectSync(e){return new w(async(t,a)=>{if(e instanceof Promise){let r=await e;t(r);return}t(e)})}static expectBefore(e){return new w(async(t,a)=>{if(e instanceof Promise){let r=await e;t(r);return}t(e)})}};function P(m){return R.expect(m)}var M=Symbol("No Test Defined"),D=new CSSStyleSheet;D.replaceSync(H);var S="code-tests",A=class extends HTMLElement{componentParts=new Map;getElement(e){if(this.componentParts.get(e)==null){let s=this.findElement(e);s!=null&&this.componentParts.set(e,s)}return this.componentParts.get(e)}findElement(e){return this.shadowRoot.getElementById(e)}#e=new Map;#h={[b]:x(),[y]:x(),[k]:x(),[E]:x()};#t=!0;constructor(){super(),this.attachShadow({mode:"open"}),this.shadowRoot.innerHTML=F,this.shadowRoot.adoptedStyleSheets.push(D),this.#u=this.#f.bind(this)}connectedCallback(){this.addEventListener("click",this.#u);let e=this.getAttribute("src")??this.getAttribute("test")??this.getAttribute("tests")??this.getAttribute("run")??this.getAttribute("path");e!=null&&this.loadTests(e)}disconnectedCallback(){this.removeEventListener("click",this.#u)}#u;#f(e){let s=e.composedPath().find(n=>n instanceof HTMLButtonElement&&n.classList.contains("run"));if(s==null)return;let t=s.closest("li");if(t==null){s.hasAttribute("data-all")==!0&&this.runTests();return}let a=t.dataset.testId;if(a==null)return;let r=this.#r.get(a);r!=null&&this.#c(a,r)}async loadTests(e){this.classList.remove("has-before-hook"),this.classList.remove("has-after-hook");try{let s=window.location.href.lastIndexOf("/"),a=window.location.href.substring(s).indexOf(".")!=-1==!0?window.location.href.substring(0,s+1):window.location.href,r=a+e.substring(0,e.lastIndexOf("/")+1),n=a+e,o=await(await fetch(n)).text();o=o.replaceAll(/['"`](((\.\/)|(\.\.\/))+(.*))['"`]/g,`'${r}$1'`);let l=new File([o],e.substring(e.lastIndexOf("/")),{type:"text/javascript"}),u=await import(URL.createObjectURL(l)),d=u.tests??u.default;if(d==null)throw new Error(`Unable to find tests definition in file at path: ${e}`);let p=d[b];if(p!=null){if(this.#e.get(b)==null){let c=new Map;c.set(p,new Set),this.#e.set(b,c)}this.classList.add("has-before-hook")}let g=d[y];if(g!=null&&this.#e.get(y)==null){let c=new Map;c.set(g,new Set),this.#e.set(y,c)}let T=d[E];if(T!=null){if(this.#e.get(E)==null){let c=new Map;c.set(T,new Set),this.#e.set(E,c)}this.classList.add("has-after-hook")}let L=d[k];if(L!=null&&this.#e.get(k)==null){let c=new Map;c.set(L,new Set),this.#e.set(k,c)}for(let[v,c]of Object.entries(d)){let C=this.#g(v,c);if(p!=null){let h=this.#e.get(b);if(h!=null){let f=h.get(p);f?.add(C)}}if(g!=null){let h=this.#e.get(y);if(h!=null){let f=h.get(g);f?.add(C)}}if(T!=null){let h=this.#e.get(E);if(h!=null){let f=h.get(T);f?.add(C)}}if(L!=null){let h=this.#e.get(k);if(h!=null){let f=h.get(L);f?.add(C)}}}}catch(s){this.#i("An error occurred while loading the tasks:",s)}}async runTests(){this.#t=!0,this.classList.add("running"),this.toggleAttribute("success",!1),this.#p();let e=this.hasAttribute("in-order"),s=this.#e.get(b);if(s!=null){let r;try{let n=this.getElement("before-all-details");n.toggleAttribute("success",!1),n.classList.add("running"),n.part.add("running"),n.classList.remove("success","fail"),n.part.remove("success","fail");for(let[o,l]of s)r=await o(),this.#n(r,!0,"before");n.part.remove("running")}catch(n){this.#n(r,!1,"before",n),console.error(n),this.#t=!1;return}}if(e==!1){let r=[];for(let[n,o]of this.#r)r.push(this.#c(n,o));await Promise.all(r)}else for(let[r,n]of this.#r){if(this.#t==!1)break;await this.#c(r,n)}if(this.#t==!1)return;let t=this.#e.get(E);if(t!=null){let r;try{let n=this.getElement("after-all-details");n.toggleAttribute("success",!1),n.classList.add("running"),n.part.add("running"),n.classList.remove("success","fail"),n.part.remove("success","fail");for(let[o,l]of t)r=await o(),this.#n(r,!0,"after");n.part.remove("running")}catch(n){this.#n(r,!1,"after",n),console.error(n),this.#t=!1;return}}let a=this.shadowRoot.querySelectorAll('[success="false"]');this.setAttribute("success",a.length==0?"true":"false"),this.classList.remove("running")}#p(){for(let[e,s]of this.#r){let t=this.getElement("tests").querySelector(`[data-test-id="${e}"]`);if(t==null){this.#i(`Unable to find test element for test: ${e}`);return}t.toggleAttribute("success",!1),t.classList.remove("success","fail"),t.part.remove("success","fail")}}async#c(e,s){let t=this.getElement("tests").querySelector(`[data-test-id="${e}"]`);if(t==null){this.#i(`Unable to find test element for test: ${e}`);return}t.toggleAttribute("success",!1),t.classList.add("running"),t.part.add("running"),t.classList.remove("success","fail"),t.part.remove("success","fail");let a=t.querySelector(".error-message");a!=null&&(a.textContent="");let r=t.querySelector("details");r!=null&&(r.open=!1);let n=M,o,l=M,i;try{let u=this.#e.get(y);if(u!=null){for(let[p,g]of u)if(g.has(e)){n=await p();break}}o=await s();let d=this.#e.get(k);if(d!=null){for(let[p,g]of d)if(g.has(e)){l=await p();break}}i="before",n!=M&&this.#a(t,n,!0,void 0,i),i=void 0,this.#a(t,o,!0,void 0,i),i="after",l!=M&&this.#a(t,l,!0,void 0,i)}catch(u){this.#a(t,o,!1,u,i),console.error(u),this.#t=!1}finally{t?.classList.remove("running")}}#a(e,s,t,a,r){if(s instanceof HTMLElement)this.#o(e,s,t,r);else if(s==null){let o=r==null?"Passed":"Hook Ran Successfully",l=this.#s(t==!0?`${o}`:`Failed${a!=null?`:
388
- ${a.message}`:""}`,t,r);this.#o(e,l,t,r)}else if(typeof s=="string"){let o=this.#s(`${s}${a==null?"":`:
389
- ${a.message}`}`,t,r);this.#o(e,o,t,r)}else if(typeof s=="object"){let o=s;if(o.success!=null&&o.expected!=null&&o.value!=null){let l=r==null?"Passed":"Success",i=r==null?"Failed":"Fail",u=this.#s(`${o.success==!0?`${l}:`:`${i}:`}
386
+ </details>`;var T=class extends Promise{async toBeDefined(t){if(await this==null)throw new Error(`${t??"Value"} is undefined`)}async toBe(t,s=!1){let e=await this;if((s==!0?e===t:e==t)==!1)throw new Error(` Value is not equal.
387
+ Expected: ${t}
388
+ Result: ${e}`)}async toContainText(t){let s=await this}async toHaveAttribute(t){let s=await this;if(!(s instanceof HTMLElement))throw new Error("Unable to check for attribute on non-HTMLElement target");if(s.getAttribute(t))throw new Error("Taret does not have attribute")}},y=Symbol("beforeAll"),v=Symbol("beforeEach"),k=Symbol("afterAll"),x=Symbol("afterEach"),A=class{static timeoutMS=500;static#e;static#p;static expect(t){return new T(async(e,r)=>{if(t instanceof Promise){let a=await t;e(a);return}e(t)})}static expectSync(t){return new T(async(e,r)=>{if(t instanceof Promise){let a=await t;e(a);return}e(t)})}static expectBefore(t){return new T(async(e,r)=>{if(t instanceof Promise){let a=await t;e(a);return}e(t)})}};function q(h){return A.expect(h)}var F=":not(slot,defs,g,rect,path,circle,ellipse,line,polygon,text,tspan,use,svg image,svg title,desc,template,template *)";function $(h){let t=[...h.querySelectorAll(`${F}[id]`)];for(let e=0;e<t.length;e++)t[e].part.add(t[e].id);let s=[...h.querySelectorAll(`${F}[class]`)];for(let e=0;e<s.length;e++)s[e].part.add(...s[e].classList)}var j=(r=>(r.BeforeAll="beforeall",r.AfterAll="afterall",r.BeforeTest="beforetest",r.AfterTest="aftertest",r))(j||{}),M=Symbol("No Test Defined"),P=new CSSStyleSheet;P.replaceSync(S);var D="code-tests",R=class extends HTMLElement{componentParts=new Map;getElement(t){if(this.componentParts.get(t)==null){let s=this.findElement(t);s!=null&&this.componentParts.set(t,s)}return this.componentParts.get(t)}findElement(t){return this.shadowRoot.getElementById(t)}#e=new Map;#p={[y]:L(),[v]:L(),[x]:L(),[k]:L()};#t=!0;constructor(){super(),this.attachShadow({mode:"open"}),this.shadowRoot.innerHTML=H,this.shadowRoot.adoptedStyleSheets.push(P),this.#c=this.#h.bind(this)}connectedCallback(){this.addEventListener("click",this.#c);let t=this.getAttribute("src")??this.getAttribute("test")??this.getAttribute("tests")??this.getAttribute("run")??this.getAttribute("path");t!=null&&(this.loadTests(t),$(this.shadowRoot))}disconnectedCallback(){this.removeEventListener("click",this.#c)}#c;#h(t){let s=t.composedPath().find(n=>n instanceof HTMLButtonElement&&n.classList.contains("run"));if(s==null)return;let e=s.closest("li");if(e==null){s.hasAttribute("data-all")==!0&&this.runTests();return}let r=e.dataset.testId;if(r==null)return;let a=this.#s.get(r);a!=null&&this.#u(r,a)}async loadTests(t){try{this.getElement("tests").innerHTML="",this.#s.clear(),this.classList.remove("has-before-hook"),this.classList.remove("has-after-hook");let s=window.location.href.lastIndexOf("/"),r=window.location.href.substring(s).indexOf(".")!=-1==!0?window.location.href.substring(0,s+1):window.location.href,a=r+t.substring(0,t.lastIndexOf("/")+1),n=r+t,o=await(await fetch(n)).text();o=o.replaceAll(/['"`](((\.\/)|(\.\.\/))+(.*))['"`]/g,`'${a}$1'`);let l=new File([o],t.substring(t.lastIndexOf("/")),{type:"text/javascript"}),i=await import(URL.createObjectURL(l)),c=i.tests??i.default;if(c==null)throw new Error(`Unable to find tests definition in file at path: ${t}`);let b=c[y];if(b!=null){if(this.#e.get(y)==null){let u=new Map;u.set(b,new Set),this.#e.set(y,u)}this.classList.add("has-before-hook")}let E=c[v];if(E!=null&&this.#e.get(v)==null){let u=new Map;u.set(E,new Set),this.#e.set(v,u)}let g=c[k];if(g!=null){if(this.#e.get(k)==null){let u=new Map;u.set(g,new Set),this.#e.set(k,u)}this.classList.add("has-after-hook")}let m=c[x];if(m!=null&&this.#e.get(x)==null){let u=new Map;u.set(m,new Set),this.#e.set(x,u)}for(let[w,u]of Object.entries(c)){let C=this.#g(w,u);if(b!=null){let d=this.#e.get(y);if(d!=null){let p=d.get(b);p?.add(C)}}if(E!=null){let d=this.#e.get(v);if(d!=null){let p=d.get(E);p?.add(C)}}if(g!=null){let d=this.#e.get(k);if(d!=null){let p=d.get(g);p?.add(C)}}if(m!=null){let d=this.#e.get(x);if(d!=null){let p=d.get(m);p?.add(C)}}}}catch(s){this.#i("An error occurred while loading the tasks:",s)}}async runTests(){this.dispatchEvent(new CustomEvent("beforeall",{bubbles:!0,composed:!0})),this.#t=!0,this.classList.add("running"),this.toggleAttribute("success",!1),this.#f();let t=this.hasAttribute("in-order"),s=this.#e.get(y);if(s!=null){let a;try{let n=this.getElement("before-all-details");n.classList.add("running"),n.part.add("running");for(let[o,l]of s)a=await o(),this.#n(a,!0,"before");n.part.remove("running"),n.classList.remove("running")}catch(n){this.#n(a,!1,"before",n),console.error(n),this.#t=!1;return}}if(t==!1){let a=[];for(let[n,o]of this.#s)a.push(this.#u(n,o));await Promise.all(a)}else for(let[a,n]of this.#s){if(this.#t==!1)break;await this.#u(a,n)}if(this.#t==!1)return;let e=this.#e.get(k);if(e!=null){let a;try{let n=this.getElement("after-all-details");n.classList.add("running"),n.part.add("running");for(let[o,l]of e)a=await o(),this.#n(a,!0,"after");n.part.remove("running"),n.classList.remove("running")}catch(n){this.#n(a,!1,"after",n),console.error(n),this.#t=!1;return}}let r=this.shadowRoot.querySelectorAll('[success="false"]');this.setAttribute("success",r.length==0?"true":"false"),this.classList.remove("running"),this.part.remove("running"),this.dispatchEvent(new CustomEvent("afterall",{bubbles:!0,composed:!0}))}#f(){for(let[e,r]of this.#s){let a=this.getElement("tests").querySelector(`[data-test-id="${e}"]`);if(a==null){this.#i(`Unable to find test element for test: ${e}`);return}a.toggleAttribute("success",!1),a.classList.remove("success","fail"),a.part.remove("success","fail")}let t=this.getElement("before-all-details");t.toggleAttribute("success",!1),t.classList.remove("success","fail"),t.part.remove("success","fail");let s=this.getElement("after-all-details");s.toggleAttribute("success",!1),s.classList.remove("success","fail"),s.part.remove("success","fail")}async#u(t,s){let e=this.getElement("tests").querySelector(`[data-test-id="${t}"]`);if(e==null){this.#i(`Unable to find test element for test: ${t}`);return}e.toggleAttribute("success",!1),e.classList.add("running"),e.part.add("running"),e.classList.remove("success","fail"),e.part.remove("success","fail");let r=e.querySelector(".result-icon");r?.classList.remove("success","fail"),r?.part.remove("success","fail"),r?.classList.add("running"),r?.part.add("running");let a=e.querySelector(".error-message");a!=null&&(a.textContent="");let n=e.querySelector("details");n!=null&&(n.open=!1);let o=M,l,f=M,i;try{if(this.dispatchEvent(new CustomEvent("beforetest",{bubbles:!0,cancelable:!0,composed:!0,detail:{testElement:e}}))==!0){let b=this.#e.get(v);if(b!=null){for(let[g,m]of b)if(m.has(t)){o=await g();break}}l=await s();let E=this.#e.get(x);if(E!=null){for(let[g,m]of E)if(m.has(t)){f=await g();break}}i="before",o!=M&&this.#a(e,o,!0,void 0,i),i=void 0,this.#a(e,l,!0,void 0,i),i="after",f!=M&&this.#a(e,f,!0,void 0,i)}}catch(c){this.#a(e,l,!1,c,i),console.error(c),this.#t=!1}finally{e?.classList.remove("running"),e?.part.remove("running"),r?.classList.remove("running"),r?.part.remove("running"),this.dispatchEvent(new CustomEvent("aftertest",{bubbles:!0,cancelable:!0,composed:!0,detail:{testElement:e}}))}}#a(t,s,e,r,a){if(s instanceof HTMLElement)this.#o(t,s,e,a);else if(s==null){let o=a==null?"Passed":"Hook Ran Successfully",l=this.#r(e==!0?`${o}`:`Failed${r!=null?`:
389
+ ${r.message}`:""}`,e,a);this.#o(t,l,e,a)}else if(typeof s=="string"){let o=this.#r(`${s}${r==null?"":`:
390
+ ${r.message}`}`,e,a);this.#o(t,o,e,a)}else if(typeof s=="object"){let o=s;if(o.success!=null&&o.expected!=null&&o.value!=null){let l=a==null?"Passed":"Success",f=a==null?"Failed":"Fail",i=this.#r(`${o.success==!0?`${l}:`:`${f}:`}
390
391
  Expected:${o.expected}
391
- Result:${o.value}`,o.success,r);this.#o(e,u,t,r)}}let n=e.querySelector("details");n!=null&&(n.open=!0)}#n(e,s,t,a){if(e instanceof HTMLElement)this.#l(e,s,t);else{let n;if(e==null)n=this.#s(s==!0?"Hook Ran Successfully":`Failed${a!=null?`:
392
- ${a.message}`:""}`,s),this.#l(n,s,t);else if(typeof e=="string")n=this.#s(`${e}${a==null?"":`:
393
- ${a.message}`}`,s),this.#l(n,s,t);else if(typeof e=="object"){let o=e;o.success!=null&&o.expected!=null&&o.value!=null&&(n=this.#s(`${o.success==!0?"Success:":"Fail:"}
392
+ Result:${o.value}`,o.success,a);this.#o(t,i,e,a)}}let n=t.querySelector("details");n!=null&&(n.open=!0)}#n(t,s,e,r){if(t instanceof HTMLElement)this.#l(t,s,e);else{let n;if(t==null)n=this.#r(s==!0?"Hook Ran Successfully":`Failed${r!=null?`:
393
+ ${r.message}`:""}`,s),this.#l(n,s,e);else if(typeof t=="string")n=this.#r(`${t}${r==null?"":`:
394
+ ${r.message}`}`,s),this.#l(n,s,e);else if(typeof t=="object"){let o=t;o.success!=null&&o.expected!=null&&o.value!=null&&(n=this.#r(`${o.success==!0?"Success:":"Fail:"}
394
395
  Expected:${o.expected}
395
- Result:${o.value}`,o.success),this.#l(n,s,t))}}let r=this.getElement(`${t}-all-details`);r!=null&&(r.open=!0)}static create(e){let s=document.createElement("code-tests");return console.log(e),s}#r=new Map;#g(e,s){let t=x();this.#r.set(t,s);let a=this.#m(t,e);return this.getElement("tests").append(a),t}#m(e,s){let t=document.createElement("li");t.dataset.testId=e,t.classList.add("test");let a=document.createElement("details");a.classList.add("test-details");let r=document.createElement("summary");r.classList.add("test-summary");let n=document.createElement("div");n.classList.add("result-icon"),r.append(n);let o=document.createElement("span");o.classList.add("description","test-description"),o.textContent=s,r.append(o);let l=document.createElement("button");l.classList.add("run","test-run"),l.textContent="Run Test",l.title="Run Test",r.append(l);let i=document.createElement("div");i.classList.add("before-result","test-before-result");let u=document.createElement("div");u.classList.add("result","test-result");let d=document.createElement("div");return d.classList.add("after-result","test-after-result"),a.append(r),a.append(i),a.append(u),a.append(d),t.append(a),t}#o(e,s,t,a){e.setAttribute("success",t==!0?"true":"false"),e.classList.toggle("success",t),e.part.toggle("success",t),e.classList.toggle("fail",!t),e.part.toggle("fail",!t);let r=e.querySelector(`.${a==null?"result":a=="before"?"before-result":"after-result"}`);if(r==null){this.#i("Unable to find result element");return}r.innerHTML="",r.appendChild(s)}#s(e,s,t){let a=document.createElement("code"),r=document.createElement("pre");return r.textContent=e,r.classList.add(s==!0?"success-message":"error-message"),a.appendChild(r),a}#l(e,s,t){let a=this.getElement(`${t}-all-details`),r=this.getElement(`${t}-all-results`);a.setAttribute("success",s==!0?"true":"false"),a.classList.toggle("success",s),a.part.toggle("success",s),a.classList.toggle("fail",!s),a.part.toggle("fail",!s),r.innerHTML="",r.appendChild(e)}#i(e,s){s instanceof Error&&(e+=`
396
- ${s.message}`,console.error(s));let t=document.createElement("li"),a=document.createElement("code"),r=document.createElement("pre");r.textContent=e,a.append(r),t.append(a),this.getElement("tests").append(t)}#d(e){if(e=="ordered"){let s=this.shadowRoot.querySelector("ul");if(s==null)return;let t=this.shadowRoot?.querySelectorAll("li"),a=document.createElement("ol");t!=null&&a.append(...t),a.id="tests",s.replaceWith(a)}else{let s=this.shadowRoot.querySelector("ol");if(s==null)return;let t=this.shadowRoot?.querySelectorAll("li"),a=document.createElement("ul");a.id="tests",t!=null&&a.append(...t),s.replaceWith(a)}}static observedAttributes=["in-order"];attributeChangedCallback(e,s,t){e=="in-order"&&(t==null?this.#d("unordered"):this.#d("ordered"))}};function x(){let m=new Uint8Array(20);crypto.getRandomValues(m);let e=[].slice.apply(m).map(function(t){return String.fromCharCode(t)}).join("");return btoa(e).replace(/\//g,"_").replace(/\+/g,"-").replace(/=/g,"")}customElements.get(S)==null&&customElements.define(S,A);export{E as AFTERALL,k as AFTEREACH,b as BEFOREALL,y as BEFOREEACH,R as CodeTests,A as CodeTestsElement,P as expect};
396
+ Result:${o.value}`,o.success),this.#l(n,s,e))}}let a=this.getElement(`${e}-all-details`);a!=null&&(a.open=!0)}static create(t){let s=document.createElement("code-tests");return console.log(t),s}#s=new Map;#g(t,s){let e=L();this.#s.set(e,s);let r=this.#m(e,t);return this.getElement("tests").append(r),e}#m(t,s){let e=document.createElement("li");e.dataset.testId=t,e.classList.add("test"),e.part.add("test");let r=document.createElement("details");r.classList.add("test-details"),r.part.add("test-details");let a=document.createElement("summary");a.classList.add("test-summary"),a.part.add("test-summary");let n=document.createElement("div");n.classList.add("result-icon"),n.part.add("result-icon"),a.append(n);let o=document.createElement("span");o.classList.add("description","test-description"),o.textContent=s,a.append(o);let l=document.createElement("button");l.classList.add("run","test-run"),l.part.add("run","test-run"),l.textContent="Run Test",l.title="Run Test",a.append(l);let f=document.createElement("div");f.classList.add("before-result","test-before-result"),f.part.add("before-result","test-before-result");let i=document.createElement("div");i.classList.add("result","test-result"),i.part.add("result","test-result");let c=document.createElement("div");return c.classList.add("after-result","test-after-result"),c.part.add("after-result","test-after-result"),r.append(a),r.append(f),r.append(i),r.append(c),e.append(r),e}#o(t,s,e,r){t.setAttribute("success",e==!0?"true":"false"),t.classList.toggle("success",e),t.part.toggle("success",e),t.classList.toggle("fail",!e),t.part.toggle("fail",!e);let a=t.querySelector(".result-icon");a?.classList.toggle("success",e),a?.part.toggle("success",e),a?.classList.toggle("fail",!e),a?.part.toggle("fail",!e);let n=t.querySelector(`.${r==null?"result":r=="before"?"before-result":"after-result"}`);if(n==null){this.#i("Unable to find result element");return}n.innerHTML="",n.appendChild(s)}#r(t,s,e){let r=document.createElement("code");r.classList.add("code"),r.part.add("code");let a=document.createElement("pre");a.textContent=t;let n=s==!0?"success-message":"error-message";return a.classList.add("pre",n),a.part.add("pre",n),r.appendChild(a),r}#l(t,s,e){let r=this.getElement(`${e}-all-details`),a=this.getElement(`${e}-all-results`);r.setAttribute("success",s==!0?"true":"false"),r.classList.toggle("success",s),r.part.toggle("success",s),r.classList.toggle("fail",!s),r.part.toggle("fail",!s),a.innerHTML="",a.appendChild(t)}#i(t,s){s instanceof Error&&(t+=`
397
+ ${s.message}`,console.error(s));let e=document.createElement("li");e.classList.add("error","process-error"),e.part.add("error","process-error");let r=document.createElement("code");r.classList.add("code","process-error-code"),r.part.add("code","process-error-code");let a=document.createElement("pre");a.classList.add("pre","process-error-pre"),a.part.add("pre","process-error-pre"),a.textContent=t,r.append(a),e.append(r),this.getElement("tests").append(e)}#d(t){if(t=="ordered"){let s=this.shadowRoot.querySelector("ul");if(s==null)return;let e=this.shadowRoot?.querySelectorAll("li"),r=document.createElement("ol");e!=null&&r.append(...e),r.id="tests",s.replaceWith(r)}else{let s=this.shadowRoot.querySelector("ol");if(s==null)return;let e=this.shadowRoot?.querySelectorAll("li"),r=document.createElement("ul");r.id="tests",e!=null&&r.append(...e),s.replaceWith(r)}}static observedAttributes=["in-order"];attributeChangedCallback(t,s,e){t=="in-order"&&(e==null?this.#d("unordered"):this.#d("ordered"))}};function L(){let h=new Uint8Array(20);crypto.getRandomValues(h);let t=[].slice.apply(h).map(function(e){return String.fromCharCode(e)}).join("");return btoa(t).replace(/\//g,"_").replace(/\+/g,"-").replace(/=/g,"")}customElements.get(D)==null&&customElements.define(D,R);export{k as AFTERALL,x as AFTEREACH,y as BEFOREALL,v as BEFOREEACH,j as CodeTestEventType,A as CodeTests,R as CodeTestsElement,q as expect};
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@magnit-ce/code-tests",
3
- "version": "0.0.1",
4
- "description": "A custom html element that provides a selection gallery as a dialog, to mimic an os-native file browser.",
3
+ "version": "0.0.3",
4
+ "description": "A custom html element that interprets and runs tests in a browser.",
5
5
  "type": "module",
6
6
  "main": "dist/code-tests.js",
7
7
  "module": "dist/code-tests.mjs",
@@ -34,11 +34,15 @@
34
34
  "tsup": "^8.2.0",
35
35
  "typescript": "^5.5.3"
36
36
  },
37
+ "dependencies": {
38
+ "ce-part-utils": "^0.0.0"
39
+ },
37
40
  "scripts": {
38
41
  "build": "tsup src/code-tests.ts --format cjs,esm --dts --clean",
39
42
  "minify": "tsup src/code-tests.ts --format esm --config ./tsup.config.min.ts --outDir ./dist --minify",
43
+ "copyToDemo": "node -e \"const fs = require('fs'); fs.cpSync('dist', 'demo/dist', {recursive: true});\"",
40
44
  "lint": "tsup src/code-tests.ts --format esm --tsconfig ./tsconfig.lint.json",
41
- "package": "npm run build && npm run minify",
45
+ "package": "npm run build && npm run minify && npm run copyToDemo",
42
46
  "release": "npm run package && changeset publish"
43
47
  }
44
48
  }