Skip to content
Draft
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 package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@
"nativewind": "^4.1.23",
"next": "^15.3.1",
"openai": "^4.90.0",
"prop-types": "^15.8.1",
"react": "18.3.1",
"react-dom": "18.3.1",
"react-native": "0.76.7",
Expand Down
231 changes: 231 additions & 0 deletions src/components/DoseCalculator.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
/**
* DoseCalculator PropTypes Validation Test
*
* This test file validates that PropTypes are working correctly
* for the DoseCalculator component during development.
*/

import React from 'react';
import DoseCalculator from './DoseCalculator';

// Mock React Native components for testing
jest.mock('react-native', () => ({
View: 'View',
Text: 'Text',
StyleSheet: {
create: (styles) => styles,
},
}));

describe('DoseCalculator PropTypes Validation', () => {
let originalError;
let errorSpy;

beforeEach(() => {
// Capture console.error to monitor PropTypes warnings
originalError = console.error;
errorSpy = jest.fn();
console.error = errorSpy;
});

afterEach(() => {
// Restore original console.error
console.error = originalError;
});

it('should have PropTypes defined', () => {
expect(DoseCalculator.propTypes).toBeDefined();
expect(typeof DoseCalculator.propTypes).toBe('object');
});

it('should have defaultProps defined', () => {
expect(DoseCalculator.defaultProps).toBeDefined();
expect(typeof DoseCalculator.defaultProps).toBe('object');
});

it('should accept valid props without PropTypes warnings', () => {
const validProps = {
dose: '100',
setDose: jest.fn(),
unit: 'mg',
setUnit: jest.fn(),
substanceName: 'Insulin',
setSubstanceName: jest.fn(),
medicationInputType: 'concentration',
setMedicationInputType: jest.fn(),
concentrationAmount: '100',
setConcentrationAmount: jest.fn(),
concentrationUnit: 'mg/ml',
setConcentrationUnit: jest.fn(),
totalAmount: '1000',
setTotalAmount: jest.fn(),
solutionVolume: '10',
setSolutionVolume: jest.fn(),
manualSyringe: { type: 'Insulin', volume: '1 ml' },
setManualSyringe: jest.fn(),
substanceNameHint: null,
setSubstanceNameHint: jest.fn(),
concentrationHint: null,
setConcentrationHint: jest.fn(),
totalAmountHint: null,
setTotalAmountHint: jest.fn(),
syringeHint: null,
setSyringeHint: jest.fn(),
};

// This should not generate any PropTypes warnings
React.createElement(DoseCalculator, validProps);

// In development mode, PropTypes warnings would be logged to console.error
// No warnings should occur with valid props
expect(errorSpy).not.toHaveBeenCalled();
});

it('should validate required props', () => {
const requiredProps = [
'setDose',
'setUnit',
'setSubstanceName',
'setMedicationInputType',
'setConcentrationAmount',
'setConcentrationUnit',
'setTotalAmount',
'setSolutionVolume',
'setManualSyringe',
'setSubstanceNameHint',
'setConcentrationHint',
'setTotalAmountHint',
'setSyringeHint'
];

requiredProps.forEach(prop => {
expect(DoseCalculator.propTypes[prop]).toBeDefined();
expect(DoseCalculator.propTypes[prop].isRequired).toBeTruthy();
});
});

it('should validate enum props correctly', () => {
const enumProps = {
unit: ['mg', 'mcg', 'units', 'mL'],
medicationInputType: ['concentration', 'totalAmount', null],
concentrationUnit: ['mg/ml', 'mcg/ml', 'units/ml'],
currentStep: [
'dose',
'medicationSource',
'concentrationInput',
'totalAmountInput',
'reconstitution',
'syringe',
'preDoseConfirmation',
'finalResult'
],
theme: ['light', 'dark', 'auto']
};

Object.entries(enumProps).forEach(([propName, validValues]) => {
expect(DoseCalculator.propTypes[propName]).toBeDefined();
// PropTypes oneOf validation exists (this is a structural test)
});
});

it('should validate manualSyringe shape prop', () => {
expect(DoseCalculator.propTypes.manualSyringe).toBeDefined();
// Verify it's a shape prop type (structural validation)
expect(typeof DoseCalculator.propTypes.manualSyringe).toBe('function');
});

it('should have reasonable default props', () => {
const defaults = DoseCalculator.defaultProps;

expect(defaults.dose).toBe('');
expect(defaults.unit).toBe('mg');
expect(defaults.substanceName).toBe('');
expect(defaults.medicationInputType).toBe(null);
expect(defaults.concentrationUnit).toBe('mg/ml');
expect(defaults.manualSyringe).toEqual({
type: 'Standard',
volume: '3 ml'
});
expect(defaults.currentStep).toBe('dose');
expect(defaults.isLoading).toBe(false);
expect(defaults.showValidation).toBe(true);
expect(defaults.theme).toBe('auto');
});

it('should validate function props', () => {
const functionProps = [
'setDose',
'setUnit',
'setSubstanceName',
'setMedicationInputType',
'setConcentrationAmount',
'setConcentrationUnit',
'setTotalAmount',
'setSolutionVolume',
'setManualSyringe',
'setSubstanceNameHint',
'setConcentrationHint',
'setTotalAmountHint',
'setSyringeHint',
'onStepChange',
'validateDoseInput',
'validateConcentrationInput',
'onCalculate',
'onReset',
'onComplete'
];

functionProps.forEach(prop => {
expect(DoseCalculator.propTypes[prop]).toBeDefined();
});
});

it('should validate number props', () => {
const numberProps = [
'doseValue',
'calculatedVolume',
'calculatedConcentration'
];

numberProps.forEach(prop => {
expect(DoseCalculator.propTypes[prop]).toBeDefined();
});
});

it('should validate boolean props', () => {
const booleanProps = [
'isLoading',
'showValidation'
];

booleanProps.forEach(prop => {
expect(DoseCalculator.propTypes[prop]).toBeDefined();
});
});
});

// Integration test to ensure component renders without errors
describe('DoseCalculator Component Integration', () => {
it('should render basic component structure', () => {
const mockProps = {
setDose: jest.fn(),
setUnit: jest.fn(),
setSubstanceName: jest.fn(),
setMedicationInputType: jest.fn(),
setConcentrationAmount: jest.fn(),
setConcentrationUnit: jest.fn(),
setTotalAmount: jest.fn(),
setSolutionVolume: jest.fn(),
setManualSyringe: jest.fn(),
setSubstanceNameHint: jest.fn(),
setConcentrationHint: jest.fn(),
setTotalAmountHint: jest.fn(),
setSyringeHint: jest.fn(),
};

// This should not throw any errors
expect(() => {
React.createElement(DoseCalculator, mockProps);
}).not.toThrow();
});
});
Loading