jasmine-core 5.9.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
@@ -27,13 +27,13 @@ for information on writing specs, and [the FAQ](https://jasmine.github.io/pages/
27
27
  Jasmine tests itself across popular browsers (Safari, Chrome, Firefox, and
28
28
  Microsoft Edge) as well as Node.
29
29
 
30
- | Environment | Supported versions |
31
- |-------------------|----------------------------|
32
- | Node | 18.20.5+*, 20, 22, 24 |
33
- | Safari | 15*, 16*, 17* |
34
- | Chrome | Evergreen |
35
- | Firefox | Evergreen, 102*, 115*, 128 |
36
- | Edge | Evergreen |
30
+ | Environment | Supported versions |
31
+ |-------------------|----------------------------------|
32
+ | Node | 18.20.5+*, 20, 22, 24 |
33
+ | Safari | 16*, 17* |
34
+ | Chrome | Evergreen |
35
+ | Firefox | Evergreen, 102*, 115*, 128*, 140 |
36
+ | Edge | Evergreen |
37
37
 
38
38
  For evergreen browsers, each version of Jasmine is tested against the version of the browser that is available to us
39
39
  at the time of release. Other browsers, as well as older & newer versions of some supported browsers, are likely to work.
@@ -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(
@@ -557,6 +576,11 @@ jasmineRequire.HtmlReporter = function(j$) {
557
576
  'a',
558
577
  { href: specHref(resultNode.result) },
559
578
  specDescription
579
+ ),
580
+ createDom(
581
+ 'span',
582
+ { className: 'jasmine-spec-duration' },
583
+ '(' + resultNode.result.duration + 'ms)'
560
584
  )
561
585
  )
562
586
  );
@@ -711,21 +735,6 @@ jasmineRequire.HtmlReporter = function(j$) {
711
735
  return wrapper;
712
736
  }
713
737
 
714
- function suiteHref(suite) {
715
- const els = [];
716
-
717
- while (suite && suite.parent) {
718
- els.unshift(suite.result.description);
719
- suite = suite.parent;
720
- }
721
-
722
- // include window.location.pathname to fix issue with karma-jasmine-html-reporter in angular: see https://github.com/jasmine/jasmine/issues/1906
723
- return (
724
- (window.location.pathname || '') +
725
- addToExistingQueryString('spec', els.join(' '))
726
- );
727
- }
728
-
729
738
  function addDeprecationWarnings(result, runnableType) {
730
739
  if (result && result.deprecationWarnings) {
731
740
  for (let i = 0; i < result.deprecationWarnings.length; i++) {
@@ -823,11 +832,33 @@ jasmineRequire.HtmlReporter = function(j$) {
823
832
  return '' + count + ' ' + word;
824
833
  }
825
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
+
826
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) {
827
858
  // include window.location.pathname to fix issue with karma-jasmine-html-reporter in angular: see https://github.com/jasmine/jasmine/issues/1906
828
859
  return (
829
860
  (window.location.pathname || '') +
830
- addToExistingQueryString('spec', result.fullName)
861
+ addToExistingQueryString('spec', JSON.stringify(path))
831
862
  );
832
863
  }
833
864
 
@@ -876,13 +907,36 @@ jasmineRequire.HtmlReporter = function(j$) {
876
907
  };
877
908
 
878
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
879
921
  function HtmlSpecFilter(options) {
880
- const filterString =
881
- options &&
882
- options.filterString() &&
883
- 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
+
884
931
  const filterPattern = new RegExp(filterString);
885
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
+ */
886
940
  this.matches = function(specName) {
887
941
  return filterPattern.test(specName);
888
942
  };
@@ -916,38 +970,57 @@ jasmineRequire.ResultsNode = function() {
916
970
  };
917
971
 
918
972
  jasmineRequire.QueryString = function() {
919
- function QueryString(options) {
920
- this.navigateWithNewParam = function(key, value) {
921
- 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(
922
995
  key,
923
996
  value
924
997
  );
925
- };
998
+ }
926
999
 
927
- this.fullStringWithNewParam = function(key, value) {
928
- 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();
929
1009
  paramMap[key] = value;
930
1010
  return toQueryString(paramMap);
931
- };
932
-
933
- this.getParam = function(key) {
934
- return queryStringToParamMap()[key];
935
- };
936
-
937
- return this;
1011
+ }
938
1012
 
939
- function toQueryString(paramMap) {
940
- const qStrPairs = [];
941
- for (const prop in paramMap) {
942
- qStrPairs.push(
943
- encodeURIComponent(prop) + '=' + encodeURIComponent(paramMap[prop])
944
- );
945
- }
946
- 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];
947
1020
  }
948
1021
 
949
- function queryStringToParamMap() {
950
- const paramStr = options.getWindowLocation().search.substring(1);
1022
+ #queryStringToParamMap() {
1023
+ const paramStr = this.#getWindowLocation().search.substring(1);
951
1024
  let params = [];
952
1025
  const paramMap = {};
953
1026
 
@@ -967,5 +1040,68 @@ jasmineRequire.QueryString = function() {
967
1040
  }
968
1041
  }
969
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
+
970
1053
  return QueryString;
971
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
+ };
@@ -229,6 +229,9 @@ body {
229
229
  .jasmine_html-reporter .jasmine-specs li.jasmine-excluded a:before {
230
230
  content: "• ";
231
231
  }
232
+ .jasmine_html-reporter .jasmine-specs li .jasmine-spec-duration {
233
+ margin-left: 1em;
234
+ }
232
235
  .jasmine_html-reporter .jasmine-description + .jasmine-suite {
233
236
  margin-top: 0;
234
237
  }