diff options
Diffstat (limited to 'server/sonar-web/design-system/src/helpers/__tests__')
3 files changed, 376 insertions, 0 deletions
diff --git a/server/sonar-web/design-system/src/helpers/__tests__/colors-test.ts b/server/sonar-web/design-system/src/helpers/__tests__/colors-test.ts new file mode 100644 index 00000000000..eead6e02c5c --- /dev/null +++ b/server/sonar-web/design-system/src/helpers/__tests__/colors-test.ts @@ -0,0 +1,61 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as colors from '../colors'; + +describe('#stringToColor', () => { + it('should return a color for a text', () => { + expect(colors.stringToColor('skywalker')).toBe('#97f047'); + }); +}); + +describe('#isDarkColor', () => { + it('should be dark', () => { + expect(colors.isDarkColor('#000000')).toBe(true); + expect(colors.isDarkColor('#222222')).toBe(true); + expect(colors.isDarkColor('#000')).toBe(true); + }); + it('should be light', () => { + expect(colors.isDarkColor('#FFFFFF')).toBe(false); + expect(colors.isDarkColor('#CDCDCD')).toBe(false); + expect(colors.isDarkColor('#FFF')).toBe(false); + }); +}); + +describe('#getTextColor', () => { + it('should return dark color', () => { + expect(colors.getTextColor('#FFF', 'dark', 'light')).toBe('dark'); + expect(colors.getTextColor('#FFF')).toBe('#222'); + }); + it('should return light color', () => { + expect(colors.getTextColor('#000', 'dark', 'light')).toBe('light'); + expect(colors.getTextColor('#000')).toBe('#fff'); + }); +}); + +describe('rgb array to color', () => { + it('should return rgb color without opacity', () => { + expect(colors.getRGBAString([0, 0, 0])).toBe('rgb(0,0,0)'); + expect(colors.getRGBAString([255, 255, 255])).toBe('rgb(255,255,255)'); + }); + it('should return rgba color with opacity', () => { + expect(colors.getRGBAString([5, 6, 100], 0.05)).toBe('rgba(5,6,100,0.05)'); + expect(colors.getRGBAString([255, 255, 255], 0)).toBe('rgba(255,255,255,0)'); + }); +}); diff --git a/server/sonar-web/design-system/src/helpers/__tests__/positioning-test.ts b/server/sonar-web/design-system/src/helpers/__tests__/positioning-test.ts new file mode 100644 index 00000000000..7953d3531c9 --- /dev/null +++ b/server/sonar-web/design-system/src/helpers/__tests__/positioning-test.ts @@ -0,0 +1,167 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import { PopupPlacement, popupPositioning } from '../positioning'; + +const toggleRect = { + getBoundingClientRect: jest.fn().mockReturnValue({ + left: 400, + top: 200, + width: 50, + height: 20, + }), +} as any; + +const popupRect = { + getBoundingClientRect: jest.fn().mockReturnValue({ + width: 200, + height: 100, + }), +} as any; + +beforeAll(() => { + Object.defineProperties(document.documentElement, { + clientWidth: { + configurable: true, + value: 1000, + }, + clientHeight: { + configurable: true, + value: 1000, + }, + }); +}); + +it('should calculate positioning based on placement', () => { + const fixes = { leftFix: 0, topFix: 0 }; + expect(popupPositioning(toggleRect, popupRect, PopupPlacement.Bottom)).toMatchObject({ + left: 325, + top: 220, + ...fixes, + }); + expect(popupPositioning(toggleRect, popupRect, PopupPlacement.BottomLeft)).toMatchObject({ + left: 400, + top: 220, + ...fixes, + }); + expect(popupPositioning(toggleRect, popupRect, PopupPlacement.BottomRight)).toMatchObject({ + left: 250, + top: 220, + ...fixes, + }); + expect(popupPositioning(toggleRect, popupRect, PopupPlacement.Top)).toMatchObject({ + left: 325, + top: 100, + ...fixes, + }); + expect(popupPositioning(toggleRect, popupRect, PopupPlacement.TopLeft)).toMatchObject({ + left: 400, + top: 100, + ...fixes, + }); + expect(popupPositioning(toggleRect, popupRect, PopupPlacement.TopRight)).toMatchObject({ + left: 250, + top: 100, + ...fixes, + }); + expect(popupPositioning(toggleRect, popupRect, PopupPlacement.Left)).toMatchObject({ + left: 200, + top: 160, + ...fixes, + }); + expect(popupPositioning(toggleRect, popupRect, PopupPlacement.LeftBottom)).toMatchObject({ + left: 200, + top: 120, + ...fixes, + }); + expect(popupPositioning(toggleRect, popupRect, PopupPlacement.LeftTop)).toMatchObject({ + left: 200, + top: 200, + ...fixes, + }); + expect(popupPositioning(toggleRect, popupRect, PopupPlacement.Right)).toMatchObject({ + left: 450, + top: 160, + ...fixes, + }); + expect(popupPositioning(toggleRect, popupRect, PopupPlacement.RightBottom)).toMatchObject({ + left: 450, + top: 120, + ...fixes, + }); + expect(popupPositioning(toggleRect, popupRect, PopupPlacement.RightTop)).toMatchObject({ + left: 450, + top: 200, + ...fixes, + }); +}); + +it('should position the element in the boundaries of the screen', () => { + toggleRect.getBoundingClientRect.mockReturnValueOnce({ + left: 0, + top: 850, + width: 50, + height: 50, + }); + expect(popupPositioning(toggleRect, popupRect, PopupPlacement.Bottom)).toMatchObject({ + left: 4, + leftFix: 79, + top: 896, + topFix: -4, + }); + toggleRect.getBoundingClientRect.mockReturnValueOnce({ + left: 900, + top: 0, + width: 50, + height: 50, + }); + expect(popupPositioning(toggleRect, popupRect, PopupPlacement.Top)).toMatchObject({ + left: 796, + leftFix: -29, + top: 4, + topFix: 104, + }); +}); + +it('should position the element outside the boundaries of the screen when the toggle is outside', () => { + toggleRect.getBoundingClientRect.mockReturnValueOnce({ + left: -100, + top: 1100, + width: 50, + height: 50, + }); + expect(popupPositioning(toggleRect, popupRect, PopupPlacement.Bottom)).toMatchObject({ + left: -75, + leftFix: 100, + top: 1025, + topFix: -125, + }); + toggleRect.getBoundingClientRect.mockReturnValueOnce({ + left: 1500, + top: -200, + width: 50, + height: 50, + }); + expect(popupPositioning(toggleRect, popupRect, PopupPlacement.Top)).toMatchObject({ + left: 1325, + leftFix: -100, + top: -175, + topFix: 125, + }); +}); diff --git a/server/sonar-web/design-system/src/helpers/__tests__/theme-test.ts b/server/sonar-web/design-system/src/helpers/__tests__/theme-test.ts new file mode 100644 index 00000000000..66f1b97ce05 --- /dev/null +++ b/server/sonar-web/design-system/src/helpers/__tests__/theme-test.ts @@ -0,0 +1,148 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +import * as ThemeHelper from '../../helpers/theme'; +import { lightTheme } from '../../theme'; + +const props = { + color: 'rgb(0,0,0)', +}; + +describe('getProp', () => { + it('should work', () => { + expect(ThemeHelper.getProp('color')(props)).toEqual('rgb(0,0,0)'); + }); +}); + +describe('themeColor', () => { + it('should work for light theme', () => { + expect(ThemeHelper.themeColor('backgroundPrimary')({ theme: lightTheme })).toEqual( + 'rgb(252,252,253)' + ); + }); + + it('should work with a theme-defined opacity', () => { + expect(ThemeHelper.themeColor('bannerIconHover')({ theme: lightTheme })).toEqual( + 'rgba(217,45,32,0.2)' + ); + }); + + it('should work for all kind of color parameters', () => { + expect(ThemeHelper.themeColor('transparent')({ theme: lightTheme })).toEqual('transparent'); + expect(ThemeHelper.themeColor('currentColor')({ theme: lightTheme })).toEqual('currentColor'); + expect(ThemeHelper.themeColor('var(--test)')({ theme: lightTheme })).toEqual('var(--test)'); + expect(ThemeHelper.themeColor('rgb(0,0,0)')({ theme: lightTheme })).toEqual('rgb(0,0,0)'); + expect(ThemeHelper.themeColor('rgba(0,0,0,1)')({ theme: lightTheme })).toEqual('rgba(0,0,0,1)'); + expect( + ThemeHelper.themeColor(ThemeHelper.themeContrast('backgroundPrimary')({ theme: lightTheme }))( + { + theme: lightTheme, + } + ) + ).toEqual('rgb(8,9,12)'); + expect( + ThemeHelper.themeColor(ThemeHelper.themeAvatarColor('luke')({ theme: lightTheme }))({ + theme: lightTheme, + }) + ).toEqual('rgb(209,215,254)'); + }); +}); + +describe('themeContrast', () => { + it('should work for light theme', () => { + expect(ThemeHelper.themeContrast('backgroundPrimary')({ theme: lightTheme })).toEqual( + 'rgb(8,9,12)' + ); + }); + + it('should work for all kind of color parameters', () => { + expect(ThemeHelper.themeContrast('var(--test)')({ theme: lightTheme })).toEqual('var(--test)'); + expect(ThemeHelper.themeContrast('rgb(0,0,0)')({ theme: lightTheme })).toEqual('rgb(0,0,0)'); + expect(ThemeHelper.themeContrast('rgba(0,0,0,1)')({ theme: lightTheme })).toEqual( + 'rgba(0,0,0,1)' + ); + expect( + ThemeHelper.themeContrast(ThemeHelper.themeColor('backgroundPrimary')({ theme: lightTheme }))( + { + theme: lightTheme, + } + ) + ).toEqual('rgb(252,252,253)'); + expect( + ThemeHelper.themeContrast(ThemeHelper.themeAvatarColor('luke')({ theme: lightTheme }))({ + theme: lightTheme, + }) + ).toEqual('rgb(209,215,254)'); + expect( + ThemeHelper.themeContrast('backgroundPrimary')({ + theme: { + ...lightTheme, + contrasts: { ...lightTheme.contrasts, backgroundPrimary: 'inherit' }, + }, + }) + ).toEqual('inherit'); + }); +}); + +describe('themeBorder', () => { + it('should work for light theme', () => { + expect(ThemeHelper.themeBorder()({ theme: lightTheme })).toEqual('1px solid rgb(235,235,235)'); + }); + it('should allow to override the color of the border', () => { + expect(ThemeHelper.themeBorder('focus', 'primaryLight')({ theme: lightTheme })).toEqual( + '4px solid rgba(123,135,217,0.2)' + ); + }); + it('should allow to override the opacity of the border', () => { + expect(ThemeHelper.themeBorder('focus', undefined, 0.5)({ theme: lightTheme })).toEqual( + '4px solid rgba(197,205,223,0.5)' + ); + }); + it('should allow to pass a CSS prop as color name', () => { + expect( + ThemeHelper.themeBorder('focus', 'var(--outlineColor)', 0.5)({ theme: lightTheme }) + ).toEqual('4px solid var(--outlineColor)'); + }); +}); + +describe('themeShadow', () => { + it('should work for light theme', () => { + expect(ThemeHelper.themeShadow('xs')({ theme: lightTheme })).toEqual( + '0px 1px 2px 0px rgba(29,33,47,0.05)' + ); + }); + it('should allow to override the color of the shadow', () => { + expect(ThemeHelper.themeShadow('xs', 'backgroundPrimary')({ theme: lightTheme })).toEqual( + '0px 1px 2px 0px rgba(252,252,253,0.05)' + ); + expect(ThemeHelper.themeShadow('xs', 'transparent')({ theme: lightTheme })).toEqual( + '0px 1px 2px 0px transparent' + ); + }); + it('should allow to override the opacity of the shadow', () => { + expect(ThemeHelper.themeShadow('xs', 'backgroundPrimary', 0.8)({ theme: lightTheme })).toEqual( + '0px 1px 2px 0px rgba(252,252,253,0.8)' + ); + }); + it('should allow to pass a CSS prop as color name', () => { + expect(ThemeHelper.themeShadow('xs', 'var(--shadowColor)')({ theme: lightTheme })).toEqual( + '0px 1px 2px 0px var(--shadowColor)' + ); + }); +}); |