-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Prevented error thrown when ckeditor5-utils/src/env.ts
is used in an environment without window global object
#16370
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -4,7 +4,8 @@ | |
*/ | ||
|
||
import env, { | ||
isMac, isWindows, isGecko, isSafari, isiOS, isAndroid, isRegExpUnicodePropertySupported, isBlink, getUserAgent, isMediaForcedColors | ||
isMac, isWindows, isGecko, isSafari, isiOS, isAndroid, isRegExpUnicodePropertySupported, isBlink, getUserAgent, | ||
isMediaForcedColors, isMotionReduced | ||
} from '../src/env.js'; | ||
|
||
import global from '../src/dom/global.js'; | ||
|
@@ -64,9 +65,33 @@ describe( 'Env', () => { | |
} ); | ||
|
||
describe( 'isMediaForcedColors', () => { | ||
let matchMediaStub; | ||
|
||
beforeEach( () => { | ||
matchMediaStub = sinon.stub( global.window, 'matchMedia' ); | ||
} ); | ||
|
||
it( 'is a boolean', () => { | ||
expect( env.isMediaForcedColors ).to.be.a( 'boolean' ); | ||
mockMediaForcedColors(); | ||
|
||
expect( env.isMediaForcedColors ).to.be.true; | ||
} ); | ||
|
||
it( 'should watch changes in forced colors setting', () => { | ||
mockMediaForcedColors(); | ||
|
||
expect( env.isMediaForcedColors ).to.be.true; | ||
|
||
mockMediaForcedColors( false ); | ||
|
||
expect( env.isMediaForcedColors ).to.be.false; | ||
} ); | ||
|
||
function mockMediaForcedColors( enabled = true ) { | ||
return matchMediaStub | ||
.withArgs( '(forced-colors: active)' ) | ||
.returns( { matches: enabled } ); | ||
} | ||
} ); | ||
|
||
describe( 'isMotionReduced', () => { | ||
|
@@ -326,6 +351,44 @@ describe( 'Env', () => { | |
|
||
expect( isMediaForcedColors() ).to.be.false; | ||
} ); | ||
|
||
it( 'returns false if window object is not available', () => { | ||
// `global.window` is an empty object if `window` was not available in global space. | ||
const _window = global.window; | ||
global.window = {}; | ||
|
||
expect( isMediaForcedColors() ).to.be.false; | ||
|
||
global.window = _window; | ||
} ); | ||
} ); | ||
|
||
describe( 'isMotionReduced()', () => { | ||
Mati365 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
it( 'returns true if the document media query matches prefers-reduced-motion', () => { | ||
testUtils.sinon.stub( global.window, 'matchMedia' ) | ||
.withArgs( '(prefers-reduced-motion)' ) | ||
.returns( { matches: true } ); | ||
|
||
expect( isMotionReduced() ).to.be.true; | ||
} ); | ||
|
||
it( 'returns false if the document media query does not match prefers-reduced-motion', () => { | ||
testUtils.sinon.stub( global.window, 'matchMedia' ) | ||
.withArgs( '(prefers-reduced-motion)' ) | ||
.returns( { matches: false } ); | ||
|
||
expect( isMotionReduced() ).to.be.false; | ||
} ); | ||
|
||
it( 'returns false if window object is not available', () => { | ||
// `global.window` is an empty object if `window` was not available in global space. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If you have a better idea how to mock, please suggest. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only thing I can think of is the use of before/after() so it's properly cleaned up on a fail, but it's a simple test so I don't see this as a must-have. |
||
const _window = global.window; | ||
global.window = {}; | ||
|
||
expect( isMotionReduced() ).to.be.false; | ||
|
||
global.window = _window; | ||
} ); | ||
} ); | ||
|
||
describe( 'isRegExpUnicodePropertySupported()', () => { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I first wanted to get rid of these getters and make it so that the property is resolved immediately (just like all other
is*
properties above). However, the existing tests were failing and it appeared that we test whether the util reacts to the change of related settings.Indeed, this setting can change (tested that), so I decided to keep these functions as getters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doh... so maybe this should be a function? To indicate that it's a dynamic value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's an API change, but from what I understand this is a freshly introduced prop and that'd be fine (not a breaking change, IMO).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
All the other properties of the
env
object are static (should not change with time) except the two recently introduced. So it'd make sense to think twice before we commit in any direction.