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

fix: eslint and linting issues, addition of PR and testing workflows #46

Merged
merged 3 commits into from
Sep 13, 2023
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.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
module.exports = {
root: true,
extends: '@react-native',
ignorePatterns: ['e2e/'],
};
13 changes: 13 additions & 0 deletions .github/workflows/pr-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
name: Check PR title

on:
pull_request:
types: [opened, edited, synchronize, reopened]

jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: aslafy-z/conventional-pr-title-action@v3
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43 changes: 43 additions & 0 deletions .github/workflows/unit-testing.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Unit Testing
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
on:
push:
branches:
- main
pull_request:
types: [opened, synchronize, reopened]

jobs:
install-lint-test-scan:
runs-on: ubuntu-latest
steps:
# Checkout the repository
- uses: actions/checkout@v3
with:
fetch-depth: 0
# Setup Node environment
- name: Setup Node
uses: actions/setup-node@v3
with:
node-version: 18.x
cache: 'yarn'
# Load previous cache
- name: ESLint Cache
uses: actions/cache@v3
with:
path: './.eslintcache'
key: ${{ runner.os }}-eslintcache-${{ github.ref_name }}-${{ hashFiles('.eslintcache') }}

- name: Install Dependencies
run: yarn install --immutable
# Verify linting
- name: Lint
run: yarn lint
# Run unit tests with coverage
- name: test
run: yarn test:unit:coverage
# Run Code Analysis Scan
- name: SonarCloud Scan
uses: SonarSource/sonarcloud-github-action@master
4 changes: 2 additions & 2 deletions __mocks__/react-native-video.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import {View} from 'react-native'
import {View} from 'react-native';

export default View
export default View;
18 changes: 13 additions & 5 deletions __tests__/ListWithFetch.test.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import React from 'react';
import {cleanup, render, screen} from '@testing-library/react-native';
import {
cleanup,
render,
screen,
waitForElementToBeRemoved,
} from '@testing-library/react-native';
import ListWithFetch from '../src/components/ListWithFetch';
import {server} from '../src/test/mocks/server';
import {rest} from 'msw';
Expand All @@ -15,16 +20,19 @@ test('displays images from the server', async () => {

// Loader is initially visible
expect(screen.getByLabelText(/loader/i)).toBeOnTheScreen();

await waitForElementToBeRemoved(() => screen.getByLabelText(/loader/i), {
timeout: 1500,
});
// Verify that users are fetched and rendered
expect(await screen.findAllByLabelText(/user-container/i)).toHaveLength(10);

// Verifying that the loader is no longer visible
// There are 2 ways to verify that a component is not in the UI tree
// 1. Use getBy* methods and expect them to throw an error with a corresponding message
// 2. Use queryBy* methods and expect them to return null (See the next expect statement)
// 1. Use waitForElementToBeRemoved to wait for the element to be removed from the DOM
// 2. Use getBy* methods and expect them to throw an error with a corresponding message
// 3. Use queryBy* methods and expect them to return null (See the next expect statement)
expect(() => screen.getByLabelText(/loader/i)).toThrow(
'Unable to find an element with accessibilityLabel: /loader/i',
'Unable to find an element with accessibility label: /loader/i',
);

// Verifying that there are no errors
Expand Down
32 changes: 16 additions & 16 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,27 +27,27 @@
"react-native-video": "6.0.0-alpha.7"
},
"devDependencies": {
"@babel/core": "^7.22.11",
"@babel/preset-env": "^7.22.14",
"@babel/runtime": "^7.22.11",
"@babel/core": "^7.20.0",
"@babel/preset-env": "^7.20.0",
"@babel/runtime": "^7.20.0",
"@react-native/eslint-config": "^0.72.2",
"@react-native/metro-config": "^0.72.11",
"@tsconfig/react-native": "^3.0.2",
"@testing-library/jest-native": "^5.4.2",
"@testing-library/react-native": "^12.2.2",
"@types/jest": "^29.5.4",
"@types/react": "^18.2.21",
"@types/react-native-video": "^5.0.15",
"@tsconfig/react-native": "^3.0.0",
"@types/react": "^18.0.24",
"@types/react-test-renderer": "^18.0.0",
"axios": "^1.5.0",
"babel-jest": "^29.6.4",
"eslint": "^8.48.0",
"jest": "^29.6.4",
"babel-jest": "^29.2.1",
"eslint": "^8.19.0",
"jest": "^29.2.1",
"metro-react-native-babel-preset": "0.76.8",
"msw": "^1.2.5",
"prettier": "^3.0.3",
"prettier": "^2.4.1",
"react-test-renderer": "18.2.0",
"typescript": "5.2.2"
"typescript": "4.8.4",
"@testing-library/jest-native": "^5.4.3",
"@testing-library/react-native": "^12.3.0",
"@types/jest": "^29.2.1",
"@types/react-native-video": "^5.0.15",
"axios": "^1.5.0",
"msw": "^1.3.0"
},
"engines": {
"node": ">=16"
Expand Down
10 changes: 10 additions & 0 deletions sonar-project.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
sonar.organization=vangalilea
sonar.projectKey=vanGalilea_react-native-testing
sonar.javascript.lcov.reportPaths=coverage/lcov.info
sonar.sources=src/
sonar.test.exclusions=**/__tests__/**
sonar.coverage.exclusions=**/__tests__/**, **/__mocks__/**
sonar.coverage.inclusions=**/src/**/**.ts|tsx
sonar.exclusions=**/android/**, **/ios/**
sonar.verbose=true
sonar.host.url=https://sonarcloud.io
7 changes: 5 additions & 2 deletions src/components/Home.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,9 @@ export default () => {
return (
<View style={styles.body}>
<StatusBar barStyle="dark-content" />
<SafeAreaView style={{flex: 1}}>
<SafeAreaView style={styles.flex1}>
<ScrollView
style={{flex: 1}}
style={styles.flex1}
contentInsetAdjustmentBehavior="automatic">
<View style={styles.innerScrollView}>
<Text>Go to component...</Text>
Expand Down Expand Up @@ -49,6 +49,9 @@ export default () => {
};

const styles = StyleSheet.create({
flex1: {
flex: 1,
},
body: {
backgroundColor: Colors.white,
...StyleSheet.absoluteFillObject,
Expand Down
5 changes: 4 additions & 1 deletion src/components/Modal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export default () => {
<View style={styles.modalView}>
<Text style={styles.modalText}>Hello World!</Text>
<Pressable
style={{...styles.openButton, backgroundColor: '#2196F3'}}
style={[styles.openButton, styles.specialBGColor]}
onPress={() => {
setModalVisible(!modalVisible);
}}>
Expand Down Expand Up @@ -74,4 +74,7 @@ const styles = StyleSheet.create({
marginBottom: 15,
textAlign: 'center',
},
specialBGColor: {
backgroundColor: '#2196F3',
},
});
16 changes: 8 additions & 8 deletions src/utils/theme.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,21 @@ import React, {
SetStateAction,
useContext,
useState,
} from 'react'
} from 'react';

export type ThemeType = 'dark' | 'light';
type ThemeContextType = {
theme: ThemeType;
setTheme: Dispatch<SetStateAction<ThemeType>>;
};
const ThemeContext = createContext<ThemeContextType | null>(null)
const ThemeContext = createContext<ThemeContextType | null>(null);

const useTheme = () => {
const context = useContext(ThemeContext)
const context = useContext(ThemeContext);
if (!context) {
throw new Error('useTheme should be used within a ThemeProvider')
throw new Error('useTheme should be used within a ThemeProvider');
}
return context
return context;
};

const ThemeProvider = ({
Expand All @@ -28,8 +28,8 @@ const ThemeProvider = ({
initialTheme: ThemeType;
children: React.ReactNode;
}): JSX.Element => {
const [theme, setTheme] = useState(initialTheme)
return <ThemeContext.Provider value={{theme, setTheme}} {...props} />
const [theme, setTheme] = useState(initialTheme);
return <ThemeContext.Provider value={{theme, setTheme}} {...props} />;
};

export {useTheme, ThemeProvider}
export {useTheme, ThemeProvider};
Loading