aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-web/design-system/src/helpers/__tests__
diff options
context:
space:
mode:
Diffstat (limited to 'server/sonar-web/design-system/src/helpers/__tests__')
-rw-r--r--server/sonar-web/design-system/src/helpers/__tests__/colors-test.ts61
-rw-r--r--server/sonar-web/design-system/src/helpers/__tests__/positioning-test.ts167
-rw-r--r--server/sonar-web/design-system/src/helpers/__tests__/theme-test.ts148
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)'
+ );
+ });
+});