-
Notifications
You must be signed in to change notification settings - Fork 31
feat: Implement jest mocks for react-native. #535
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
Merged
kinyoklion
merged 54 commits into
launchdarkly:main
from
professorice:mzafir/react-native-jest-mock
Nov 4, 2024
Merged
Changes from 41 commits
Commits
Show all changes
54 commits
Select commit
Hold shift + click to select a range
75725a5
v2.0.0
9e0ea68
v3.0.0
799200d
v3.1.0
7833f46
v3.2.0
db3697f
v3.3.0
4f04b46
v3.4.0
d248241
v3.5.0
4944307
v3.5.1
f4ee714
v4.0.0
e8b3649
v4.1.0
a877514
v4.2.0
2531181
v4.2.1
8f9cec6
v4.2.2
b2657ff
chore: created jest mock test for react-native
75583b3
chore:added example test app for react-native
efbf89c
Merge branch 'launchdarkly:main' into mzafir/react-native-jest-mock
professorice 60cd0a1
chore: added react-native-jest-example to root package.json
a5341e6
chore: added @launchdarkly/jest to example app package.json
ad47e51
Merge branch 'launchdarkly:main' into mzafir/react-native-jest-mock
professorice fbc8178
chore: added workspace:^ to package.json of example and jest root. Al…
professorice 7750714
chore: added @testing-library/react-hooks to jest root package, added…
professorice 3e3252a
chore:updated metro config to include find-yarn-workspace-root
professorice f737935
chore: Moved @launchdarkly/jest to devDependencies and changed test e…
professorice 26692ce
Linting
kinyoklion af3fcc4
chore: modified App.tsx and welcome.tsx so that the example app is mo…
professorice f4b52b9
chrore: modified App.tsx and welcome.tsx to appear more like a normal…
professorice 99c789f
Merge branch 'launchdarkly:main' into mzafir/react-native-jest-mock
professorice d95b070
Merge branch 'launchdarkly:main' into mzafir/react-native-jest-mock
professorice d4bbdeb
feature: added resetLDMocks to reset information stored in the mock.
professorice c578a19
chore: added "clean script to package json, and changed package json …
professorice 1d92d09
fix: correct errors in jest configuration
professorice 0728fdf
fix: typo in resetLDMocks
professorice 4dc3bf2
chore: changed <Welcome> component to be a normal application
professorice 3ef8baa
Merge branch 'launchdarkly:main' into mzafir/react-native-jest-mock
professorice b32dedf
Merge branch 'launchdarkly:main' into mzafir/react-native-jest-mock
professorice d36a2ad
chore: bumped versions
professorice 1f2163e
fix: boolean flags work with simplified flag logic, but no other flag…
professorice 6e3caf7
fix: MockFlags correctly mocks all types of flags
professorice 3e146e8
chore: added tests for ldClient and boolean flag
professorice 78fd823
chore: added a newline to the end of this files
professorice 3d45157
chore: changed @launchdarkly/react-native-client-sdk from workspace t…
professorice 3f5b48c
Merge branch 'main' into mzafir/react-native-jest-mock
professorice 61aefc7
Update package.json
kinyoklion a4fad23
Update package.json
kinyoklion 23e7dac
chore: pinned react native version to 10.9.0
professorice beef6b0
fix: removed getConnectionMode and setConnectionMode to since they ar…
professorice 4fdbdbd
Merge branch 'launchdarkly:main' into mzafir/react-native-jest-mock
professorice e9493ed
Merge branch 'launchdarkly:main' into mzafir/react-native-jest-mock
professorice d2cb48e
chore: changed React Native dependency to patch releases
professorice 0760dab
fix: prettier issue
professorice 7bd782f
fix: removed setConnectionMode test
professorice 210f710
Merge branch 'launchdarkly:main' into mzafir/react-native-jest-mock
professorice 2fc00e4
Merge branch 'launchdarkly:main' into mzafir/react-native-jest-mock
professorice 32d4a22
Merge branch 'main' into mzafir/react-native-jest-mock
kinyoklion File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
38 changes: 38 additions & 0 deletions
38
packages/tooling/jest/example/react-native-example/.gitignore
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| # Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files | ||
|
|
||
| # dependencies | ||
| node_modules/ | ||
|
|
||
| # Expo | ||
| .expo/ | ||
| dist/ | ||
| web-build/ | ||
|
|
||
| # Native | ||
| *.orig.* | ||
| *.jks | ||
| *.p8 | ||
| *.p12 | ||
| *.key | ||
| *.mobileprovision | ||
|
|
||
| # Metro | ||
| .metro-health-check* | ||
|
|
||
| # debug | ||
| npm-debug.* | ||
| yarn-debug.* | ||
| yarn-error.* | ||
|
|
||
| # macOS | ||
| .DS_Store | ||
| *.pem | ||
|
|
||
| # local env files | ||
| .env*.local | ||
|
|
||
| # typescript | ||
| *.tsbuildinfo | ||
|
|
||
| # vscode | ||
| .vscode |
36 changes: 36 additions & 0 deletions
36
packages/tooling/jest/example/react-native-example/App.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,36 @@ | ||
| import { StyleSheet } from 'react-native'; | ||
| import { | ||
| AutoEnvAttributes, | ||
| LDProvider, | ||
| ReactNativeLDClient, | ||
| LDOptions, | ||
| } from '@launchdarkly/react-native-client-sdk'; | ||
| import Welcome from './src/welcome'; | ||
|
|
||
| const options: LDOptions = { | ||
| debug: true, | ||
| } | ||
| //TODO Set MOBILE_KEY in .env file to a mobile key in your project/environment. | ||
| const MOBILE_KEY = 'YOUR_MOBILE_KEY'; | ||
| const featureClient = new ReactNativeLDClient(MOBILE_KEY, AutoEnvAttributes.Enabled, options); | ||
|
|
||
| const userContext = { kind: 'user', key: '', anonymous: true }; | ||
|
|
||
| export default function App() { | ||
| featureClient.identify(userContext).catch((e: any) => console.log(e)); | ||
|
|
||
| return ( | ||
| <LDProvider client={featureClient}> | ||
| <Welcome /> | ||
| </LDProvider> | ||
| ); | ||
| } | ||
|
|
||
| const styles = StyleSheet.create({ | ||
| container: { | ||
| flex: 1, | ||
| backgroundColor: '#fff', | ||
| alignItems: 'center', | ||
| justifyContent: 'center', | ||
| }, | ||
| }); |
29 changes: 29 additions & 0 deletions
29
packages/tooling/jest/example/react-native-example/app.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| { | ||
| "expo": { | ||
| "name": "react-native-jest-example", | ||
| "slug": "react-native-jest-example", | ||
| "version": "0.0.1", | ||
| "orientation": "portrait", | ||
| "icon": "./assets/icon.png", | ||
| "userInterfaceStyle": "light", | ||
| "splash": { | ||
| "image": "./assets/splash.png", | ||
| "resizeMode": "contain", | ||
| "backgroundColor": "#ffffff" | ||
| }, | ||
| "ios": { | ||
| "supportsTablet": true, | ||
| "bundleIdentifier": "com.anonymous.reactnativejestexample" | ||
| }, | ||
| "android": { | ||
| "adaptiveIcon": { | ||
| "foregroundImage": "./assets/adaptive-icon.png", | ||
| "backgroundColor": "#ffffff" | ||
| }, | ||
| "package": "com.anonymous.reactnativejestexample" | ||
| }, | ||
| "web": { | ||
| "favicon": "./assets/favicon.png" | ||
| } | ||
| } | ||
| } |
Binary file added
BIN
+17.1 KB
packages/tooling/jest/example/react-native-example/assets/adaptive-icon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added
BIN
+1.43 KB
packages/tooling/jest/example/react-native-example/assets/favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
7 changes: 7 additions & 0 deletions
7
packages/tooling/jest/example/react-native-example/babel.config.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| module.exports = function (api) { | ||
| api.cache(true); | ||
| return { | ||
| presets: ['babel-preset-expo', '@babel/preset-typescript'], | ||
|
|
||
| }; | ||
| }; |
10 changes: 10 additions & 0 deletions
10
packages/tooling/jest/example/react-native-example/index.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| // We have to use a custom entrypoint for monorepo workspaces to work. | ||
| // https://docs.expo.dev/guides/monorepos/#change-default-entrypoint | ||
| import { registerRootComponent } from 'expo'; | ||
|
|
||
| import App from './App'; | ||
|
|
||
| // registerRootComponent calls AppRegistry.registerComponent('main', () => App); | ||
| // It also ensures that whether you load the app in Expo Go or in a native build, | ||
| // the environment is set up appropriately | ||
| registerRootComponent(App); |
4 changes: 4 additions & 0 deletions
4
packages/tooling/jest/example/react-native-example/jest.config.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| module.exports = { | ||
| preset: 'jest-expo', | ||
| setupFiles: ['@launchdarkly/jest/react-native'], | ||
| }; |
28 changes: 28 additions & 0 deletions
28
packages/tooling/jest/example/react-native-example/metro.config.js
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,28 @@ | ||
| // We need to use a custom metro config for monorepo workspaces to work. | ||
| // https://docs.expo.dev/guides/monorepos/#modify-the-metro-config | ||
| /** | ||
| * @type {import('expo/metro-config')} | ||
| */ | ||
| const { getDefaultConfig } = require('expo/metro-config'); | ||
| const path = require('path'); | ||
|
|
||
| // Find the project and workspace directories | ||
| const projectRoot = __dirname; | ||
|
|
||
| const findWorkspaceRoot = require('find-yarn-workspace-root'); | ||
|
|
||
| const workspaceRoot = findWorkspaceRoot(__dirname); // Absolute path or null | ||
|
|
||
| const config = getDefaultConfig(projectRoot); | ||
|
|
||
| // 1. Watch all files within the monorepo | ||
| config.watchFolders = [workspaceRoot]; | ||
| // 2. Let Metro know where to resolve packages and in what order | ||
| config.resolver.nodeModulesPaths = [ | ||
| path.resolve(projectRoot, 'node_modules'), | ||
| path.resolve(workspaceRoot, 'node_modules'), | ||
| ]; | ||
| // 3. Force Metro to resolve (sub)dependencies only from the `nodeModulesPaths` | ||
| config.resolver.disableHierarchicalLookup = true; | ||
|
|
||
| module.exports = config; |
40 changes: 40 additions & 0 deletions
40
packages/tooling/jest/example/react-native-example/package.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| { | ||
| "name": "react-native-jest-example", | ||
| "version": "0.0.1", | ||
| "main": "index.js", | ||
| "scripts": { | ||
| "start": "expo start", | ||
| "android": "expo run:android", | ||
| "ios": "expo run:ios", | ||
| "test": "jest", | ||
| "clean": "rm -rf node_modules && rm -rf package-lock.json && rm -rf yarn.lock" | ||
| }, | ||
| "dependencies": { | ||
| "@launchdarkly/react-native-client-sdk": "^10.9.0", | ||
| "expo": "^51.0.26", | ||
| "expo-status-bar": "~1.12.1", | ||
| "find-yarn-workspace-root": "^2.0.0", | ||
| "react": "^18.2.0", | ||
| "react-native": "0.74.5" | ||
| }, | ||
| "devDependencies": { | ||
| "@babel/core": "^7.20.0", | ||
| "@babel/preset-env": "^7.25.4", | ||
| "@babel/preset-react": "^7.24.7", | ||
| "@babel/runtime": "^7.25.4", | ||
| "@launchdarkly/jest": "workspace:^", | ||
| "@react-native/babel-preset": "^0.75.2", | ||
| "@testing-library/react-native": "^12.6.1", | ||
| "@types/jest": "^29.5.12", | ||
| "@types/react": "~18.2.45", | ||
| "jest": "^29.7.0", | ||
| "jest-expo": "^51.0.4", | ||
| "react-test-renderer": "^18.2.0", | ||
| "typescript": "^5.1.3" | ||
| }, | ||
| "packageManager": "[email protected]", | ||
| "installConfig": { | ||
| "hoistingLimits": "workspaces" | ||
| }, | ||
| "private": true | ||
| } |
29 changes: 29 additions & 0 deletions
29
packages/tooling/jest/example/react-native-example/src/welcome.test.tsx
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This looks good. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| /** | ||
| * @jest-environment jsdom | ||
| */ | ||
|
|
||
| import { mockFlags, resetLDMocks } from '@launchdarkly/jest/react-native'; | ||
| import { screen, render } from '@testing-library/react-native'; | ||
| import { useLDClient } from '@launchdarkly/react-native-client-sdk'; | ||
| import Welcome from './welcome'; | ||
|
|
||
| describe('Welcome component test', () => { | ||
|
|
||
| afterEach(() => { | ||
| resetLDMocks(); | ||
| }); | ||
|
|
||
| test('mock boolean flag correctly', () => { | ||
| mockFlags({ 'my-boolean-flag': true }); | ||
| render(<Welcome />); | ||
| expect(screen.getByText('Flag value is true')).toBeTruthy(); | ||
| }); | ||
|
|
||
| test('mock ldClient correctly', () => { | ||
| const current = useLDClient(); | ||
|
|
||
| current?.track('event'); | ||
| expect(current.track).toHaveBeenCalledTimes(1); | ||
| }); | ||
|
|
||
| }); |
25 changes: 25 additions & 0 deletions
25
packages/tooling/jest/example/react-native-example/src/welcome.tsx
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,25 @@ | ||
| import { StyleSheet, Text, View } from 'react-native'; | ||
| import { useLDClient } from '@launchdarkly/react-native-client-sdk'; | ||
|
|
||
| export default function Welcome() { | ||
|
|
||
| const ldClient = useLDClient(); | ||
|
|
||
| const flagValue = ldClient.boolVariation('my-boolean-flag', false); | ||
|
|
||
| return ( | ||
| <View style={styles.container}> | ||
| <Text>Welcome to LaunchDarkly</Text> | ||
| <Text>Flag value is {`${flagValue}`}</Text> | ||
| </View> | ||
| ); | ||
| } | ||
|
|
||
| const styles = StyleSheet.create({ | ||
| container: { | ||
| flex: 1, | ||
| backgroundColor: '#fff', | ||
| alignItems: 'center', | ||
| justifyContent: 'center', | ||
| }, | ||
| }); |
10 changes: 10 additions & 0 deletions
10
packages/tooling/jest/example/react-native-example/tsconfig.eslint.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,10 @@ | ||
| { | ||
| "extends": "./tsconfig.json", | ||
| "include": [ | ||
| "/**/*.ts", | ||
| "/**/*.tsx", | ||
| "/*.js", | ||
| "/*.tsx" | ||
| ], | ||
| "exclude": ["node_modules"] | ||
| } |
8 changes: 8 additions & 0 deletions
8
packages/tooling/jest/example/react-native-example/tsconfig.json
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| { | ||
| "extends": "expo/tsconfig.base", | ||
| "compilerOptions": { | ||
| "strict": true, | ||
| "moduleResolution": "bundler", | ||
| "jsx": "react-jsx" | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -55,9 +55,18 @@ | |
| "eslint-plugin-prettier": "^5.0.0", | ||
| "jest": "^29.5.0", | ||
| "prettier": "^3.0.0", | ||
| "react-test-renderer": "^18.3.1", | ||
| "rimraf": "^5.0.1", | ||
| "ts-jest": "^29.1.0", | ||
| "typedoc": "0.25.0", | ||
| "typescript": "5.1.6" | ||
| }, | ||
| "dependencies": { | ||
| "@launchdarkly/react-native-client-sdk": "workspace:^", | ||
|
||
| "@testing-library/react-hooks": "^8.0.1", | ||
| "@testing-library/react-native": "^12.7.2", | ||
| "@types/lodash": "^4.17.7", | ||
| "launchdarkly-react-client-sdk": "^3.4.0", | ||
| "react": "^18.3.1" | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,73 @@ | ||
| import { | ||
| ldClientMock, | ||
| mockFlags, | ||
| mockLDProvider, | ||
| mockReactNativeLDClient, | ||
| mockUseLDClient, | ||
| resetLDMocks, | ||
| } from '.'; | ||
|
|
||
| describe('react-native', () => { | ||
| test.todo('Add react-native tests'); | ||
| afterEach(() => { | ||
| resetLDMocks(); | ||
| }); | ||
|
|
||
| test('reset LD Mocks', () => { | ||
| const current = mockUseLDClient(); | ||
|
|
||
| current?.track('event'); | ||
| expect(ldClientMock.track).toHaveBeenCalledTimes(1); | ||
|
|
||
| resetLDMocks(); | ||
| expect(ldClientMock.track).toHaveBeenCalledTimes(0); | ||
| }); | ||
|
|
||
| test('mock boolean flag correctly', () => { | ||
| mockFlags({ 'bool-flag': true }); | ||
| expect(ldClientMock.boolVariation).toBeDefined(); | ||
| }); | ||
|
|
||
| test('mock number flag correctly', () => { | ||
| mockFlags({ 'number-flag': 42 }); | ||
| expect(ldClientMock.numberVariation).toBeDefined(); | ||
| }); | ||
|
|
||
| test('mock string flag correctly', () => { | ||
| mockFlags({ 'string-flag': 'hello' }); | ||
| expect(ldClientMock.stringVariation).toBeDefined(); | ||
| }); | ||
|
|
||
| test('mock json flag correctly', () => { | ||
| mockFlags({ 'json-flag': { key: 'value' } }); | ||
| expect(ldClientMock.jsonVariation).toBeDefined(); | ||
| }); | ||
|
|
||
| test('mock LDProvider correctly', () => { | ||
| expect(mockLDProvider).toBeDefined(); | ||
| }); | ||
|
|
||
| test('mock ReactNativeLDClient correctly', () => { | ||
| expect(mockReactNativeLDClient).toBeDefined(); | ||
| }); | ||
|
|
||
| test('mock ldClient correctly', () => { | ||
| const current = mockUseLDClient(); | ||
|
|
||
| current?.track('event'); | ||
| expect(ldClientMock.track).toHaveBeenCalledTimes(1); | ||
| }); | ||
|
|
||
| test('mock ldClient complete set of methods correctly', () => { | ||
| expect(ldClientMock.identify).toBeDefined(); | ||
| expect(ldClientMock.allFlags.mock).toBeDefined(); | ||
| expect(ldClientMock.close.mock).toBeDefined(); | ||
| expect(ldClientMock.flush).toBeDefined(); | ||
| expect(ldClientMock.getContext.mock).toBeDefined(); | ||
| expect(ldClientMock.off.mock).toBeDefined(); | ||
| expect(ldClientMock.on.mock).toBeDefined(); | ||
| expect(ldClientMock.setConnectionMode.mock).toBeDefined(); | ||
| expect(ldClientMock.track.mock).toBeDefined(); | ||
| expect(ldClientMock.variation.mock).toBeDefined(); | ||
| expect(ldClientMock.variationDetail.mock).toBeDefined(); | ||
| }); | ||
| }); |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.