Skip to content
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

Add Basic Test Framework and Tests #121

Merged
merged 4 commits into from
Jun 12, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"react/destructuring-assignment": 0,
"react/jsx-filename-extension": 0,
"no-plusplus": 0,
"react/forbid-prop-types": 0,
"no-param-reassign": ["error", { "props": false }],
"prefer-destructuring": ["error", { "object": true, "array": false }],
"react/no-unused-class-component-methods": 0,
Expand Down
3 changes: 3 additions & 0 deletions .github/workflows/smoke_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ jobs:

- name: Install dependencies
run: npm install --legacy-peer-deps

- name: Install dev dependencies
run: npm install --only=dev

- name: Run test
run: npm test
3 changes: 3 additions & 0 deletions babel.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module.exports = {
presets: ['@babel/preset-env', '@babel/preset-react'],
};
1 change: 1 addition & 0 deletions config/wines_data.json

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
module.exports = {
testEnvironment: 'jsdom',
moduleFileExtensions: ['js', 'jsx'],
transform: {
'^.+\\.jsx?$': 'babel-jest',
},
moduleNameMapper: {
'\\.css$': 'identity-obj-proxy',
},
transformIgnorePatterns: [
'/node_modules/(?!react-dnd)/', // Ignore node_modules except for react-dnd
],
setupFilesAfterEnv: ['@testing-library/jest-dom', './tests/setupTests.js'],
};

12,518 changes: 8,085 additions & 4,433 deletions package-lock.json

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
"scripts": {
"lint": "eslint source",
"lint:fix": "eslint source --fix",
"test": "npm run-script build",
"test": "jest",
"build": "parcel build source/index.html --public-url ./",
"dev": "parcel source/index.html"
},
Expand Down Expand Up @@ -63,6 +63,10 @@
"vega-lite": "^4.17.0"
},
"devDependencies": {
"@babel/preset-react": "^7.24.7",
"@testing-library/jest-dom": "^6.4.6",
"@testing-library/react": "^16.0.0",
"cross-fetch": "^4.0.0",
"eslint": "^8.52.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-prettier": "^8.10.0",
Expand All @@ -71,6 +75,10 @@
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.33.2",
"eslint-plugin-react-hooks": "^4.6.0",
"identity-obj-proxy": "^3.0.0",
"jest": "^29.7.0",
"jest-environment-jsdom": "^29.7.0",
"node-fetch": "^3.3.2",
"parcel-plugin-static-files-copy": "^2.6.0",
"prettier": "^2.8.8",
"sass": "^1.69.5"
Expand Down
12 changes: 4 additions & 8 deletions source/Application.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,18 +3,14 @@ import Eaglescope from './components/Eaglescope/Eaglescope';
import ConfigContextProvider from './contexts/ConfigContext';
import DataContextProvider from './contexts/DataContext';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap'; // <-- JS File
import 'bootstrap';

// style

function APP() {
function APP({ overrideConfig, overrideData }) {
const query = new URLSearchParams(window.location.search);
const configUrl = query.get('configurl') || './config/wines.json';

//
return (
<ConfigContextProvider configName={configUrl}>
<DataContextProvider>
<ConfigContextProvider configName={configUrl} overrideConfig={overrideConfig}>
<DataContextProvider overrideData={overrideData}>
<Eaglescope />
</DataContextProvider>
</ConfigContextProvider>
Expand Down
2 changes: 1 addition & 1 deletion source/components/Layout/VisGridView/VisGridView.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ function VisGridView({ fullVisScreenHandler, fullScreened }) {
width: 0,
currentCols: 0,
layout: [],
margin: 0,
margins: [], // Initialize margins as an empty array or with default values
grid,
});
const self = useRef();
Expand Down
51 changes: 38 additions & 13 deletions source/contexts/ConfigContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,28 +4,53 @@ import useFetch from '../hooks/useFetch';

export const ConfigContext = createContext();

export default function ConfigContextProvider({ children, configName }) {
const {
error: configError,
data: config,
isPending: configLoading,
setData: setConfig,
} = useFetch(`${configName}`);
export default function ConfigContextProvider({ children, configName, overrideConfig }) {
let configData;

if (overrideConfig) {
// If overrideConfig is provided, use it directly
configData = {
error: false,
data: overrideConfig,
isPending: false,
setData: console.error,
};
} else {
// Otherwise, fetch the data using useFetch
const {
error: configError,
data: config,
isPending: configLoading,
setData: setConfig,
} = useFetch(`${configName}`);

configData = {
error: configError,
data: config,
isPending: configLoading,
setData: setConfig,
};
}

const memoConfig = useMemo(
() => ({
configError,
config,
configLoading,
setConfig,
configError: configData.error,
config: configData.data,
configLoading: configData.isPending,
setConfig: configData.setData,
}),
[config, configLoading, configError],
[configData],
);

return <ConfigContext.Provider value={memoConfig}>{children}</ConfigContext.Provider>;
}

ConfigContextProvider.propTypes = {
children: PropTypes.shape().isRequired,
children: PropTypes.node.isRequired,
configName: PropTypes.string.isRequired,
overrideConfig: PropTypes.object, // Optional parameter to override configuration data
};

ConfigContextProvider.defaultProps = {
overrideConfig: false,
};
18 changes: 15 additions & 3 deletions source/contexts/DataContext.js
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,21 @@ function filterData(data, filters) {

export const DataContext = createContext();

export default function DataContextProvider({ children }) {
export default function DataContextProvider({ children, overrideData }) {
const { config } = useContext(ConfigContext);
const [loading, setLoading] = useState(true);
const [filteredData, setFilteredData] = useState([]);
const filtersRef = useRef();
const [filters, setFilters] = useState([]);
const { error: dataError, data } = useFetch(config?.DATA_RESOURCE_URL, config?.DATA_FORMAT);

let data;
let dataError;
if (overrideData) {
data = overrideData;
} else {
const { error, data: fetchedData } = useFetch(config?.DATA_RESOURCE_URL, config?.DATA_FORMAT);
dataError = error;
data = fetchedData;
}
const addFiltersHandler = (toAddFilters) => {
const oldFilters = [...filtersRef.current];
// remove first
Expand Down Expand Up @@ -145,4 +152,9 @@ export default function DataContextProvider({ children }) {

DataContextProvider.propTypes = {
children: PropTypes.shape().isRequired,
overrideData: PropTypes.object, // Optional parameter to override configuration data
};

DataContextProvider.defaultProps = {
overrideData: false,
};
30 changes: 30 additions & 0 deletions tests/App.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';
import { render, screen, waitFor } from '@testing-library/react';

import App from '../source/Application';

import testConfig from '../config/wines.json';
import testData from '../config/wines_data.json';



describe('Eaglescope basic tests', () => {
test('renders title from config', async () => {
const container = render(
<App overrideConfig={testConfig} overrideData={testData}/>
);
await waitFor(() => {
const titleElement = screen.getByText('Eaglescope Demo | Wines');
expect(titleElement).toBeInTheDocument();
});
});
test('renders vis elems', async () => {
const container = render(
<App overrideConfig={testConfig} overrideData={testData}/>
);
await waitFor(() => {
const elements = document.getElementsByClassName('vis-grid-item');
expect(elements.length).toBeGreaterThan(6);
});
});
});
12 changes: 12 additions & 0 deletions tests/setupTests.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
const fetch = require('cross-fetch');

global.fetch = fetch;


window.matchMedia = jest.fn().mockImplementation(query => ({
matches: false,
media: query,
onchange: null,
addListener: jest.fn(), // Deprecated, but still used in some cases
removeListener: jest.fn(), // Deprecated, but still used in some cases
}));
Loading