@internetarchive/bookreader 5.0.0-9 → 5.0.0-90
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/.eslintrc.js +21 -19
- package/.github/workflows/node.js.yml +76 -11
- package/.github/workflows/npm-publish.yml +6 -20
- package/.testcaferc.js +10 -0
- package/BookReader/BookReader.css +404 -1125
- package/BookReader/BookReader.js +1 -1
- package/BookReader/BookReader.js.LICENSE.txt +20 -20
- package/BookReader/BookReader.js.map +1 -1
- package/BookReader/ia-bookreader-bundle.js +1782 -0
- package/BookReader/ia-bookreader-bundle.js.LICENSE.txt +7 -0
- package/BookReader/ia-bookreader-bundle.js.map +1 -0
- package/BookReader/icons/1up.svg +1 -1
- package/BookReader/icons/2up.svg +1 -1
- package/BookReader/icons/advance.svg +1 -1
- package/BookReader/icons/chevron-right.svg +1 -1
- package/BookReader/icons/close-circle-dark.svg +1 -1
- package/BookReader/icons/close-circle.svg +1 -1
- package/BookReader/icons/fullscreen.svg +1 -1
- package/BookReader/icons/fullscreen_exit.svg +1 -1
- package/BookReader/icons/hamburger.svg +1 -1
- package/BookReader/icons/left-arrow.svg +1 -1
- package/BookReader/icons/magnify-minus.svg +1 -1
- package/BookReader/icons/magnify-plus.svg +1 -1
- package/BookReader/icons/magnify.svg +1 -1
- package/BookReader/icons/pause.svg +1 -1
- package/BookReader/icons/play.svg +1 -1
- package/BookReader/icons/playback-speed.svg +1 -1
- package/BookReader/icons/read-aloud.svg +1 -1
- package/BookReader/icons/review.svg +1 -1
- package/BookReader/icons/thumbnails.svg +1 -1
- package/BookReader/icons/voice.svg +1 -0
- package/BookReader/icons/volume-full.svg +1 -1
- package/BookReader/images/BRicons.svg +3 -3
- package/BookReader/images/books_graphic.svg +1 -1
- package/BookReader/images/icon_book.svg +1 -1
- package/BookReader/images/icon_bookmark.svg +1 -1
- package/BookReader/images/icon_gear.svg +1 -1
- package/BookReader/images/icon_hamburger.svg +1 -1
- package/BookReader/images/icon_home.svg +1 -1
- package/BookReader/images/icon_info.svg +1 -1
- package/BookReader/images/icon_one_page.svg +1 -1
- package/BookReader/images/icon_pause.svg +1 -1
- package/BookReader/images/icon_play.svg +1 -1
- package/BookReader/images/icon_playback-rate.svg +1 -1
- package/BookReader/images/icon_search_button.svg +1 -1
- package/BookReader/images/icon_share.svg +1 -1
- package/BookReader/images/icon_skip-ahead.svg +1 -1
- package/BookReader/images/icon_skip-back.svg +1 -1
- package/BookReader/images/icon_speaker.svg +1 -1
- package/BookReader/images/icon_speaker_open.svg +1 -1
- package/BookReader/images/icon_thumbnails.svg +1 -1
- package/BookReader/images/icon_toc.svg +1 -1
- package/BookReader/images/icon_two_pages.svg +1 -1
- package/BookReader/images/marker_chap-off.svg +1 -1
- package/BookReader/images/marker_chap-on.svg +1 -1
- package/BookReader/images/marker_srch-on.svg +1 -1
- package/BookReader/images/unviewable_page.png +0 -0
- package/BookReader/jquery-3.js +2 -0
- package/BookReader/jquery-3.js.LICENSE.txt +24 -0
- package/BookReader/plugins/plugin.archive_analytics.js +1 -1
- package/BookReader/plugins/plugin.archive_analytics.js.map +1 -1
- package/BookReader/plugins/plugin.autoplay.js +1 -1
- package/BookReader/plugins/plugin.autoplay.js.map +1 -1
- package/BookReader/plugins/plugin.chapters.js +25 -1
- package/BookReader/plugins/plugin.chapters.js.LICENSE.txt +1 -0
- package/BookReader/plugins/plugin.chapters.js.map +1 -1
- package/BookReader/plugins/plugin.iframe.js +1 -1
- package/BookReader/plugins/plugin.iframe.js.map +1 -1
- package/BookReader/plugins/plugin.iiif.js +2 -0
- package/BookReader/plugins/plugin.iiif.js.map +1 -0
- package/BookReader/plugins/plugin.resume.js +1 -1
- package/BookReader/plugins/plugin.resume.js.map +1 -1
- package/BookReader/plugins/plugin.search.js +2 -1
- package/BookReader/plugins/plugin.search.js.LICENSE.txt +1 -0
- package/BookReader/plugins/plugin.search.js.map +1 -1
- package/BookReader/plugins/plugin.text_selection.js +2 -1
- package/BookReader/plugins/plugin.text_selection.js.LICENSE.txt +1 -0
- package/BookReader/plugins/plugin.text_selection.js.map +1 -1
- package/BookReader/plugins/plugin.tts.js +1 -1
- package/BookReader/plugins/plugin.tts.js.LICENSE.txt +2 -0
- package/BookReader/plugins/plugin.tts.js.map +1 -1
- package/BookReader/plugins/plugin.url.js +1 -1
- package/BookReader/plugins/plugin.url.js.map +1 -1
- package/BookReader/plugins/plugin.vendor-fullscreen.js +1 -1
- package/BookReader/plugins/plugin.vendor-fullscreen.js.map +1 -1
- package/BookReader/webcomponents-bundle.js +3 -0
- package/BookReader/webcomponents-bundle.js.LICENSE.txt +9 -0
- package/BookReader/webcomponents-bundle.js.map +1 -0
- package/BookReaderDemo/BookReaderDemo.css +18 -19
- package/BookReaderDemo/BookReaderJSAdvanced.js +0 -3
- package/BookReaderDemo/BookReaderJSSimple.js +1 -0
- package/BookReaderDemo/IADemoBr.js +144 -0
- package/BookReaderDemo/demo-advanced.html +2 -2
- package/BookReaderDemo/demo-embed-iframe-src.html +2 -1
- package/BookReaderDemo/demo-fullscreen-mobile.html +3 -5
- package/BookReaderDemo/demo-fullscreen.html +2 -4
- package/BookReaderDemo/demo-iiif.html +99 -12
- package/BookReaderDemo/demo-internetarchive.html +214 -18
- package/BookReaderDemo/demo-multiple.html +2 -1
- package/BookReaderDemo/demo-preview-pages.html +526 -525
- package/BookReaderDemo/demo-simple.html +2 -1
- package/BookReaderDemo/demo-vendor-fullscreen.html +2 -4
- package/BookReaderDemo/ia-multiple-volumes-manifest.js +170 -0
- package/BookReaderDemo/immersion-1up.html +2 -2
- package/BookReaderDemo/immersion-mode.html +2 -4
- package/BookReaderDemo/toggle_controls.html +3 -2
- package/BookReaderDemo/view_mode.html +2 -1
- package/BookReaderDemo/viewmode-cycle.html +2 -3
- package/CHANGELOG.md +584 -33
- package/README.md +14 -1
- package/babel.config.js +20 -0
- package/codecov.yml +6 -0
- package/index.html +5 -2
- package/jsconfig.json +19 -0
- package/netlify.toml +9 -0
- package/package.json +70 -62
- package/renovate.json +52 -0
- package/scripts/preversion.js +0 -1
- package/src/BookNavigator/assets/bookmark-colors.js +1 -1
- package/src/BookNavigator/assets/button-base.js +5 -2
- package/src/BookNavigator/assets/ia-logo.js +17 -0
- package/src/BookNavigator/assets/icon_checkmark.js +1 -1
- package/src/BookNavigator/assets/icon_close.js +1 -1
- package/src/BookNavigator/book-navigator.js +590 -0
- package/src/BookNavigator/bookmarks/bookmark-button.js +3 -2
- package/src/BookNavigator/bookmarks/bookmark-edit.js +3 -4
- package/src/BookNavigator/bookmarks/bookmarks-list.js +2 -3
- package/src/BookNavigator/bookmarks/bookmarks-loginCTA.js +4 -9
- package/src/BookNavigator/bookmarks/bookmarks-provider.js +27 -17
- package/src/BookNavigator/bookmarks/ia-bookmarks.js +116 -67
- package/src/BookNavigator/delete-modal-actions.js +1 -1
- package/src/BookNavigator/downloads/downloads-provider.js +36 -21
- package/src/BookNavigator/downloads/downloads.js +29 -25
- package/src/BookNavigator/search/search-provider.js +50 -28
- package/src/BookNavigator/search/search-results.js +24 -10
- package/src/BookNavigator/sharing.js +27 -0
- package/src/BookNavigator/viewable-files.js +95 -0
- package/src/BookNavigator/visual-adjustments/visual-adjustments-provider.js +13 -12
- package/src/BookNavigator/visual-adjustments/visual-adjustments.js +7 -7
- package/src/BookReader/BookModel.js +76 -41
- package/src/BookReader/DragScrollable.js +233 -0
- package/src/BookReader/ImageCache.js +48 -15
- package/src/BookReader/Mode1Up.js +56 -351
- package/src/BookReader/Mode1UpLit.js +388 -0
- package/src/BookReader/Mode2Up.js +73 -1318
- package/src/BookReader/Mode2UpLit.js +777 -0
- package/src/BookReader/ModeCoordinateSpace.js +29 -0
- package/src/BookReader/ModeSmoothZoom.js +312 -0
- package/src/BookReader/ModeThumb.js +19 -13
- package/src/BookReader/Navbar/Navbar.js +70 -54
- package/src/BookReader/PageContainer.js +116 -22
- package/src/BookReader/ReduceSet.js +3 -3
- package/src/BookReader/Toolbar/Toolbar.js +14 -41
- package/src/BookReader/events.js +2 -3
- package/src/BookReader/options.js +73 -15
- package/src/BookReader/utils/HTMLDimensionsCacher.js +44 -0
- package/src/BookReader/utils/ScrollClassAdder.js +31 -0
- package/src/BookReader/utils/SelectionObserver.js +45 -0
- package/src/BookReader/utils/classes.js +1 -1
- package/src/BookReader/utils.js +128 -13
- package/src/BookReader.js +544 -1078
- package/src/BookReaderPlugin.js +44 -0
- package/src/assets/icons/magnify-minus.svg +3 -7
- package/src/assets/icons/magnify-plus.svg +3 -7
- package/src/assets/icons/voice.svg +1 -0
- package/src/assets/images/unviewable_page.png +0 -0
- package/src/css/BookReader.scss +1 -5
- package/src/css/_BRBookmarks.scss +1 -1
- package/src/css/_BRComponent.scss +1 -1
- package/src/css/_BRicon.scss +8 -2
- package/src/css/_BRmain.scss +16 -3
- package/src/css/_BRnav.scss +12 -42
- package/src/css/_BRpages.scss +170 -42
- package/src/css/_BRsearch.scss +68 -25
- package/src/css/_BRtoolbar.scss +5 -5
- package/src/css/_TextSelection.scss +87 -27
- package/src/css/_colorbox.scss +2 -2
- package/src/css/_controls.scss +24 -7
- package/src/css/_icons.scss +1 -1
- package/src/ia-bookreader/ia-bookreader.js +224 -0
- package/src/plugins/plugin.archive_analytics.js +84 -78
- package/src/plugins/plugin.autoplay.js +99 -104
- package/src/plugins/plugin.chapters.js +237 -191
- package/src/plugins/plugin.iframe.js +1 -1
- package/src/plugins/plugin.iiif.js +141 -0
- package/src/plugins/plugin.resume.js +53 -50
- package/src/plugins/plugin.text_selection.js +503 -175
- package/src/plugins/plugin.vendor-fullscreen.js +7 -7
- package/src/plugins/search/plugin.search.js +151 -127
- package/src/plugins/search/utils.js +43 -0
- package/src/plugins/search/view.js +37 -59
- package/src/plugins/tts/AbstractTTSEngine.js +75 -45
- package/src/plugins/tts/FestivalTTSEngine.js +21 -31
- package/src/plugins/tts/PageChunk.js +16 -23
- package/src/plugins/tts/PageChunkIterator.js +11 -17
- package/src/plugins/tts/WebTTSEngine.js +88 -72
- package/src/plugins/tts/plugin.tts.js +310 -350
- package/src/plugins/tts/utils.js +16 -26
- package/src/plugins/url/UrlPlugin.js +191 -0
- package/src/plugins/{plugin.url.js → url/plugin.url.js} +47 -18
- package/src/util/browserSniffing.js +22 -0
- package/src/util/docCookies.js +21 -2
- package/src/util/strings.js +1 -0
- package/tests/e2e/README.md +37 -0
- package/tests/e2e/autoplay.test.js +9 -6
- package/tests/e2e/base.test.js +8 -16
- package/tests/e2e/helpers/base.js +55 -50
- package/tests/e2e/helpers/debug.js +1 -1
- package/tests/e2e/helpers/mockSearch.js +19 -22
- package/tests/e2e/helpers/params.js +17 -0
- package/tests/e2e/helpers/rightToLeft.js +8 -14
- package/tests/e2e/helpers/search.js +73 -0
- package/tests/e2e/models/Navigation.js +20 -37
- package/tests/e2e/rightToLeft.test.js +4 -5
- package/tests/e2e/viewmode.test.js +40 -33
- package/tests/jest/BookNavigator/book-navigator.test.js +661 -0
- package/tests/jest/BookNavigator/bookmarks/bookmark-button.test.js +43 -0
- package/tests/{karma → jest}/BookNavigator/bookmarks/bookmark-edit.test.js +25 -26
- package/tests/{karma → jest}/BookNavigator/bookmarks/bookmarks-list.test.js +41 -42
- package/tests/jest/BookNavigator/bookmarks/ia-bookmarks.test.js +45 -0
- package/tests/jest/BookNavigator/downloads/downloads-provider.test.js +67 -0
- package/tests/jest/BookNavigator/downloads/downloads.test.js +53 -0
- package/tests/jest/BookNavigator/search/search-provider.test.js +167 -0
- package/tests/{karma → jest}/BookNavigator/search/search-results.test.js +109 -60
- package/tests/jest/BookNavigator/sharing/sharing-provider.test.js +49 -0
- package/tests/jest/BookNavigator/viewable-files/viewable-files-provider.test.js +80 -0
- package/tests/jest/BookNavigator/visual-adjustments.test.js +200 -0
- package/tests/{BookReader → jest/BookReader}/BookModel.test.js +74 -14
- package/tests/jest/BookReader/BookReaderPublicFunctions.test.js +193 -0
- package/tests/{BookReader → jest/BookReader}/ImageCache.test.js +4 -4
- package/tests/jest/BookReader/Mode1UpLit.test.js +73 -0
- package/tests/jest/BookReader/Mode2Up.test.js +98 -0
- package/tests/jest/BookReader/Mode2UpLit.test.js +190 -0
- package/tests/jest/BookReader/ModeCoordinateSpace.test.js +16 -0
- package/tests/jest/BookReader/ModeSmoothZoom.test.js +218 -0
- package/tests/jest/BookReader/ModeThumb.test.js +71 -0
- package/tests/{BookReader → jest/BookReader}/Navbar/Navbar.test.js +42 -29
- package/tests/jest/BookReader/PageContainer.test.js +238 -0
- package/tests/{BookReader → jest/BookReader}/ReduceSet.test.js +1 -1
- package/tests/{BookReader → jest/BookReader}/Toolbar/Toolbar.test.js +3 -3
- package/tests/jest/BookReader/utils/HTMLDimensionsCacher.test.js +59 -0
- package/tests/jest/BookReader/utils/ScrollClassAdder.test.js +49 -0
- package/tests/jest/BookReader/utils/SelectionObserver.test.js +57 -0
- package/tests/{BookReader → jest/BookReader}/utils/classes.test.js +1 -1
- package/tests/jest/BookReader/utils.test.js +250 -0
- package/tests/jest/BookReader.keyboard.test.js +190 -0
- package/tests/{BookReader.options.test.js → jest/BookReader.options.test.js} +10 -2
- package/tests/{BookReader.test.js → jest/BookReader.test.js} +43 -53
- package/tests/jest/plugins/plugin.archive_analytics.test.js +20 -0
- package/tests/jest/plugins/plugin.autoplay.test.js +35 -0
- package/tests/jest/plugins/plugin.chapters.test.js +195 -0
- package/tests/{plugins → jest/plugins}/plugin.iframe.test.js +4 -4
- package/tests/{plugins → jest/plugins}/plugin.resume.test.js +22 -35
- package/tests/jest/plugins/plugin.text_selection.test.js +316 -0
- package/tests/{plugins → jest/plugins}/plugin.vendor-fullscreen.test.js +2 -2
- package/tests/{plugins → jest/plugins}/search/plugin.search.test.js +19 -47
- package/tests/{plugins → jest/plugins}/search/plugin.search.view.test.js +42 -9
- package/tests/jest/plugins/search/utils.js +25 -0
- package/tests/jest/plugins/search/utils.test.js +29 -0
- package/tests/{plugins → jest/plugins}/tts/AbstractTTSEngine.test.js +30 -10
- package/tests/{plugins → jest/plugins}/tts/FestivalTTSEngine.test.js +4 -4
- package/tests/{plugins → jest/plugins}/tts/PageChunk.test.js +1 -1
- package/tests/{plugins → jest/plugins}/tts/PageChunkIterator.test.js +3 -3
- package/tests/{plugins → jest/plugins}/tts/WebTTSEngine.test.js +47 -1
- package/tests/{plugins → jest/plugins}/tts/utils.test.js +1 -60
- package/tests/jest/plugins/url/UrlPlugin.test.js +198 -0
- package/tests/{plugins → jest/plugins/url}/plugin.url.test.js +57 -18
- package/tests/jest/setup.js +3 -0
- package/tests/{util → jest/util}/browserSniffing.test.js +1 -1
- package/tests/jest/util/docCookies.test.js +24 -0
- package/tests/{util → jest/util}/strings.test.js +1 -1
- package/tests/{utils.js → jest/utils.js} +38 -0
- package/webpack.config.js +16 -10
- package/.babelrc +0 -12
- package/.dependabot/config.yml +0 -6
- package/.testcaferc.json +0 -5
- package/BookReader/bookreader-component-bundle.js +0 -1450
- package/BookReader/bookreader-component-bundle.js.LICENSE.txt +0 -38
- package/BookReader/bookreader-component-bundle.js.map +0 -1
- package/BookReader/jquery-1.10.1.js +0 -2
- package/BookReader/jquery-1.10.1.js.LICENSE.txt +0 -24
- package/BookReader/plugins/plugin.menu_toggle.js +0 -2
- package/BookReader/plugins/plugin.menu_toggle.js.map +0 -1
- package/BookReader/plugins/plugin.mobile_nav.js +0 -2
- package/BookReader/plugins/plugin.mobile_nav.js.map +0 -1
- package/BookReaderDemo/BookReaderJSAutoplay.js +0 -56
- package/BookReaderDemo/IIIFBookReader.js +0 -207
- package/BookReaderDemo/bookreader-template-bundle.js +0 -7178
- package/BookReaderDemo/demo-autoplay.html +0 -38
- package/BookReaderDemo/demo-iiif.js +0 -26
- package/BookReaderDemo/demo-plugin-menu-toggle.html +0 -34
- package/karma.conf.js +0 -23
- package/src/BookNavigator/BookModel.js +0 -14
- package/src/BookNavigator/BookNavigator.js +0 -446
- package/src/BookNavigator/assets/book-loader.js +0 -27
- package/src/BookNavigator/br-fullscreen-mgr.js +0 -83
- package/src/BookNavigator/search/a-search-result.js +0 -55
- package/src/BookReader/DebugConsole.js +0 -54
- package/src/BookReaderComponent/BookReaderComponent.js +0 -112
- package/src/ItemNavigator/ItemNavigator.js +0 -376
- package/src/ItemNavigator/providers/sharing.js +0 -29
- package/src/css/_MobileNav.scss +0 -194
- package/src/dragscrollable-br.js +0 -261
- package/src/plugins/menu_toggle/plugin.menu_toggle.js +0 -324
- package/src/plugins/plugin.mobile_nav.js +0 -287
- package/tests/BookReader/BookReaderPublicFunctions.test.js +0 -171
- package/tests/BookReader/DebugConsole.test.js +0 -25
- package/tests/BookReader/Mode1Up.test.js +0 -164
- package/tests/BookReader/Mode2Up.test.js +0 -247
- package/tests/BookReader/PageContainer.test.js +0 -115
- package/tests/BookReader/utils.test.js +0 -109
- package/tests/e2e/helpers/desktopSearch.js +0 -72
- package/tests/e2e/helpers/mobileSearch.js +0 -85
- package/tests/e2e/ia-production/ia-prod-base.js +0 -17
- package/tests/karma/BookNavigator/book-navigator.test.js +0 -132
- package/tests/karma/BookNavigator/search/search-provider.test.js +0 -23
- package/tests/karma/BookNavigator/visual-adjustments.test.js +0 -201
- package/tests/plugins/menu_toggle/plugin.menu_toggle.test.js +0 -68
- package/tests/plugins/plugin.archive_analytics.test.js +0 -23
- package/tests/plugins/plugin.autoplay.test.js +0 -52
- package/tests/plugins/plugin.chapters.test.js +0 -130
- package/tests/plugins/plugin.mobile_nav.test.js +0 -66
- package/tests/plugins/plugin.text_selection.test.js +0 -203
- package/tests/util/docCookies.test.js +0 -15
@@ -1,6 +1,6 @@
|
|
1
1
|
|
2
|
-
import BookReader from '
|
3
|
-
import * as util from '
|
2
|
+
import BookReader from '@/src/BookReader.js';
|
3
|
+
import * as util from '@/src/plugins/plugin.vendor-fullscreen.js';
|
4
4
|
|
5
5
|
let br;
|
6
6
|
beforeEach(() => {
|
@@ -1,9 +1,9 @@
|
|
1
|
+
import BookReader from '@/src/BookReader.js';
|
2
|
+
import '@/src/plugins/search/plugin.search.js';
|
3
|
+
import { deepCopy } from '../../utils.js';
|
4
|
+
import { DUMMY_RESULTS } from './utils.js';
|
1
5
|
|
2
|
-
|
3
|
-
import '../../../src/plugins/plugin.mobile_nav.js';
|
4
|
-
import '../../../src/plugins/search/plugin.search.js';
|
5
|
-
|
6
|
-
jest.mock('../../../src/plugins/search/view.js');
|
6
|
+
jest.mock('@/src/plugins/search/view.js');
|
7
7
|
|
8
8
|
let br;
|
9
9
|
const namespace = 'BookReader:';
|
@@ -18,27 +18,7 @@ beforeEach(() => {
|
|
18
18
|
$.ajax = jest.fn().mockImplementation(() => {
|
19
19
|
// return from:
|
20
20
|
// `https://ia800304.us.archive.org/fulltext/inside.php?item_id=adventuresofoli00dick&doc=adventuresofoli00dick&path=/30/items/adventuresofoli00dick&q=child&callback=<serialized jQ CB>`
|
21
|
-
return Promise.resolve(
|
22
|
-
ia: "adventuresofoli00dick",
|
23
|
-
q: "child",
|
24
|
-
indexed: true,
|
25
|
-
page_count: 644,
|
26
|
-
body_length: 666,
|
27
|
-
leaf0_missing: false,
|
28
|
-
matches: [{
|
29
|
-
text: 'For a long; time after it was ushered into this world of sorrow and trouble, by the parish surgeon, it remained a matter of considerable doubt wliether the {{{child}}} Avould survi^ e to bear any name at all; in which case it is somewhat more than probable that these memoirs would never have appeared; or, if they had, that being comprised within a couple of pages, they would have possessed the inestimable meiit of being the most concise and faithful specimen of biography, extant in the literature of any age or country.',
|
30
|
-
par: [{
|
31
|
-
boxes: [{r: 1221, b: 2121, t: 2075, page: 37, l: 1107}],
|
32
|
-
b: 2535,
|
33
|
-
t: 1942,
|
34
|
-
page_width: 1790,
|
35
|
-
r: 1598,
|
36
|
-
l: 50,
|
37
|
-
page_height: 2940,
|
38
|
-
page: 37
|
39
|
-
}]
|
40
|
-
}]
|
41
|
-
});
|
21
|
+
return Promise.resolve(deepCopy(DUMMY_RESULTS));
|
42
22
|
});
|
43
23
|
|
44
24
|
$.fn.trigger = jest.fn();
|
@@ -102,7 +82,7 @@ describe('Plugin: Search', () => {
|
|
102
82
|
expect(br.search.mock.calls[0][1])
|
103
83
|
.toHaveProperty('goToFirstResult', true);
|
104
84
|
expect(br.search.mock.calls[0][1])
|
105
|
-
.toHaveProperty('suppressFragmentChange',
|
85
|
+
.toHaveProperty('suppressFragmentChange', false);
|
106
86
|
});
|
107
87
|
|
108
88
|
test('calling `search` fires ajax call`', () => {
|
@@ -123,28 +103,24 @@ describe('Plugin: Search', () => {
|
|
123
103
|
expect(br.options.goToFirstResult).toBeTruthy();
|
124
104
|
});
|
125
105
|
|
126
|
-
test('SearchCallback event fires when AJAX search returns results', () => {
|
106
|
+
test('SearchCallback event fires when AJAX search returns results', async () => {
|
127
107
|
br.init();
|
128
|
-
|
129
|
-
|
130
|
-
expect(triggeredEvents()).toContain(`${namespace}SearchCallback`);
|
131
|
-
});
|
108
|
+
await br.search('foo');
|
109
|
+
expect(triggeredEvents()).toContain(`${namespace}SearchCallback`);
|
132
110
|
});
|
133
111
|
|
134
|
-
test('SearchCallbackError event fires when AJAX search returns error', () => {
|
112
|
+
test('SearchCallbackError event fires when AJAX search returns error', async () => {
|
135
113
|
$.ajax = jest.fn().mockImplementation(() => {
|
136
114
|
return Promise.resolve({
|
137
115
|
error: true,
|
138
116
|
});
|
139
117
|
});
|
140
118
|
br.init();
|
141
|
-
|
142
|
-
|
143
|
-
expect(triggeredEvents()).toContain(`${namespace}SearchCallbackError`);
|
144
|
-
});
|
119
|
+
await br.search('foo');
|
120
|
+
expect(triggeredEvents()).toContain(`${namespace}SearchCallbackError`);
|
145
121
|
});
|
146
122
|
|
147
|
-
test('SearchCallbackNotIndexed event fires when AJAX search returns false indexed value', () => {
|
123
|
+
test('SearchCallbackNotIndexed event fires when AJAX search returns false indexed value', async () => {
|
148
124
|
$.ajax = jest.fn().mockImplementation(() => {
|
149
125
|
return Promise.resolve({
|
150
126
|
matches: [],
|
@@ -152,22 +128,18 @@ describe('Plugin: Search', () => {
|
|
152
128
|
});
|
153
129
|
});
|
154
130
|
br.init();
|
155
|
-
|
156
|
-
|
157
|
-
expect(triggeredEvents()).toContain(`${namespace}SearchCallbackBookNotIndexed`);
|
158
|
-
});
|
131
|
+
await br.search('foo');
|
132
|
+
expect(triggeredEvents()).toContain(`${namespace}SearchCallbackBookNotIndexed`);
|
159
133
|
});
|
160
134
|
|
161
|
-
test('SearchCallbackEmpty event fires when AJAX search returns no matches', () => {
|
135
|
+
test('SearchCallbackEmpty event fires when AJAX search returns no matches', async () => {
|
162
136
|
$.ajax = jest.fn().mockImplementation(() => {
|
163
137
|
return Promise.resolve({
|
164
138
|
matches: [],
|
165
139
|
});
|
166
140
|
});
|
167
141
|
br.init();
|
168
|
-
|
169
|
-
|
170
|
-
expect(triggeredEvents()).toContain(`${namespace}SearchCallbackEmpty`);
|
171
|
-
});
|
142
|
+
await br.search('foo');
|
143
|
+
expect(triggeredEvents()).toContain(`${namespace}SearchCallbackEmpty`);
|
172
144
|
});
|
173
145
|
});
|
@@ -1,8 +1,8 @@
|
|
1
1
|
|
2
|
-
import BookReader from '
|
3
|
-
import '
|
4
|
-
import '
|
5
|
-
import '
|
2
|
+
import BookReader from '@/src/BookReader.js';
|
3
|
+
import '@/src/plugins/search/plugin.search.js';
|
4
|
+
import { marshallSearchResults } from '@/src/plugins/search/utils.js';
|
5
|
+
import '@/src/plugins/search/view.js';
|
6
6
|
|
7
7
|
let br;
|
8
8
|
const namespace = 'BookReader:';
|
@@ -23,10 +23,35 @@ const results = {
|
|
23
23
|
r: 1598,
|
24
24
|
l: 50,
|
25
25
|
page_height: 2940,
|
26
|
-
page: 37
|
27
|
-
}]
|
28
|
-
}]
|
26
|
+
page: 37,
|
27
|
+
}],
|
28
|
+
}],
|
29
29
|
};
|
30
|
+
|
31
|
+
marshallSearchResults(results, () => '', '{{{', '}}}');
|
32
|
+
const resultWithScript = {
|
33
|
+
ia: "adventuresofoli00dick",
|
34
|
+
q: "child",
|
35
|
+
indexed: true,
|
36
|
+
page_count: 644,
|
37
|
+
body_length: 666,
|
38
|
+
leaf0_missing: false,
|
39
|
+
matches: [{
|
40
|
+
text: 'foo bar <script>alert(1);</script> {{{keyword}}} baz',
|
41
|
+
par: [{
|
42
|
+
boxes: [{r: 1221, b: 2121, t: 2075, page: 37, l: 1107}],
|
43
|
+
b: 2535,
|
44
|
+
t: 1942,
|
45
|
+
page_width: 1790,
|
46
|
+
r: 1598,
|
47
|
+
l: 50,
|
48
|
+
page_height: 2940,
|
49
|
+
page: 37,
|
50
|
+
}],
|
51
|
+
}],
|
52
|
+
};
|
53
|
+
|
54
|
+
marshallSearchResults(resultWithScript, () => '', '{{{', '}}}');
|
30
55
|
beforeEach(() => {
|
31
56
|
$.ajax = jest.fn().mockImplementation(() => {
|
32
57
|
// return from:
|
@@ -63,14 +88,14 @@ describe('View: Plugin: Search', () => {
|
|
63
88
|
|
64
89
|
expect(br.searchView.dom.searchNavigation).toBeUndefined();
|
65
90
|
|
66
|
-
br.searchView.handleSearchCallback(event, { results, options})
|
91
|
+
br.searchView.handleSearchCallback(event, { results, options});
|
67
92
|
expect(br.searchView.dom.searchNavigation).toBeDefined();
|
68
93
|
});
|
69
94
|
test('has controls', () => {
|
70
95
|
br.init();
|
71
96
|
const event = new CustomEvent(`${namespace}SearchCallback`);
|
72
97
|
const options = { goToFirstResult: false };
|
73
|
-
br.searchView.handleSearchCallback(event, { results, options})
|
98
|
+
br.searchView.handleSearchCallback(event, { results, options});
|
74
99
|
|
75
100
|
const searchResultsNav = document.querySelector('.BRsearch-navigation');
|
76
101
|
expect(searchResultsNav).toBeDefined();
|
@@ -81,6 +106,14 @@ describe('View: Plugin: Search', () => {
|
|
81
106
|
expect(searchResultsNav.querySelector('.prev')).toBeDefined();
|
82
107
|
expect(searchResultsNav.querySelector('.next')).toBeDefined();
|
83
108
|
});
|
109
|
+
test('disallows xss from search results', () => {
|
110
|
+
br.init();
|
111
|
+
const event = new CustomEvent(`${namespace}SearchCallback`);
|
112
|
+
const options = { goToFirstResult: false };
|
113
|
+
br.searchView.handleSearchCallback(event, { results: resultWithScript, options });
|
114
|
+
|
115
|
+
expect(br.searchView.dom.searchNavigation.parent().html()).not.toContain('<script>alert(1);</script>');
|
116
|
+
});
|
84
117
|
|
85
118
|
describe('Click events handlers', () => {
|
86
119
|
it('triggers custom event when toggling side menu', () => {
|
@@ -0,0 +1,25 @@
|
|
1
|
+
import { marshallSearchResults } from "@/src/plugins/search/utils";
|
2
|
+
|
3
|
+
export const DUMMY_RESULTS = {
|
4
|
+
ia: "adventuresofoli00dick",
|
5
|
+
q: "child",
|
6
|
+
indexed: true,
|
7
|
+
page_count: 644,
|
8
|
+
body_length: 666,
|
9
|
+
leaf0_missing: false,
|
10
|
+
matches: [{
|
11
|
+
text: 'For a long; time after it was ushered into this world of sorrow and trouble, by the parish surgeon, it remained a matter of considerable doubt wliether the {{{child}}} Avould survi^ e to bear any name at all; in which case it is somewhat more than probable that these memoirs would never have appeared; or, if they had, that being comprised within a couple of pages, they would have possessed the inestimable meiit of being the most concise and faithful specimen of biography, extant in the literature of any age or country.',
|
12
|
+
par: [{
|
13
|
+
boxes: [{r: 1221, b: 2121, t: 2075, page: 37, l: 1107}],
|
14
|
+
b: 2535,
|
15
|
+
t: 1942,
|
16
|
+
page_width: 1790,
|
17
|
+
r: 1598,
|
18
|
+
l: 50,
|
19
|
+
page_height: 2940,
|
20
|
+
page: 37,
|
21
|
+
}],
|
22
|
+
}],
|
23
|
+
};
|
24
|
+
|
25
|
+
marshallSearchResults(DUMMY_RESULTS, () => '', '{{{', '}}}');
|
@@ -0,0 +1,29 @@
|
|
1
|
+
import { marshallSearchResults, renderMatch } from '@/src/plugins/search/utils.js';
|
2
|
+
import { deepCopy } from '@/tests/jest/utils.js';
|
3
|
+
import { DUMMY_RESULTS } from './utils.js';
|
4
|
+
|
5
|
+
describe('renderMatch', () => {
|
6
|
+
test('Supports custom pre/post tags', () => {
|
7
|
+
const matchText = DUMMY_RESULTS.matches[0].text
|
8
|
+
.replace(/\{\{\{/g, '<IA_FTS_MATCH>')
|
9
|
+
.replace(/\}\}\}/g, '</IA_FTS_MATCH>');
|
10
|
+
const html = renderMatch(matchText, '<IA_FTS_MATCH>', '</IA_FTS_MATCH>');
|
11
|
+
expect(html).toContain('<mark>');
|
12
|
+
expect(html).toContain('</mark>');
|
13
|
+
});
|
14
|
+
});
|
15
|
+
|
16
|
+
describe('marshallSearchResults', () => {
|
17
|
+
test('Adds match index', () => {
|
18
|
+
const results = deepCopy(DUMMY_RESULTS);
|
19
|
+
marshallSearchResults(results, x => x.toString(), '{{{', '}}}');
|
20
|
+
expect(results.matches[0]).toHaveProperty('matchIndex', 0);
|
21
|
+
expect(results.matches[0].par[0].boxes[0]).toHaveProperty('matchIndex', 0);
|
22
|
+
});
|
23
|
+
|
24
|
+
test('Adds display page number', () => {
|
25
|
+
const results = deepCopy(DUMMY_RESULTS);
|
26
|
+
marshallSearchResults(results, x => `n${x}`, '{{{', '}}}');
|
27
|
+
expect(results.matches[0]).toHaveProperty('displayPageNumber', 'n37');
|
28
|
+
});
|
29
|
+
});
|
@@ -1,12 +1,12 @@
|
|
1
1
|
import sinon from 'sinon';
|
2
2
|
import { afterEventLoop } from '../../utils.js';
|
3
|
-
import AbstractTTSEngine from '
|
4
|
-
import PageChunkIterator from '
|
5
|
-
/** @typedef {import('
|
3
|
+
import AbstractTTSEngine from '@/src/plugins/tts/AbstractTTSEngine.js';
|
4
|
+
import PageChunkIterator from '@/src/plugins/tts/PageChunkIterator.js';
|
5
|
+
/** @typedef {import('@/src/plugins/tts/AbstractTTSEngine.js').TTSEngineOptions} TTSEngineOptions */
|
6
6
|
|
7
7
|
// Skipping because it's flaky. Fix in #672
|
8
8
|
describe.skip('AbstractTTSEngine', () => {
|
9
|
-
test('stops playing once done', () => {
|
9
|
+
test('stops playing once done', async () => {
|
10
10
|
class DummyEngine extends AbstractTTSEngine {
|
11
11
|
getVoices() { return []; }
|
12
12
|
}
|
@@ -15,12 +15,12 @@ describe.skip('AbstractTTSEngine', () => {
|
|
15
15
|
const stopStub = sinon.stub(d, 'stop');
|
16
16
|
expect(stopStub.callCount).toBe(0);
|
17
17
|
d.step();
|
18
|
-
|
19
|
-
|
18
|
+
await afterEventLoop();
|
19
|
+
expect(stopStub.callCount).toBe(1);
|
20
20
|
});
|
21
21
|
});
|
22
22
|
|
23
|
-
for (const dummyVoice of [
|
23
|
+
for (const dummyVoice of [dummyVoiceHyphens, dummyVoiceUnderscores]) {
|
24
24
|
describe(`getBestBookVoice with BCP47 ${dummyVoice == dummyVoiceUnderscores ? '+' : '-'} underscores`, () => {
|
25
25
|
const { getBestBookVoice } = AbstractTTSEngine;
|
26
26
|
|
@@ -106,11 +106,31 @@ for (const dummyVoice of [dummyVoice, dummyVoiceUnderscores]) {
|
|
106
106
|
{ default: false, lang: "ru-RU", name: "Google русский", localService: false, voiceURI: "Google русский" },
|
107
107
|
{ default: false, lang: "zh-CN", name: "Google 普通话(中国大陆)", localService: false, voiceURI: "Google 普通话(中国大陆)" },
|
108
108
|
{ default: false, lang: "zh-HK", name: "Google 粤語(香港)", localService: false, voiceURI: "Google 粤語(香港)" },
|
109
|
-
{ default: false, lang: "zh-TW", name: "Google 國語(臺灣)", localService: false, voiceURI: "Google 國語(臺灣)" }
|
109
|
+
{ default: false, lang: "zh-TW", name: "Google 國語(臺灣)", localService: false, voiceURI: "Google 國語(臺灣)" },
|
110
110
|
];
|
111
111
|
|
112
112
|
expect(getBestBookVoice(voices, 'en', ['en-CA', 'en'])).toBe(voices[0]);
|
113
113
|
});
|
114
|
+
|
115
|
+
test('choose stored language from localStorage', () => {
|
116
|
+
const voices = [
|
117
|
+
dummyVoice({lang: "en-US", voiceURI: "English US", default: true}),
|
118
|
+
dummyVoice({lang: "en-GB", voiceURI: "English GB"}),
|
119
|
+
dummyVoice({lang: "en-CA", voiceURI: "English CA"}),
|
120
|
+
];
|
121
|
+
class DummyEngine extends AbstractTTSEngine {
|
122
|
+
getVoices() { return voices; }
|
123
|
+
}
|
124
|
+
const ttsEngine = new DummyEngine({...DUMMY_TTS_ENGINE_OPTS, bookLanguage: 'en'});
|
125
|
+
// simulates setting default voice on tts startup
|
126
|
+
ttsEngine.updateBestVoice();
|
127
|
+
// simulates user choosing a voice that matches the bookLanguage
|
128
|
+
// voice will be stored in localStorage
|
129
|
+
ttsEngine.setVoice(voices[2].voiceURI);
|
130
|
+
|
131
|
+
// expecting the voice to be selected by getMatchingStoredVoice and returned as best voice
|
132
|
+
expect(getBestBookVoice(voices, 'en', [])).toBe(voices[2]);
|
133
|
+
});
|
114
134
|
});
|
115
135
|
}
|
116
136
|
|
@@ -130,7 +150,7 @@ export const DUMMY_TTS_ENGINE_OPTS = {
|
|
130
150
|
* @param {SpeechSynthesisVoice}
|
131
151
|
* @return {SpeechSynthesisVoice}
|
132
152
|
**/
|
133
|
-
function
|
153
|
+
function dummyVoiceHyphens(overrides) {
|
134
154
|
return Object.assign({
|
135
155
|
default: false,
|
136
156
|
lang: "en-US",
|
@@ -147,7 +167,7 @@ function dummyVoice(overrides) {
|
|
147
167
|
* @return {SpeechSynthesisVoice}
|
148
168
|
**/
|
149
169
|
function dummyVoiceUnderscores(overrides) {
|
150
|
-
const voice =
|
170
|
+
const voice = dummyVoiceHyphens(overrides);
|
151
171
|
voice.lang = voice.lang.replace('-', '_');
|
152
172
|
return voice;
|
153
173
|
}
|
@@ -1,10 +1,10 @@
|
|
1
|
-
import FestivalTTSEngine from '
|
1
|
+
import FestivalTTSEngine from '@/src/plugins/tts/FestivalTTSEngine.js';
|
2
2
|
import sinon from 'sinon';
|
3
3
|
import { afterEventLoop } from '../../utils.js';
|
4
4
|
import { DUMMY_TTS_ENGINE_OPTS } from './AbstractTTSEngine.test.js';
|
5
|
-
import PageChunk from '
|
6
|
-
import PageChunkIterator from '
|
7
|
-
/** @typedef {import('
|
5
|
+
import PageChunk from '@/src/plugins/tts/PageChunk.js';
|
6
|
+
import PageChunkIterator from '@/src/plugins/tts/PageChunkIterator.js';
|
7
|
+
/** @typedef {import('@/src/plugins/tts/AbstractTTSEngine.js').TTSEngineOptions} TTSEngineOptions */
|
8
8
|
|
9
9
|
describe('iOSCaptureUserIntentHack', () => {
|
10
10
|
test('synchronously calls createSound/play to capture user intent', () => {
|
@@ -1,6 +1,6 @@
|
|
1
1
|
import sinon from 'sinon';
|
2
|
-
import PageChunkIterator from "
|
3
|
-
import PageChunk from '
|
2
|
+
import PageChunkIterator from "@/src/plugins/tts/PageChunkIterator";
|
3
|
+
import PageChunk from '@/src/plugins/tts/PageChunk';
|
4
4
|
|
5
5
|
describe('Buffers pages', () => {
|
6
6
|
test('Does not error if no room for reverse buffer', async () => {
|
@@ -109,7 +109,7 @@ describe('Iterates pages', () => {
|
|
109
109
|
expect(iterator._cursor.chunk).toBe(0);
|
110
110
|
|
111
111
|
for (let i = 2; i >= 0; i--) {
|
112
|
-
await iterator.decrement()
|
112
|
+
await iterator.decrement();
|
113
113
|
expect(iterator._cursor.page).toBe(49);
|
114
114
|
expect(iterator._cursor.chunk).toBe(i);
|
115
115
|
}
|
@@ -1,5 +1,5 @@
|
|
1
1
|
import sinon from 'sinon';
|
2
|
-
import { WebTTSSound } from '
|
2
|
+
import WebTTSEngine, { WebTTSSound } from '@/src/plugins/tts/WebTTSEngine.js';
|
3
3
|
import { afterEventLoop, eventTargetMixin } from '../../utils.js';
|
4
4
|
|
5
5
|
beforeEach(() => {
|
@@ -8,6 +8,7 @@ beforeEach(() => {
|
|
8
8
|
speak: sinon.stub(),
|
9
9
|
pause: sinon.stub(),
|
10
10
|
resume: sinon.stub(),
|
11
|
+
|
11
12
|
...eventTargetMixin(),
|
12
13
|
};
|
13
14
|
window.SpeechSynthesisUtterance = function (text) {
|
@@ -21,6 +22,51 @@ afterEach(() => {
|
|
21
22
|
delete window.SpeechSynthesisUtterance;
|
22
23
|
});
|
23
24
|
|
25
|
+
describe('WebTTSEngine', () => {
|
26
|
+
test('getVoices should include default voice when no actual default', () => {
|
27
|
+
// iOS devices set all the voices to default -_-
|
28
|
+
speechSynthesis.getVoices = () => [
|
29
|
+
{
|
30
|
+
default: true,
|
31
|
+
lang: "ar-001",
|
32
|
+
localService: true,
|
33
|
+
name: "Majed",
|
34
|
+
voiceURI: "com.apple.voice.compact.ar-001.Maged",
|
35
|
+
},
|
36
|
+
{
|
37
|
+
default: true,
|
38
|
+
lang: "bg-BG",
|
39
|
+
localService: true,
|
40
|
+
name: "Daria",
|
41
|
+
voiceURI: "com.apple.voice.compact.bg-BG.Daria",
|
42
|
+
},
|
43
|
+
];
|
44
|
+
const voices = WebTTSEngine.prototype.getVoices();
|
45
|
+
expect(voices.length).toBe(3);
|
46
|
+
expect(voices[0].voiceURI).toBe('bookreader.SystemDefault');
|
47
|
+
});
|
48
|
+
|
49
|
+
test('getVoices should not include default voice when there is a default', () => {
|
50
|
+
speechSynthesis.getVoices = () => [
|
51
|
+
{
|
52
|
+
default: true,
|
53
|
+
lang: "ar-001",
|
54
|
+
localService: true,
|
55
|
+
name: "Majed",
|
56
|
+
voiceURI: "com.apple.voice.compact.ar-001.Maged",
|
57
|
+
},
|
58
|
+
{
|
59
|
+
default: false,
|
60
|
+
lang: "bg-BG",
|
61
|
+
localService: true,
|
62
|
+
name: "Daria",
|
63
|
+
voiceURI: "com.apple.voice.compact.bg-BG.Daria",
|
64
|
+
},
|
65
|
+
];
|
66
|
+
const voices = WebTTSEngine.prototype.getVoices();
|
67
|
+
expect(voices.length).toBe(2);
|
68
|
+
});
|
69
|
+
});
|
24
70
|
|
25
71
|
describe('WebTTSSound', () => {
|
26
72
|
describe('setPlaybackRate', () => {
|
@@ -1,38 +1,4 @@
|
|
1
|
-
import
|
2
|
-
import { afterEventLoop, eventTargetMixin } from '../../utils.js';
|
3
|
-
import * as utils from '../../../src/plugins/tts/utils.js';
|
4
|
-
|
5
|
-
describe('promisifyEvent', () => {
|
6
|
-
const { promisifyEvent } = utils;
|
7
|
-
|
8
|
-
test('Resolves once event fires', async () => {
|
9
|
-
const fakeTarget = eventTargetMixin();
|
10
|
-
const resolveSpy = sinon.spy();
|
11
|
-
promisifyEvent(fakeTarget, 'pause').then(resolveSpy);
|
12
|
-
|
13
|
-
await afterEventLoop()
|
14
|
-
expect(resolveSpy.callCount).toBe(0);
|
15
|
-
fakeTarget.dispatchEvent('pause', {});
|
16
|
-
await afterEventLoop();
|
17
|
-
expect(resolveSpy.callCount).toBe(1);
|
18
|
-
});
|
19
|
-
|
20
|
-
test('Only resolves once', async () => {
|
21
|
-
const fakeTarget = eventTargetMixin();
|
22
|
-
const resolveSpy = sinon.spy();
|
23
|
-
promisifyEvent(fakeTarget, 'pause').then(resolveSpy);
|
24
|
-
|
25
|
-
await afterEventLoop()
|
26
|
-
expect(resolveSpy.callCount).toBe(0);
|
27
|
-
fakeTarget.dispatchEvent('pause', {});
|
28
|
-
fakeTarget.dispatchEvent('pause', {});
|
29
|
-
fakeTarget.dispatchEvent('pause', {});
|
30
|
-
fakeTarget.dispatchEvent('pause', {});
|
31
|
-
|
32
|
-
await afterEventLoop();
|
33
|
-
expect(resolveSpy.callCount).toBe(1);
|
34
|
-
});
|
35
|
-
});
|
1
|
+
import * as utils from '@/src/plugins/tts/utils.js';
|
36
2
|
|
37
3
|
describe('approximateWordCount', () => {
|
38
4
|
const { approximateWordCount } = utils;
|
@@ -66,31 +32,6 @@ describe('approximateWordCount', () => {
|
|
66
32
|
});
|
67
33
|
});
|
68
34
|
|
69
|
-
describe('sleep', () => {
|
70
|
-
const { sleep } = utils;
|
71
|
-
|
72
|
-
test('Sleep 0 doest not called immediately', async () => {
|
73
|
-
const spy = sinon.spy();
|
74
|
-
sleep(0).then(spy);
|
75
|
-
expect(spy.callCount).toBe(0);
|
76
|
-
await afterEventLoop();
|
77
|
-
expect(spy.callCount).toBe(1);
|
78
|
-
});
|
79
|
-
|
80
|
-
test('Waits the appropriate ms', async () => {
|
81
|
-
const clock = sinon.useFakeTimers();
|
82
|
-
const spy = sinon.spy();
|
83
|
-
sleep(10).then(spy);
|
84
|
-
expect(spy.callCount).toBe(0);
|
85
|
-
clock.tick(10);
|
86
|
-
expect(spy.callCount).toBe(0);
|
87
|
-
clock.restore();
|
88
|
-
|
89
|
-
await afterEventLoop();
|
90
|
-
expect(spy.callCount).toBe(1);
|
91
|
-
});
|
92
|
-
});
|
93
|
-
|
94
35
|
describe('toISO6391', () => {
|
95
36
|
const { toISO6391 } = utils;
|
96
37
|
|