Skip to content

Commit

Permalink
feat/long term quick adaptation screen
Browse files Browse the repository at this point in the history
  • Loading branch information
sebastien-perpignane committed Oct 29, 2023
1 parent fa6b6eb commit 9a36148
Show file tree
Hide file tree
Showing 5 changed files with 178 additions and 0 deletions.
5 changes: 5 additions & 0 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {NavigationContainer} from '@react-navigation/native'
import {PunctualGlycemiaScreen} from './screens/PunctualGlycemiaScreen'
import {HomeScreen} from './screens/HomeScreen'
import {BasalAdaptationScreen} from './screens/BasalAdaptationScreen'
import {QuickInsulinAdaptationScreen} from './screens/QuickInsulinAdaptationScreen'

const Stack = createNativeStackNavigator()

Expand All @@ -24,6 +25,10 @@ function App(): JSX.Element {
name="Punctual quick adaptation"
component={PunctualGlycemiaScreen}
/>
<Stack.Screen
name="Long term quick adaptation"
component={QuickInsulinAdaptationScreen}
/>
<Stack.Screen name="Basal" component={BasalAdaptationScreen} />
</Stack.Navigator>
</NavigationContainer>
Expand Down
8 changes: 8 additions & 0 deletions src/__tests__/App.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -41,3 +41,11 @@ it('navigates well to basal screen', () => {
let basalElement = screen.getByTestId('basal')
fireEvent(basalElement, 'onPress')
})

it('navigates well to longterm quick adaptation screen', () => {
const SampleApp = () => <App />

render(<SampleApp />)
let longtermElement = screen.getByTestId('longterm')
fireEvent(longtermElement, 'onPress')
})
7 changes: 7 additions & 0 deletions src/screens/HomeScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,13 @@ export function HomeScreen({navigation}: any): JSX.Element {
navigation.navigate('Punctual quick adaptation')
}}
/>
<DbButton
title="Long term quick adaptation"
testID="longterm"
onPress={() => {
navigation.navigate('Long term quick adaptation')
}}
/>
<DbButton
title="Basal adaptation"
testID="basal"
Expand Down
122 changes: 122 additions & 0 deletions src/screens/QuickInsulinAdaptationScreen.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
import React from 'react'
import {Appearance, ScrollView, StatusBar, View} from 'react-native'
import {SafeAreaView} from 'react-native-safe-area-context'
import {screenStyles} from './styles'
import {Colors} from 'react-native/Libraries/NewAppScreen'
import {MealGlycemiaMeasure, QuickInsulin} from '../core/QuickInsulin'
import {Text} from 'react-native-paper'
import {DbNumericTextInput} from '../components/DbNumericTextInputComponent'

interface QuickInsulinAdaptationState {
glycemiasAfter: number[]
adaptation: number | undefined
}

export class QuickInsulinAdaptationScreen extends React.Component<
{},
QuickInsulinAdaptationState
> {
constructor(props: {}) {
super(props)
this.state = {
glycemiasAfter: new Array(3),
adaptation: undefined,
}
}

manageComputation = () => {
const containsInvalidElement = (numbers: number[]): boolean => {
for (let n of numbers) {
if (n === undefined || isNaN(n)) {
return true
}
}
return false
}

if (containsInvalidElement(this.state.glycemiasAfter)) {
this.setState({
adaptation: undefined,
})
return
}

let quickInsulin = new QuickInsulin()

let objective = quickInsulin.findObjectiveCriterion()
if (
objective === undefined ||
objective.min === undefined ||
objective.max === undefined
) {
throw new Error('Check your configuration. Objective not found')
}
let lObjective: {min: number; max: number} = objective
let measures = this.state.glycemiasAfter.map(
g => new MealGlycemiaMeasure(g, lObjective),
)
let adaptation = quickInsulin.computeLongtermAdaptation(measures)
this.setState({
adaptation: adaptation,
})
}

render(): React.ReactNode {
const manageGlycemiaAfter = (i: number, glycemiaStr: string) => {
let newAfter = Array.from(this.state.glycemiasAfter)
newAfter[i] = parseFloat(glycemiaStr)

this.setState(
{
glycemiasAfter: newAfter,
},
this.manageComputation,
)
}

const glycemiaIntervalInputs = []
for (let i = 0; i < 3; i++) {
glycemiaIntervalInputs.push(
<View key={i} style={screenStyles.intervalContainer}>
<Text style={screenStyles.intervalLabel}>
Glycemia measure {i + 1}:{' '}
</Text>
<DbNumericTextInput
testID={'glycemiaAfterInput' + (i + 1)}
placeholder={'glycemia after ' + (i + 1)}
onChangeText={newtText => {
manageGlycemiaAfter(i, newtText)
}}
/>
</View>,
)
}

const isDarkMode = Appearance.getColorScheme() === 'dark'

const backgroundStyle = {
backgroundColor: isDarkMode ? Colors.darker : Colors.lighter,
}

return (
<SafeAreaView style={screenStyles.screenBackground}>
<StatusBar
barStyle={isDarkMode ? 'light-content' : 'dark-content'}
backgroundColor={backgroundStyle.backgroundColor}
/>
<ScrollView
contentInsetAdjustmentBehavior="automatic"
style={backgroundStyle}>
<View>{glycemiaIntervalInputs}</View>
<View>
{this.state.adaptation !== undefined && (
<Text testID='adaptationResult' style={screenStyles.intervalLabel}>
Adaptation: {this.state.adaptation}
</Text>
)}
</View>
</ScrollView>
</SafeAreaView>
)
}
}
36 changes: 36 additions & 0 deletions src/screens/__tests__/QuickInsulinAdaptationScreen.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import 'react-native'
import React from 'react'

// Note: import explicitly to use the types shiped with jest.
import {it, expect} from '@jest/globals'

// Note: test renderer must be required after react-native.
//import renderer from 'react-test-renderer';
import {fireEvent, render, screen} from '@testing-library/react-native'
import {BasalAdaptationScreen} from '../BasalAdaptationScreen'
import { QuickInsulinAdaptationScreen } from '../QuickInsulinAdaptationScreen'

it('renders correctly', () => {
let SampleScreen = () => <QuickInsulinAdaptationScreen />

render(<SampleScreen />)

for (let i = 1; i < 4; i++) {
expect(screen.getByTestId('glycemiaAfterInput' + i)).toBeDefined()
}
expect(() => screen.getByTestId('adaptationResult')).toThrowError()
})

it('display result when all glycemia levels are entered', () => {
let SampleScreen = () => <QuickInsulinAdaptationScreen />

render(<SampleScreen />)

for (let i = 1; i < 4; i++) {
let currentBeforeInput = screen.getByTestId('glycemiaAfterInput' + i)
fireEvent.changeText(currentBeforeInput, '1.2')
}

expect(screen.getByTestId('adaptationResult').props.children).toBeDefined()
expect(screen.getByTestId('adaptationResult').props.children).toEqual(["Adaptation: ", 0])
})

0 comments on commit 9a36148

Please sign in to comment.