jasmine-core 5.10.0 → 5.11.0

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.
package/README.md CHANGED
@@ -30,7 +30,7 @@ Microsoft Edge) as well as Node.
30
30
  | Environment | Supported versions |
31
31
  |-------------------|----------------------------------|
32
32
  | Node | 18.20.5+*, 20, 22, 24 |
33
- | Safari | 15*, 16*, 17* |
33
+ | Safari | 16*, 17* |
34
34
  | Chrome | Evergreen |
35
35
  | Firefox | Evergreen, 102*, 115*, 128*, 140 |
36
36
  | Edge | Evergreen |
@@ -38,20 +38,12 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38
38
  (function() {
39
39
  const env = jasmine.getEnv();
40
40
 
41
- /**
42
- * ## Runner Parameters
43
- *
44
- * More browser specific code - wrap the query string in an object and to allow for getting/setting parameters from the runner user interface.
45
- */
46
-
47
41
  const queryString = new jasmine.QueryString({
48
42
  getWindowLocation: function() {
49
43
  return window.location;
50
44
  }
51
45
  });
52
46
 
53
- const filterSpecs = !!queryString.getParam('spec');
54
-
55
47
  const config = {
56
48
  stopOnSpecFailure: queryString.getParam('stopOnSpecFailure'),
57
49
  stopSpecOnExpectationFailure: queryString.getParam(
@@ -93,7 +85,7 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
93
85
  return document.createTextNode.apply(document, arguments);
94
86
  },
95
87
  timer: new jasmine.Timer(),
96
- filterSpecs: filterSpecs
88
+ queryString
97
89
  });
98
90
 
99
91
  /**
@@ -105,14 +97,9 @@ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
105
97
  /**
106
98
  * Filter which specs will be run by matching the start of the full name against the `spec` query param.
107
99
  */
108
- const specFilter = new jasmine.HtmlSpecFilter({
109
- filterString: function() {
110
- return queryString.getParam('spec');
111
- }
112
- });
113
-
100
+ const specFilter = new jasmine.HtmlExactSpecFilter({ queryString });
114
101
  config.specFilter = function(spec) {
115
- return specFilter.matches(spec.getFullName());
102
+ return specFilter.matches(spec);
116
103
  };
117
104
 
118
105
  env.configure(config);
@@ -30,6 +30,7 @@ jasmineRequire.html = function(j$) {
30
30
  j$.HtmlReporter = jasmineRequire.HtmlReporter(j$);
31
31
  j$.QueryString = jasmineRequire.QueryString();
32
32
  j$.HtmlSpecFilter = jasmineRequire.HtmlSpecFilter();
33
+ j$.HtmlExactSpecFilter = jasmineRequire.HtmlExactSpecFilter();
33
34
  };
34
35
 
35
36
  jasmineRequire.HtmlReporter = function(j$) {
@@ -39,11 +40,13 @@ jasmineRequire.HtmlReporter = function(j$) {
39
40
  this.specsExecuted = 0;
40
41
  this.failureCount = 0;
41
42
  this.pendingSpecCount = 0;
43
+ this.suitesById = [];
42
44
  }
43
45
 
44
46
  ResultsStateBuilder.prototype.suiteStarted = function(result) {
45
47
  this.currentParent.addChild(result, 'suite');
46
48
  this.currentParent = this.currentParent.last();
49
+ this.suitesById[result.id] = this.currentParent;
47
50
  };
48
51
 
49
52
  ResultsStateBuilder.prototype.suiteDone = function(result) {
@@ -81,6 +84,13 @@ jasmineRequire.HtmlReporter = function(j$) {
81
84
  }
82
85
  };
83
86
 
87
+ /**
88
+ * @class HtmlReporter
89
+ * @classdesc Displays results and allows re-running individual specs and suites.
90
+ * @implements {Reporter}
91
+ * @param options Options object. See lib/jasmine-core/boot1.js for details.
92
+ * @since 1.2.0
93
+ */
84
94
  function HtmlReporter(options) {
85
95
  function config() {
86
96
  return (options.env && options.env.configuration()) || {};
@@ -89,15 +99,24 @@ jasmineRequire.HtmlReporter = function(j$) {
89
99
  const getContainer = options.getContainer;
90
100
  const createElement = options.createElement;
91
101
  const createTextNode = options.createTextNode;
102
+ // TODO: in the next major release, replace navigateWithNewParam and
103
+ // addToExistingQueryString with direct usage of options.queryString
92
104
  const navigateWithNewParam = options.navigateWithNewParam || function() {};
93
105
  const addToExistingQueryString =
94
106
  options.addToExistingQueryString || defaultQueryString;
95
- const filterSpecs = options.filterSpecs;
107
+ const filterSpecs = options.queryString
108
+ ? !!options.queryString.getParam('spec')
109
+ : options.filterSpecs; // For compatibility with pre-5.11 boot files
96
110
  let htmlReporterMain;
97
111
  let symbols;
98
112
  const deprecationWarnings = [];
99
113
  const failures = [];
100
114
 
115
+ /**
116
+ * Initializes the reporter. Should be called before {@link Env#execute}.
117
+ * @function
118
+ * @name HtmlReporter#initialize
119
+ */
101
120
  this.initialize = function() {
102
121
  clearPrior();
103
122
  htmlReporterMain = createDom(
@@ -716,21 +735,6 @@ jasmineRequire.HtmlReporter = function(j$) {
716
735
  return wrapper;
717
736
  }
718
737
 
719
- function suiteHref(suite) {
720
- const els = [];
721
-
722
- while (suite && suite.parent) {
723
- els.unshift(suite.result.description);
724
- suite = suite.parent;
725
- }
726
-
727
- // include window.location.pathname to fix issue with karma-jasmine-html-reporter in angular: see https://github.com/jasmine/jasmine/issues/1906
728
- return (
729
- (window.location.pathname || '') +
730
- addToExistingQueryString('spec', els.join(' '))
731
- );
732
- }
733
-
734
738
  function addDeprecationWarnings(result, runnableType) {
735
739
  if (result && result.deprecationWarnings) {
736
740
  for (let i = 0; i < result.deprecationWarnings.length; i++) {
@@ -828,11 +832,33 @@ jasmineRequire.HtmlReporter = function(j$) {
828
832
  return '' + count + ' ' + word;
829
833
  }
830
834
 
835
+ function suitePath(suite) {
836
+ const els = [];
837
+
838
+ while (suite && suite.parent) {
839
+ els.unshift(suite.result.description);
840
+ suite = suite.parent;
841
+ }
842
+
843
+ return els;
844
+ }
845
+
846
+ function suiteHref(suite) {
847
+ return pathHref(suitePath(suite));
848
+ }
849
+
831
850
  function specHref(result) {
851
+ const suite = stateBuilder.suitesById[result.parentSuiteId];
852
+ const path = suitePath(suite);
853
+ path.push(result.description);
854
+ return pathHref(path);
855
+ }
856
+
857
+ function pathHref(path) {
832
858
  // include window.location.pathname to fix issue with karma-jasmine-html-reporter in angular: see https://github.com/jasmine/jasmine/issues/1906
833
859
  return (
834
860
  (window.location.pathname || '') +
835
- addToExistingQueryString('spec', result.fullName)
861
+ addToExistingQueryString('spec', JSON.stringify(path))
836
862
  );
837
863
  }
838
864
 
@@ -881,13 +907,36 @@ jasmineRequire.HtmlReporter = function(j$) {
881
907
  };
882
908
 
883
909
  jasmineRequire.HtmlSpecFilter = function() {
910
+ /**
911
+ * @name HtmlSpecFilter
912
+ * @classdesc Legacy HTML spec filter, for backward compatibility
913
+ * with boot files that predate {@link HtmlExactSpecFilter}.
914
+ * @param options Object with a filterString method
915
+ * @constructor
916
+ * @deprecated
917
+ * @since 1.2.0
918
+ */
919
+ // Legacy HTML spec filter, preserved for backward compatibility with
920
+ // boot files that predate HtmlExactSpecFilterV2
884
921
  function HtmlSpecFilter(options) {
885
- const filterString =
886
- options &&
887
- options.filterString() &&
888
- options.filterString().replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
922
+ let filterString = (options && options.filterString()) || '';
923
+
924
+ if (filterString.startsWith('[')) {
925
+ // Convert an HtmlExactSpecFilterV2 string into something we can use
926
+ filterString = JSON.parse(filterString).join(' ');
927
+ }
928
+
929
+ filterString = filterString.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, '\\$&');
930
+
889
931
  const filterPattern = new RegExp(filterString);
890
932
 
933
+ /**
934
+ * Determines whether the spec with the specified name should be executed.
935
+ * @name HtmlSpecFilter#matches
936
+ * @function
937
+ * @param {string} specName The full name of the spec
938
+ * @returns {boolean}
939
+ */
891
940
  this.matches = function(specName) {
892
941
  return filterPattern.test(specName);
893
942
  };
@@ -921,38 +970,57 @@ jasmineRequire.ResultsNode = function() {
921
970
  };
922
971
 
923
972
  jasmineRequire.QueryString = function() {
924
- function QueryString(options) {
925
- this.navigateWithNewParam = function(key, value) {
926
- options.getWindowLocation().search = this.fullStringWithNewParam(
973
+ /**
974
+ * Reads and manipulates the query string.
975
+ * @since 2.0.0
976
+ */
977
+ class QueryString {
978
+ #getWindowLocation;
979
+
980
+ /**
981
+ * @param options Object with a getWindowLocation property, which should be
982
+ * a function returning the current value of window.location.
983
+ */
984
+ constructor(options) {
985
+ this.#getWindowLocation = options.getWindowLocation;
986
+ }
987
+
988
+ /**
989
+ * Sets the specified query parameter and navigates to the resulting URL.
990
+ * @param {string} key
991
+ * @param {string} value
992
+ */
993
+ navigateWithNewParam(key, value) {
994
+ this.#getWindowLocation().search = this.fullStringWithNewParam(
927
995
  key,
928
996
  value
929
997
  );
930
- };
998
+ }
931
999
 
932
- this.fullStringWithNewParam = function(key, value) {
933
- const paramMap = queryStringToParamMap();
1000
+ /**
1001
+ * Returns a new URL based on the current location, with the specified
1002
+ * query parameter set.
1003
+ * @param {string} key
1004
+ * @param {string} value
1005
+ * @return {string}
1006
+ */
1007
+ fullStringWithNewParam(key, value) {
1008
+ const paramMap = this.#queryStringToParamMap();
934
1009
  paramMap[key] = value;
935
1010
  return toQueryString(paramMap);
936
- };
937
-
938
- this.getParam = function(key) {
939
- return queryStringToParamMap()[key];
940
- };
941
-
942
- return this;
1011
+ }
943
1012
 
944
- function toQueryString(paramMap) {
945
- const qStrPairs = [];
946
- for (const prop in paramMap) {
947
- qStrPairs.push(
948
- encodeURIComponent(prop) + '=' + encodeURIComponent(paramMap[prop])
949
- );
950
- }
951
- return '?' + qStrPairs.join('&');
1013
+ /**
1014
+ * Gets the value of the specified query parameter.
1015
+ * @param {string} key
1016
+ * @return {string}
1017
+ */
1018
+ getParam(key) {
1019
+ return this.#queryStringToParamMap()[key];
952
1020
  }
953
1021
 
954
- function queryStringToParamMap() {
955
- const paramStr = options.getWindowLocation().search.substring(1);
1022
+ #queryStringToParamMap() {
1023
+ const paramStr = this.#getWindowLocation().search.substring(1);
956
1024
  let params = [];
957
1025
  const paramMap = {};
958
1026
 
@@ -972,5 +1040,68 @@ jasmineRequire.QueryString = function() {
972
1040
  }
973
1041
  }
974
1042
 
1043
+ function toQueryString(paramMap) {
1044
+ const qStrPairs = [];
1045
+ for (const prop in paramMap) {
1046
+ qStrPairs.push(
1047
+ encodeURIComponent(prop) + '=' + encodeURIComponent(paramMap[prop])
1048
+ );
1049
+ }
1050
+ return '?' + qStrPairs.join('&');
1051
+ }
1052
+
975
1053
  return QueryString;
976
1054
  };
1055
+
1056
+ jasmineRequire.HtmlExactSpecFilter = function() {
1057
+ /**
1058
+ * Spec filter for use with {@link HtmlReporter}
1059
+ *
1060
+ * See lib/jasmine-core/boot1.js for usage.
1061
+ * @since 5.11.0
1062
+ */
1063
+ class HtmlExactSpecFilter {
1064
+ #getFilterString;
1065
+
1066
+ /**
1067
+ * Create a filter instance.
1068
+ * @param options Object with a queryString property, which should be an
1069
+ * instance of {@link QueryString}.
1070
+ */
1071
+ constructor(options) {
1072
+ this.#getFilterString = function() {
1073
+ return options.queryString.getParam('spec');
1074
+ };
1075
+ }
1076
+
1077
+ /**
1078
+ * Determines whether the specified spec should be executed.
1079
+ * @param {Spec} spec
1080
+ * @returns {boolean}
1081
+ */
1082
+ matches(spec) {
1083
+ const filterString = this.#getFilterString();
1084
+
1085
+ if (!filterString) {
1086
+ return true;
1087
+ }
1088
+
1089
+ const filterPath = JSON.parse(this.#getFilterString());
1090
+ const specPath = spec.getPath();
1091
+
1092
+ if (filterPath.length > specPath.length) {
1093
+ return false;
1094
+ }
1095
+
1096
+ for (let i = 0; i < filterPath.length; i++) {
1097
+ if (specPath[i] !== filterPath[i]) {
1098
+ return false;
1099
+ }
1100
+ }
1101
+
1102
+ return true;
1103
+ }
1104
+ }
1105
+
1106
+ return HtmlExactSpecFilter;
1107
+ };