mirror of
https://github.com/facebook/react-native.git
synced 2025-11-01 09:14:26 +00:00
Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
adf1274955 | ||
|
|
9e42e009ab | ||
|
|
6084cf1401 | ||
|
|
1add9b4f08 | ||
|
|
f8c484dfbf | ||
|
|
9d19ab0c0c | ||
|
|
a289b7efb0 | ||
|
|
abf9b26040 | ||
|
|
57ad19758d | ||
|
|
1d5fe77468 | ||
|
|
d811d38823 | ||
|
|
23cfa29ac7 | ||
|
|
26793a052a | ||
|
|
ec887c25a4 | ||
|
|
fd5042dcef | ||
|
|
9f14ac2244 | ||
|
|
60b3942389 | ||
|
|
9151e0d400 | ||
|
|
22af50ad95 | ||
|
|
0244caf513 | ||
|
|
fb4e4fd099 | ||
|
|
4ff693b93b | ||
|
|
bbf439862c | ||
|
|
54e82a8c42 | ||
|
|
dbdb509f26 | ||
|
|
34a585e093 | ||
|
|
7546aeaf8d | ||
|
|
d25e304bcc | ||
|
|
c162c89edf | ||
|
|
57c6403048 | ||
|
|
c8b1bdb88e | ||
|
|
c88a7ca24a | ||
|
|
e0093fc98d | ||
|
|
19c3a08ca8 | ||
|
|
e29ca07749 | ||
|
|
54cb03c8d6 | ||
|
|
bd79303d5b | ||
|
|
68f6325849 | ||
|
|
1c22c10aa2 | ||
|
|
1df4713e9a | ||
|
|
f09ab6df25 | ||
|
|
94e7a10141 | ||
|
|
be40199f13 | ||
|
|
e4fffa281e | ||
|
|
6ae2ebfcab | ||
|
|
b8c0d9d289 | ||
|
|
7c04c09923 | ||
|
|
8c3111af31 | ||
|
|
26af339a47 | ||
|
|
76fc78e740 | ||
|
|
1d949a12fa | ||
|
|
8302e0cd8f | ||
|
|
e3b7e81c8c | ||
|
|
2472e65b62 | ||
|
|
7709285708 | ||
|
|
e7a52675cb | ||
|
|
06dc51f8a9 | ||
|
|
319fa03125 | ||
|
|
3c454eef8f | ||
|
|
c43b7b93b2 | ||
|
|
d8f28ceef8 | ||
|
|
370fde33da | ||
|
|
1b302b3f2a | ||
|
|
808a156769 | ||
|
|
d1e312d8ce | ||
|
|
cd8051c939 | ||
|
|
cb85396fab | ||
|
|
00c7c5ade1 | ||
|
|
1fdfed51c3 | ||
|
|
0189ea2c2b | ||
|
|
860d01a2c4 | ||
|
|
8e39451512 | ||
|
|
c0bf7a128c | ||
|
|
e54d1e27ea | ||
|
|
f6566c77b1 | ||
|
|
747b5e47ef | ||
|
|
0b32a65bbd | ||
|
|
3fbefa8664 | ||
|
|
19a7ecc837 | ||
|
|
0c1c66e719 | ||
|
|
e71fb64ecd | ||
|
|
26bdd5ba4e | ||
|
|
e0ea58ecbd | ||
|
|
64dd60fb7d | ||
|
|
d4d457b4eb | ||
|
|
b864e7e63e | ||
|
|
696bd89013 | ||
|
|
a525941ab6 |
@@ -0,0 +1,48 @@
|
||||
environment:
|
||||
ANDROID_HOME: "C:\\android-sdk-windows"
|
||||
ANDROID_NDK: "C:\\android-sdk-windows\\android-ndk-r17c"
|
||||
ANDROID_BUILD_VERSION: 28
|
||||
ANDROID_TOOLS_VERSION: 28.0.3
|
||||
|
||||
GRADLE_OPTS: -Dorg.gradle.daemon=false
|
||||
|
||||
SDK_TOOLS_URL: https://dl.google.com/android/repository/sdk-tools-windows-3859397.zip
|
||||
NDK_TOOLS_URL: https://dl.google.com/android/repository/android-ndk-r17c-windows-x86_64.zip
|
||||
|
||||
matrix:
|
||||
- nodejs_version: 8
|
||||
- nodejs_version: 10
|
||||
|
||||
install:
|
||||
# Install Android SDK Tools
|
||||
- mkdir "%ANDROID_HOME%"
|
||||
- appveyor DownloadFile "%SDK_TOOLS_URL%" -FileName "%TMP%/sdk-tools.zip"
|
||||
- 7z x "%TMP%/sdk-tools.zip" -o"%ANDROID_HOME%" > nul
|
||||
- set PATH=%PATH%;"%ANDROID_HOME%\tools\bin"
|
||||
|
||||
- yes 2> nul | sdkmanager --licenses > nul
|
||||
- sdkmanager "system-images;android-19;google_apis;armeabi-v7a"
|
||||
- sdkmanager "platforms;android-%ANDROID_BUILD_VERSION%"
|
||||
- sdkmanager "build-tools;%ANDROID_TOOLS_VERSION%"
|
||||
- sdkmanager "add-ons;addon-google_apis-google-23"
|
||||
- sdkmanager "extras;android;m2repository"
|
||||
|
||||
- appveyor DownloadFile "%NDK_TOOLS_URL%" -FileName "%TMP%/ndk.zip"
|
||||
- 7z x "%TMP%/ndk.zip" -o"%ANDROID_HOME%" > nul
|
||||
|
||||
- ps: Install-Product node $env:nodejs_version
|
||||
- node --version
|
||||
- yarn --version
|
||||
- appveyor-retry yarn install
|
||||
|
||||
build_script:
|
||||
- gradlew.bat RNTester:android:app:assembleRelease
|
||||
|
||||
test_script:
|
||||
- npm test
|
||||
|
||||
cache:
|
||||
- node_modules
|
||||
- "%LOCALAPPDATA%/Yarn"
|
||||
- "%USERPROFILE%/.gradle/caches"
|
||||
- "%USERPROFILE%/.gradle/wrapper"
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"presets": [
|
||||
"module:metro-react-native-babel-preset"
|
||||
],
|
||||
"plugins": [
|
||||
"babel-plugin-transform-flow-enums"
|
||||
]
|
||||
}
|
||||
+3
-10
@@ -1,20 +1,13 @@
|
||||
|
||||
[android]
|
||||
target = android-31
|
||||
|
||||
[kotlin]
|
||||
compile_against_abis = True
|
||||
kotlin_version = 1.6.10
|
||||
target = android-28
|
||||
|
||||
[download]
|
||||
max_number_of_retries = 3
|
||||
|
||||
[maven_repositories]
|
||||
central = https://repo1.maven.org/maven2
|
||||
google = https://maven.google.com/
|
||||
google = https://dl.google.com/dl/android/maven2/
|
||||
|
||||
[alias]
|
||||
rntester = //packages/rn-tester/android/app:app
|
||||
|
||||
[buildfile]
|
||||
includes = //tools/build_defs/oss/preload.bzl
|
||||
rntester = //RNTester/android/app:app
|
||||
|
||||
@@ -1,2 +0,0 @@
|
||||
BUNDLE_PATH: "vendor/bundle"
|
||||
BUNDLE_FORCE_RUBY_PLATFORM: 1
|
||||
@@ -1,81 +0,0 @@
|
||||
# Docker Test Environment
|
||||
|
||||
This is a high-level overview of the test configuration using Docker.
|
||||
It explains how to run the tests locally.
|
||||
|
||||
## Docker Installation
|
||||
|
||||
It is required to have Docker running on your machine in order to build and run the tests in the Dockerfiles.
|
||||
See <https://docs.docker.com/engine/installation/> for more information on how to install.
|
||||
|
||||
## Convenience Scripts
|
||||
|
||||
We have added a number of default run scripts to the `package.json` file to simplify building and running your tests.
|
||||
|
||||
### Configuring Docker Images
|
||||
|
||||
The following two scripts need to be run first before you can move on to testing:
|
||||
|
||||
- `yarn run docker-setup-android`: Pulls down the React Native Community Android image that serves as a base image when building the actual test image.
|
||||
|
||||
- `yarn run docker-build-android`: Builds a test image with the latest dependencies and React Native library code, including a compiled Android test app.
|
||||
|
||||
### Running Tests
|
||||
|
||||
Once the test image has been built, it can be used to run our Android tests.
|
||||
|
||||
- `yarn run test-android-run-unit` runs the unit tests, as defined in `scripts/run-android-docker-unit-tests.sh`.
|
||||
- `yarn run test-android-run-e2e` runs the end to end tests, as defined in `scripts/run-ci-e2e-tests.sh`.
|
||||
- `yarn run test-android-run-instrumentation` runs the instrumentation tests, as defined in `scripts/run-android-docker-instrumentation-tests.sh`.
|
||||
|
||||
#### Instrumentation Tests
|
||||
|
||||
The instrumentation test script accepts the following flags in order to customize the execution of the tests:
|
||||
|
||||
`--filter` - A regex that filters which instrumentation tests will be run. (Defaults to .*)
|
||||
|
||||
`--package` - Name of the java package containing the instrumentation tests (Defaults to com.facebook.react.tests)
|
||||
|
||||
`--path` - Path to the directory containing the instrumentation tests. (Defaults to ./ReactAndroid/src/androidTest/java/com/facebook/react/tests)
|
||||
|
||||
`--retries` - Number of times to retry a failed test before declaring a failure (Defaults to 2)
|
||||
|
||||
For example, if locally you only wanted to run the InitialPropsTestCase, you could do the following:
|
||||
`yarn run test-android-run-instrumentation -- --filter="InitialPropsTestCase"`
|
||||
|
||||
## Detailed Android Setup
|
||||
|
||||
There are two Dockerfiles for use with the Android codebase.
|
||||
The base image used to build `reactnativecommunity/react-native-android` is located in the https://github.com/react-native-community/docker-android GitHub repository.
|
||||
It contains all the necessary prerequisites required to run the React Android tests.
|
||||
It is separated out into a separate Dockerfile because these are dependencies that rarely change and also because it is quite a beastly image since it contains all the Android dependencies for running Android and the emulators (~9GB).
|
||||
|
||||
The good news is you should rarely have to build or pull down the base image!
|
||||
All iterative code updates happen as part of the `Dockerfile.android` image build.
|
||||
|
||||
Lets break it down...
|
||||
|
||||
First, you'll need to pull the base image.
|
||||
You can use `docker pull` to grab the latest version of the `reactnativecommunity/react-native-android` base image.
|
||||
This is what you get when you run `yarn run docker-setup-android`.
|
||||
|
||||
This will take quite some time depending on your connection and you need to ensure you have ~10GB of free disk space.
|
||||
|
||||
Once you have downloaded the base image, the test image can be built using `docker build -t reactnativeci/android -f ./.circleci/Dockerfiles/Dockerfile.android .`. This is what `yarn run docker-build-android` does. Note that the `-t` flag is how you tell Docker what to name this image locally. You can then use `docker run -t reactnativeci/android` to run this image.
|
||||
|
||||
Now that you've built the test image, you can run unit tests using what you've learned so far:
|
||||
|
||||
```bash
|
||||
docker run --cap-add=SYS_ADMIN -it reactnativeci/android bash .circleci/Dockerfiles/scripts/run-android-docker-unit-tests.sh
|
||||
```
|
||||
|
||||
> Note: `--cap-add=SYS_ADMIN` flag is required for the `.circleci/Dockerfiles/scripts/run-android-docker-unit-tests.sh` and `.circleci/Dockerfiles/scripts/run-android-docker-instrumentation-tests.sh` in order to allow the remounting of `/dev/shm` as writeable so the `buck` build system may write temporary output to that location.
|
||||
|
||||
Every time you make any modifications to the codebase, including changes to the test scripts inside `.circleci/Dockerfiles/scripts`, you should re-run the `docker build ...` command in order for your updates to be included in your local docker test image.
|
||||
|
||||
For rapid iteration, it's useful to keep in mind that Docker can pass along arbitrary commands to an image.
|
||||
For example, you can alternatively use Gradle in this manner:
|
||||
|
||||
```bash
|
||||
docker run --cap-add=SYS_ADMIN -it reactnativeci/android ./gradlew RNTester:android:app:assembleRelease
|
||||
```
|
||||
@@ -1,44 +0,0 @@
|
||||
# Copyright (c) Facebook, Inc. and its affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
#
|
||||
# This image builds upon the React Native Community Android image:
|
||||
# https://github.com/react-native-community/docker-android
|
||||
#
|
||||
# The base image is expected to remain relatively stable, and only
|
||||
# needs to be updated when major dependencies such as the Android
|
||||
# SDK or NDK are updated.
|
||||
#
|
||||
# In this Android Test image, we download the latest dependencies
|
||||
# and build a Android application that can be used to run the
|
||||
# tests specified in the scripts/ directory.
|
||||
#
|
||||
FROM reactnativecommunity/react-native-android:7.0
|
||||
|
||||
LABEL Description="React Native Android Test Image"
|
||||
LABEL maintainer="Héctor Ramos <hector@fb.com>"
|
||||
|
||||
# set default environment variables
|
||||
ENV GRADLE_OPTS="-Dorg.gradle.daemon=false -Dfile.encoding=utf-8 -Dorg.gradle.jvmargs=\"-Xmx512m -XX:+HeapDumpOnOutOfMemoryError\""
|
||||
ENV KOTLIN_HOME="packages/react-native/third-party/kotlin"
|
||||
|
||||
ADD .buckconfig /app/.buckconfig
|
||||
ADD .buckjavaargs /app/.buckjavaargs
|
||||
ADD BUCK /app/BUCK
|
||||
ADD packages/react-native/Libraries /app/packages/react-native/Libraries
|
||||
ADD packages/react-native/ReactAndroid /app/packages/react-native/ReactAndroid
|
||||
ADD packages/react-native/ReactCommon /app/packages/react-native/ReactCommon
|
||||
ADD packages/react-native/React /app/packages/react-native/React
|
||||
ADD keystores /app/keystores
|
||||
ADD packages/react-native-codegen /app/packages/react-native-codegen
|
||||
ADD tools /app/tools
|
||||
ADD scripts /app/scripts
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
ADD . /app
|
||||
|
||||
RUN yarn
|
||||
|
||||
RUN ./gradlew :packages:react-native:ReactAndroid:assembleDebug
|
||||
@@ -1,40 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
# for buck gen
|
||||
mount -o remount,exec /dev/shm
|
||||
|
||||
AVD_UUID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1)
|
||||
|
||||
# create virtual device
|
||||
echo no | android create avd -n "$AVD_UUID" -f -t android-21 --abi default/armeabi-v7a
|
||||
|
||||
# emulator setup
|
||||
emulator64-arm -avd $AVD_UUID -no-skin -no-audio -no-window -no-boot-anim &
|
||||
bootanim=""
|
||||
until [[ "$bootanim" =~ "stopped" ]]; do
|
||||
sleep 5
|
||||
bootanim=$(adb -e shell getprop init.svc.bootanim 2>&1)
|
||||
echo "boot animation status=$bootanim"
|
||||
done
|
||||
|
||||
set -x
|
||||
|
||||
# solve issue with max user watches limit
|
||||
echo 65536 | tee -a /proc/sys/fs/inotify/max_user_watches
|
||||
watchman shutdown-server
|
||||
|
||||
# integration tests
|
||||
# build JS bundle for instrumentation tests
|
||||
node cli.js bundle --platform android --dev true --entry-file ReactAndroid/src/androidTest/js/TestBundle.js --bundle-output ReactAndroid/src/androidTest/assets/AndroidTestBundle.js
|
||||
|
||||
# build test APK
|
||||
# shellcheck disable=SC1091
|
||||
source ./scripts/android-setup.sh && NO_BUCKD=1 scripts/retry3 buck install ReactAndroid/src/androidTest/buck-runner:instrumentation-tests --config build.threads=1
|
||||
|
||||
# run installed apk with tests
|
||||
node ./.circleci/Dockerfiles/scripts/run-android-ci-instrumentation-tests.js "$*"
|
||||
exit $?
|
||||
+601
-1803
File diff suppressed because it is too large
Load Diff
@@ -1,36 +0,0 @@
|
||||
storage: ./storage
|
||||
auth:
|
||||
htpasswd:
|
||||
file: ./htpasswd
|
||||
uplinks:
|
||||
npmjs:
|
||||
url: https://registry.npmjs.org/
|
||||
max_fails: 40
|
||||
maxage: 30m
|
||||
timeout: 60s
|
||||
fail_timeout: 10m
|
||||
cache: false
|
||||
agent_options:
|
||||
keepAlive: true
|
||||
maxSockets: 40
|
||||
maxFreeSockets: 10
|
||||
packages:
|
||||
# Get @react-native/normalize-color from npm registry, since its used in deprecated-react-native-prop-types package
|
||||
'@react-native/normalize-color':
|
||||
access: $all
|
||||
publish: $authenticated
|
||||
proxy: npmjs
|
||||
# Group and isolate all local packages, avoid being proxy from outside
|
||||
'@react-native/*':
|
||||
access: $all
|
||||
publish: $all
|
||||
'@*/*':
|
||||
access: $all
|
||||
publish: $authenticated
|
||||
proxy: npmjs
|
||||
'**':
|
||||
access: $all
|
||||
publish: $all
|
||||
proxy: npmjs
|
||||
logs:
|
||||
- {type: file, path: verdaccio.log, format: json, level: warn}
|
||||
@@ -1,91 +0,0 @@
|
||||
---
|
||||
AccessModifierOffset: -1
|
||||
AlignAfterOpenBracket: AlwaysBreak
|
||||
AlignConsecutiveAssignments: false
|
||||
AlignConsecutiveDeclarations: false
|
||||
AlignEscapedNewlinesLeft: true
|
||||
AlignOperands: false
|
||||
AlignTrailingComments: false
|
||||
AllowAllParametersOfDeclarationOnNextLine: false
|
||||
AllowShortBlocksOnASingleLine: false
|
||||
AllowShortCaseLabelsOnASingleLine: false
|
||||
AllowShortFunctionsOnASingleLine: Empty
|
||||
AllowShortIfStatementsOnASingleLine: false
|
||||
AllowShortLoopsOnASingleLine: false
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakBeforeMultilineStrings: true
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BinPackArguments: false
|
||||
BinPackParameters: false
|
||||
BraceWrapping:
|
||||
AfterClass: false
|
||||
AfterControlStatement: false
|
||||
AfterEnum: false
|
||||
AfterFunction: false
|
||||
AfterNamespace: false
|
||||
AfterObjCDeclaration: false
|
||||
AfterStruct: false
|
||||
AfterUnion: false
|
||||
BeforeCatch: false
|
||||
BeforeElse: false
|
||||
IndentBraces: false
|
||||
BreakBeforeBinaryOperators: None
|
||||
BreakBeforeBraces: Attach
|
||||
BreakBeforeTernaryOperators: true
|
||||
BreakConstructorInitializersBeforeComma: false
|
||||
BreakAfterJavaFieldAnnotations: false
|
||||
BreakStringLiterals: false
|
||||
ColumnLimit: 80
|
||||
CommentPragmas: '^ IWYU pragma:'
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
ConstructorInitializerIndentWidth: 4
|
||||
ContinuationIndentWidth: 4
|
||||
Cpp11BracedListStyle: true
|
||||
DerivePointerAlignment: false
|
||||
DisableFormat: false
|
||||
ForEachMacros: [ FOR_EACH_RANGE, FOR_EACH, ]
|
||||
IncludeCategories:
|
||||
- Regex: '^<.*\.h(pp)?>'
|
||||
Priority: 1
|
||||
- Regex: '^<.*'
|
||||
Priority: 2
|
||||
- Regex: '.*'
|
||||
Priority: 3
|
||||
IndentCaseLabels: true
|
||||
IndentWidth: 2
|
||||
IndentWrappedFunctionNames: false
|
||||
KeepEmptyLinesAtTheStartOfBlocks: false
|
||||
MacroBlockBegin: ''
|
||||
MacroBlockEnd: ''
|
||||
MaxEmptyLinesToKeep: 1
|
||||
NamespaceIndentation: None
|
||||
ObjCBlockIndentWidth: 2
|
||||
ObjCSpaceAfterProperty: true
|
||||
ObjCSpaceBeforeProtocolList: true
|
||||
PenaltyBreakBeforeFirstCallParameter: 1
|
||||
PenaltyBreakComment: 300
|
||||
PenaltyBreakFirstLessLess: 120
|
||||
PenaltyBreakString: 1000
|
||||
PenaltyExcessCharacter: 1000000
|
||||
PenaltyReturnTypeOnItsOwnLine: 200
|
||||
PointerAlignment: Right
|
||||
ReflowComments: true
|
||||
SortIncludes: true
|
||||
SpaceAfterCStyleCast: false
|
||||
SpaceBeforeAssignmentOperators: true
|
||||
SpaceBeforeParens: ControlStatements
|
||||
SpaceInEmptyParentheses: false
|
||||
SpacesBeforeTrailingComments: 1
|
||||
SpacesInAngles: false
|
||||
SpacesInContainerLiterals: true
|
||||
SpacesInCStyleCastParentheses: false
|
||||
SpacesInParentheses: false
|
||||
SpacesInSquareBrackets: false
|
||||
Standard: Cpp11
|
||||
TabWidth: 8
|
||||
UseTab: Never
|
||||
---
|
||||
Language: ObjC
|
||||
ColumnLimit: 120
|
||||
BreakBeforeBraces: WebKit
|
||||
...
|
||||
+1
-4
@@ -1,4 +1,4 @@
|
||||
# EditorConfig is awesome: https://EditorConfig.org
|
||||
# EditorConfig is awesome: http://EditorConfig.org
|
||||
|
||||
# top-most EditorConfig file
|
||||
root = true
|
||||
@@ -13,8 +13,5 @@ indent_size = 2
|
||||
[*.gradle]
|
||||
indent_size = 4
|
||||
|
||||
[*.kts]
|
||||
indent_size = 4
|
||||
|
||||
[BUCK]
|
||||
indent_size = 4
|
||||
|
||||
+9
-9
@@ -1,10 +1,10 @@
|
||||
**/main.js
|
||||
# node_modules ignored by default
|
||||
|
||||
**/staticBundle.js
|
||||
docs/generatedComponentApiDocs.js
|
||||
packages/react-native/flow/
|
||||
packages/react-native/Libraries/Renderer/*
|
||||
packages/react-native/Libraries/vendor/**/*
|
||||
node_modules/
|
||||
packages/*/node_modules
|
||||
packages/react-native-codegen/lib
|
||||
tools/eslint/rules/sort-imports.js
|
||||
**/main.js
|
||||
Libraries/vendor/**/*
|
||||
Libraries/Renderer/*
|
||||
pr-inactivity-bookmarklet.js
|
||||
question-bookmarklet.js
|
||||
flow/
|
||||
danger/
|
||||
|
||||
@@ -0,0 +1,275 @@
|
||||
{
|
||||
"root": true,
|
||||
|
||||
"parser": "babel-eslint",
|
||||
|
||||
"env": {
|
||||
"es6": true,
|
||||
"jest": true,
|
||||
},
|
||||
|
||||
"plugins": [
|
||||
"eslint-comments",
|
||||
"flowtype",
|
||||
"prettier",
|
||||
"react",
|
||||
"react-native",
|
||||
"jest"
|
||||
],
|
||||
|
||||
// Map from global var to bool specifying if it can be redefined
|
||||
"globals": {
|
||||
"__DEV__": true,
|
||||
"__dirname": false,
|
||||
"__fbBatchedBridgeConfig": false,
|
||||
"alert": false,
|
||||
"cancelAnimationFrame": false,
|
||||
"cancelIdleCallback": false,
|
||||
"clearImmediate": true,
|
||||
"clearInterval": false,
|
||||
"clearTimeout": false,
|
||||
"console": false,
|
||||
"document": false,
|
||||
"escape": false,
|
||||
"Event": false,
|
||||
"EventTarget": false,
|
||||
"exports": false,
|
||||
"fetch": false,
|
||||
"FormData": false,
|
||||
"global": false,
|
||||
"jest": false,
|
||||
"Map": true,
|
||||
"module": false,
|
||||
"navigator": false,
|
||||
"process": false,
|
||||
"Promise": true,
|
||||
"requestAnimationFrame": true,
|
||||
"requestIdleCallback": true,
|
||||
"require": false,
|
||||
"Set": true,
|
||||
"setImmediate": true,
|
||||
"setInterval": false,
|
||||
"setTimeout": false,
|
||||
"window": false,
|
||||
"XMLHttpRequest": false,
|
||||
"pit": false,
|
||||
"jasmine": true
|
||||
},
|
||||
|
||||
"rules": {
|
||||
// General
|
||||
"comma-dangle": [1, "always-multiline"], // allow or disallow trailing commas
|
||||
"no-cond-assign": 1, // disallow assignment in conditional expressions
|
||||
"no-console": 0, // disallow use of console (off by default in the node environment)
|
||||
"no-const-assign": 2, // disallow assignment to const-declared variables
|
||||
"no-constant-condition": 0, // disallow use of constant expressions in conditions
|
||||
"no-control-regex": 1, // disallow control characters in regular expressions
|
||||
"no-debugger": 1, // disallow use of debugger
|
||||
"no-dupe-class-members": 2, // Disallow duplicate name in class members
|
||||
"no-dupe-keys": 2, // disallow duplicate keys when creating object literals
|
||||
"no-empty": 0, // disallow empty statements
|
||||
"no-ex-assign": 1, // disallow assigning to the exception in a catch block
|
||||
"no-extra-boolean-cast": 1, // disallow double-negation boolean casts in a boolean context
|
||||
"no-extra-parens": 0, // disallow unnecessary parentheses (off by default)
|
||||
"no-extra-semi": 1, // disallow unnecessary semicolons
|
||||
"no-func-assign": 1, // disallow overwriting functions written as function declarations
|
||||
"no-inner-declarations": 0, // disallow function or variable declarations in nested blocks
|
||||
"no-invalid-regexp": 1, // disallow invalid regular expression strings in the RegExp constructor
|
||||
"no-negated-in-lhs": 1, // disallow negation of the left operand of an in expression
|
||||
"no-obj-calls": 1, // disallow the use of object properties of the global object (Math and JSON) as functions
|
||||
"no-regex-spaces": 1, // disallow multiple spaces in a regular expression literal
|
||||
"no-reserved-keys": 0, // disallow reserved words being used as object literal keys (off by default)
|
||||
"no-sparse-arrays": 1, // disallow sparse arrays
|
||||
"no-unreachable": 2, // disallow unreachable statements after a return, throw, continue, or break statement
|
||||
"use-isnan": 1, // disallow comparisons with the value NaN
|
||||
"valid-jsdoc": 0, // Ensure JSDoc comments are valid (off by default)
|
||||
"valid-typeof": 1, // Ensure that the results of typeof are compared against a valid string
|
||||
|
||||
// Best Practices
|
||||
// These are rules designed to prevent you from making mistakes. They either prescribe a better way of doing something or help you avoid footguns.
|
||||
|
||||
"block-scoped-var": 0, // treat var statements as if they were block scoped (off by default)
|
||||
"complexity": 0, // specify the maximum cyclomatic complexity allowed in a program (off by default)
|
||||
"consistent-return": 0, // require return statements to either always or never specify values
|
||||
"curly": 1, // specify curly brace conventions for all control statements
|
||||
"default-case": 0, // require default case in switch statements (off by default)
|
||||
"dot-notation": 1, // encourages use of dot notation whenever possible
|
||||
"eqeqeq": [1, "allow-null"], // require the use of === and !==
|
||||
"guard-for-in": 0, // make sure for-in loops have an if statement (off by default)
|
||||
"no-alert": 1, // disallow the use of alert, confirm, and prompt
|
||||
"no-caller": 1, // disallow use of arguments.caller or arguments.callee
|
||||
"no-div-regex": 1, // disallow division operators explicitly at beginning of regular expression (off by default)
|
||||
"no-else-return": 0, // disallow else after a return in an if (off by default)
|
||||
"no-eq-null": 0, // disallow comparisons to null without a type-checking operator (off by default)
|
||||
"no-eval": 2, // disallow use of eval()
|
||||
"no-extend-native": 1, // disallow adding to native types
|
||||
"no-extra-bind": 1, // disallow unnecessary function binding
|
||||
"no-fallthrough": 1, // disallow fallthrough of case statements
|
||||
"no-floating-decimal": 1, // disallow the use of leading or trailing decimal points in numeric literals (off by default)
|
||||
"no-implied-eval": 1, // disallow use of eval()-like methods
|
||||
"no-labels": 1, // disallow use of labeled statements
|
||||
"no-iterator": 1, // disallow usage of __iterator__ property
|
||||
"no-lone-blocks": 1, // disallow unnecessary nested blocks
|
||||
"no-loop-func": 0, // disallow creation of functions within loops
|
||||
"no-multi-str": 0, // disallow use of multiline strings
|
||||
"no-native-reassign": 0, // disallow reassignments of native objects
|
||||
"no-new": 1, // disallow use of new operator when not part of the assignment or comparison
|
||||
"no-new-func": 2, // disallow use of new operator for Function object
|
||||
"no-new-wrappers": 1, // disallows creating new instances of String,Number, and Boolean
|
||||
"no-octal": 1, // disallow use of octal literals
|
||||
"no-octal-escape": 1, // disallow use of octal escape sequences in string literals, such as var foo = "Copyright \251";
|
||||
"no-proto": 1, // disallow usage of __proto__ property
|
||||
"no-redeclare": 0, // disallow declaring the same variable more then once
|
||||
"no-return-assign": 1, // disallow use of assignment in return statement
|
||||
"no-script-url": 1, // disallow use of javascript: urls.
|
||||
"no-self-compare": 1, // disallow comparisons where both sides are exactly the same (off by default)
|
||||
"no-sequences": 1, // disallow use of comma operator
|
||||
"no-unused-expressions": 0, // disallow usage of expressions in statement position
|
||||
"no-void": 1, // disallow use of void operator (off by default)
|
||||
"no-warning-comments": 0, // disallow usage of configurable warning terms in comments": 1, // e.g. TODO or FIXME (off by default)
|
||||
"no-with": 1, // disallow use of the with statement
|
||||
"radix": 1, // require use of the second argument for parseInt() (off by default)
|
||||
"semi-spacing": 1, // require a space after a semi-colon
|
||||
"vars-on-top": 0, // requires to declare all vars on top of their containing scope (off by default)
|
||||
"wrap-iife": 0, // require immediate function invocation to be wrapped in parentheses (off by default)
|
||||
"yoda": 1, // require or disallow Yoda conditions
|
||||
|
||||
// Variables
|
||||
// These rules have to do with variable declarations.
|
||||
|
||||
"no-catch-shadow": 1, // disallow the catch clause parameter name being the same as a variable in the outer scope (off by default in the node environment)
|
||||
"no-delete-var": 1, // disallow deletion of variables
|
||||
"no-label-var": 1, // disallow labels that share a name with a variable
|
||||
"no-shadow": 1, // disallow declaration of variables already declared in the outer scope
|
||||
"no-shadow-restricted-names": 1, // disallow shadowing of names such as arguments
|
||||
"no-undef": 2, // disallow use of undeclared variables unless mentioned in a /*global */ block
|
||||
"no-undefined": 0, // disallow use of undefined variable (off by default)
|
||||
"no-undef-init": 1, // disallow use of undefined when initializing variables
|
||||
"no-unused-vars": [1, {"vars": "all", "args": "none", ignoreRestSiblings: true}], // disallow declaration of variables that are not used in the code
|
||||
"no-use-before-define": 0, // disallow use of variables before they are defined
|
||||
|
||||
// Node.js
|
||||
// These rules are specific to JavaScript running on Node.js.
|
||||
|
||||
"handle-callback-err": 1, // enforces error handling in callbacks (off by default) (on by default in the node environment)
|
||||
"no-mixed-requires": 1, // disallow mixing regular variable and require declarations (off by default) (on by default in the node environment)
|
||||
"no-new-require": 1, // disallow use of new operator with the require function (off by default) (on by default in the node environment)
|
||||
"no-path-concat": 1, // disallow string concatenation with __dirname and __filename (off by default) (on by default in the node environment)
|
||||
"no-process-exit": 0, // disallow process.exit() (on by default in the node environment)
|
||||
"no-restricted-modules": 1, // restrict usage of specified node modules (off by default)
|
||||
"no-sync": 0, // disallow use of synchronous methods (off by default)
|
||||
|
||||
// ESLint Comments Plugin
|
||||
// The following rules are made available via `eslint-plugin-eslint-comments`
|
||||
"eslint-comments/no-aggregating-enable": 1, // disallows eslint-enable comments for multiple eslint-disable comments
|
||||
"eslint-comments/no-unlimited-disable": 1, // disallows eslint-disable comments without rule names
|
||||
"eslint-comments/no-unused-disable": 1, // disallow disables that don't cover any errors
|
||||
"eslint-comments/no-unused-enable": 1, // // disallow enables that don't enable anything or enable rules that weren't disabled
|
||||
|
||||
// Flow Plugin
|
||||
// The following rules are made available via `eslint-plugin-flowtype`
|
||||
"flowtype/define-flow-type": 1,
|
||||
"flowtype/use-flow-type": 1,
|
||||
|
||||
// Prettier Plugin
|
||||
// https://github.com/prettier/eslint-plugin-prettier
|
||||
"prettier/prettier": [2, "fb", "@format"],
|
||||
|
||||
// Stylistic Issues
|
||||
// These rules are purely matters of style and are quite subjective.
|
||||
|
||||
"key-spacing": 0,
|
||||
"keyword-spacing": 1, // enforce spacing before and after keywords
|
||||
"jsx-quotes": [1, "prefer-double"], // enforces the usage of double quotes for all JSX attribute values which doesn’t contain a double quote
|
||||
"comma-spacing": 0,
|
||||
"no-multi-spaces": 0,
|
||||
"brace-style": 0, // enforce one true brace style (off by default)
|
||||
"camelcase": 0, // require camel case names
|
||||
"consistent-this": 1, // enforces consistent naming when capturing the current execution context (off by default)
|
||||
"eol-last": 1, // enforce newline at the end of file, with no multiple empty lines
|
||||
"func-names": 0, // require function expressions to have a name (off by default)
|
||||
"func-style": 0, // enforces use of function declarations or expressions (off by default)
|
||||
"new-cap": 0, // require a capital letter for constructors
|
||||
"new-parens": 1, // disallow the omission of parentheses when invoking a constructor with no arguments
|
||||
"no-nested-ternary": 0, // disallow nested ternary expressions (off by default)
|
||||
"no-array-constructor": 1, // disallow use of the Array constructor
|
||||
"no-empty-character-class": 1, // disallow the use of empty character classes in regular expressions
|
||||
"no-lonely-if": 0, // disallow if as the only statement in an else block (off by default)
|
||||
"no-new-object": 1, // disallow use of the Object constructor
|
||||
"no-spaced-func": 1, // disallow space between function identifier and application
|
||||
"no-ternary": 0, // disallow the use of ternary operators (off by default)
|
||||
"no-trailing-spaces": 1, // disallow trailing whitespace at the end of lines
|
||||
"no-underscore-dangle": 0, // disallow dangling underscores in identifiers
|
||||
"no-mixed-spaces-and-tabs": 1, // disallow mixed spaces and tabs for indentation
|
||||
"quotes": [1, "single", "avoid-escape"], // specify whether double or single quotes should be used
|
||||
"quote-props": 0, // require quotes around object literal property names (off by default)
|
||||
"semi": 1, // require or disallow use of semicolons instead of ASI
|
||||
"sort-vars": 0, // sort variables within the same declaration block (off by default)
|
||||
"space-in-brackets": 0, // require or disallow spaces inside brackets (off by default)
|
||||
"space-in-parens": 0, // require or disallow spaces inside parentheses (off by default)
|
||||
"space-infix-ops": 1, // require spaces around operators
|
||||
"space-unary-ops": [1, { "words": true, "nonwords": false }], // require or disallow spaces before/after unary operators (words on by default, nonwords off by default)
|
||||
"max-nested-callbacks": 0, // specify the maximum depth callbacks can be nested (off by default)
|
||||
"one-var": 0, // allow just one var statement per function (off by default)
|
||||
"wrap-regex": 0, // require regex literals to be wrapped in parentheses (off by default)
|
||||
|
||||
// Legacy
|
||||
// The following rules are included for compatibility with JSHint and JSLint. While the names of the rules may not match up with the JSHint/JSLint counterpart, the functionality is the same.
|
||||
|
||||
"max-depth": 0, // specify the maximum depth that blocks can be nested (off by default)
|
||||
"max-len": 0, // specify the maximum length of a line in your program (off by default)
|
||||
"max-params": 0, // limits the number of parameters that can be used in the function declaration. (off by default)
|
||||
"max-statements": 0, // specify the maximum number of statement allowed in a function (off by default)
|
||||
"no-bitwise": 1, // disallow use of bitwise operators (off by default)
|
||||
"no-plusplus": 0, // disallow use of unary operators, ++ and -- (off by default)
|
||||
|
||||
// React Plugin
|
||||
// The following rules are made available via `eslint-plugin-react`.
|
||||
|
||||
"react/display-name": 0,
|
||||
"react/jsx-boolean-value": 0,
|
||||
"react/jsx-no-comment-textnodes": 1,
|
||||
"react/jsx-no-duplicate-props": 2,
|
||||
"react/jsx-no-undef": 2,
|
||||
"react/jsx-sort-props": 0,
|
||||
"react/jsx-uses-react": 1,
|
||||
"react/jsx-uses-vars": 1,
|
||||
"react/no-did-mount-set-state": 1,
|
||||
"react/no-did-update-set-state": 1,
|
||||
"react/no-multi-comp": 0,
|
||||
"react/no-string-refs": 1,
|
||||
"react/no-unknown-property": 0,
|
||||
"react/prop-types": 0,
|
||||
"react/react-in-jsx-scope": 1,
|
||||
"react/self-closing-comp": 1,
|
||||
"react/wrap-multilines": 0,
|
||||
|
||||
// React-Native Plugin
|
||||
// The following rules are made available via `eslint-plugin-react-native`
|
||||
|
||||
"react-native/no-inline-styles": 1,
|
||||
|
||||
// Jest Plugin
|
||||
// The following rules are made available via `eslint-plugin-jest`.
|
||||
"jest/no-disabled-tests": 1,
|
||||
"jest/no-focused-tests": 1,
|
||||
"jest/no-identical-title": 1,
|
||||
"jest/valid-expect": 1,
|
||||
},
|
||||
|
||||
"overrides": [
|
||||
{
|
||||
"files": [
|
||||
"local-cli/**/*.js",
|
||||
],
|
||||
"rules": {
|
||||
"lint/extra-arrow-initializer": 0,
|
||||
"no-alert": 0,
|
||||
"no-console-disallow": 0,
|
||||
},
|
||||
"env": {
|
||||
"node": true,
|
||||
},
|
||||
},
|
||||
],
|
||||
}
|
||||
-105
@@ -1,105 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const path = require('node:path');
|
||||
|
||||
require('eslint-plugin-lint').load(path.join(__dirname, 'tools/eslint/rules'));
|
||||
|
||||
module.exports = {
|
||||
root: true,
|
||||
|
||||
extends: ['@react-native'],
|
||||
|
||||
plugins: ['@react-native/eslint-plugin-specs', 'lint'],
|
||||
|
||||
overrides: [
|
||||
// overriding the JS config from eslint-config-react-native-community config to ensure
|
||||
// that we use hermes-eslint for all js files
|
||||
{
|
||||
files: ['*.js'],
|
||||
parser: 'hermes-eslint',
|
||||
rules: {
|
||||
// These rules are not required with hermes-eslint
|
||||
'ft-flow/define-flow-type': 0,
|
||||
'ft-flow/use-flow-type': 0,
|
||||
// flow handles this check for us, so it's not required
|
||||
'no-undef': 0,
|
||||
},
|
||||
},
|
||||
|
||||
{
|
||||
files: ['packages/react-native/Libraries/**/*.js'],
|
||||
rules: {
|
||||
'@react-native/platform-colors': 2,
|
||||
'@react-native/specs/react-native-modules': 2,
|
||||
'lint/no-haste-imports': 2,
|
||||
'lint/no-react-native-imports': 2,
|
||||
'lint/require-extends-error': 2,
|
||||
'lint/sort-imports': 1,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['packages/react-native/flow-typed/**/*.js'],
|
||||
rules: {
|
||||
'lint/valid-flow-typed-signature': 2,
|
||||
'no-unused-vars': 0,
|
||||
quotes: 0,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: [
|
||||
'**/__fixtures__/**/*.js',
|
||||
'**/__mocks__/**/*.js',
|
||||
'**/__tests__/**/*.js',
|
||||
'packages/react-native/jest/**/*.js',
|
||||
'packages/rn-tester/**/*.js',
|
||||
],
|
||||
globals: {
|
||||
// Expose some Jest globals for test helpers
|
||||
afterAll: true,
|
||||
afterEach: true,
|
||||
beforeAll: true,
|
||||
beforeEach: true,
|
||||
expect: true,
|
||||
jest: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/__tests__/**/*-test.js'],
|
||||
env: {
|
||||
jasmine: true,
|
||||
jest: true,
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.{ts,tsx}'],
|
||||
parser: '@typescript-eslint/parser',
|
||||
plugins: ['@typescript-eslint/eslint-plugin'],
|
||||
rules: {
|
||||
'@typescript-eslint/no-unused-vars': 'off',
|
||||
'react-native/no-inline-styles': 'off',
|
||||
'@typescript-eslint/no-shadow': 'off',
|
||||
'no-self-compare': 'off',
|
||||
'react/self-closing-comp': 'off',
|
||||
},
|
||||
},
|
||||
{
|
||||
files: ['**/*.d.ts'],
|
||||
plugins: ['redundant-undefined'],
|
||||
rules: {
|
||||
'redundant-undefined/redundant-undefined': [
|
||||
'error',
|
||||
{followExactOptionalPropertyTypes: true},
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
};
|
||||
+59
-32
@@ -3,66 +3,90 @@
|
||||
.*/*[.]android.js
|
||||
|
||||
; Ignore templates for 'react-native init'
|
||||
<PROJECT_ROOT>/packages/react-native/template/.*
|
||||
.*/local-cli/templates/.*
|
||||
|
||||
; Ignore the Dangerfile
|
||||
<PROJECT_ROOT>/packages/react-native-bots/dangerfile.js
|
||||
<PROJECT_ROOT>/bots/dangerfile.js
|
||||
|
||||
; Ignore "BUCK" generated dirs
|
||||
<PROJECT_ROOT>/\.buckd/
|
||||
|
||||
; Flow doesn't support platforms
|
||||
.*/packages/react-native/Libraries/Utilities/LoadingView.js
|
||||
; Ignore unexpected extra "@providesModule"
|
||||
.*/node_modules/.*/node_modules/fbjs/.*
|
||||
|
||||
.*/node_modules/resolve/test/resolver/malformed_package_json/package\.json$
|
||||
; Ignore duplicate module providers
|
||||
; For RN Apps installed via npm, "Libraries" folder is inside
|
||||
; "node_modules/react-native" but in the source repo it is in the root
|
||||
.*/Libraries/react-native/React.js
|
||||
|
||||
[untyped]
|
||||
.*/node_modules/@react-native-community/cli/.*/.*
|
||||
; Ignore polyfills
|
||||
.*/Libraries/polyfills/.*
|
||||
|
||||
; These should not be required directly
|
||||
; require from fbjs/lib instead: require('fbjs/lib/invariant')
|
||||
.*/node_modules/invariant/.*
|
||||
.*/node_modules/warning/.*
|
||||
|
||||
[include]
|
||||
|
||||
[declarations]
|
||||
.*/node_modules/.*
|
||||
|
||||
[libs]
|
||||
packages/react-native/interface.js
|
||||
packages/react-native/flow/
|
||||
packages/react-native/flow-typed/
|
||||
Libraries/react-native/react-native-interface.js
|
||||
flow/
|
||||
flow-github/
|
||||
|
||||
[options]
|
||||
enums=true
|
||||
|
||||
emoji=true
|
||||
|
||||
exact_by_default=true
|
||||
esproposal.optional_chaining=enable
|
||||
esproposal.nullish_coalescing=enable
|
||||
|
||||
format.bracket_spacing=false
|
||||
|
||||
module.file_ext=.js
|
||||
module.file_ext=.json
|
||||
module.file_ext=.ios.js
|
||||
module.system=haste
|
||||
module.system.haste.use_name_reducers=true
|
||||
# keep the following in sync with server/haste/hasteImpl.js
|
||||
# get basename
|
||||
module.system.haste.name_reducers='^.*/\([a-zA-Z0-9$_.-]+\.js\(\.flow\)?\)$' -> '\1'
|
||||
# strip .js or .js.flow suffix
|
||||
module.system.haste.name_reducers='^\(.*\)\.js\(\.flow\)?$' -> '\1'
|
||||
# strip .ios suffix
|
||||
module.system.haste.name_reducers='^\(.*\)\.ios$' -> '\1'
|
||||
module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1'
|
||||
module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1'
|
||||
module.system.haste.paths.blacklist=.*/__tests__/.*
|
||||
module.system.haste.paths.blacklist=.*/__mocks__/.*
|
||||
module.system.haste.paths.whitelist=<PROJECT_ROOT>/Libraries/.*
|
||||
module.system.haste.paths.whitelist=<PROJECT_ROOT>/RNTester/.*
|
||||
module.system.haste.paths.whitelist=<PROJECT_ROOT>/IntegrationTests/.*
|
||||
module.system.haste.paths.blacklist=<PROJECT_ROOT>/Libraries/react-native/react-native-implementation.js
|
||||
module.system.haste.paths.blacklist=<PROJECT_ROOT>/Libraries/Animated/src/polyfills/.*
|
||||
|
||||
munge_underscores=true
|
||||
|
||||
module.name_mapper='^react-native$' -> '<PROJECT_ROOT>/packages/react-native/index.js'
|
||||
module.name_mapper='^react-native/\(.*\)$' -> '<PROJECT_ROOT>/packages/react-native\1'
|
||||
module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '<PROJECT_ROOT>/packages/react-native/Libraries/Image/RelativeImageStub'
|
||||
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
|
||||
|
||||
suppress_type=$FlowIssue
|
||||
suppress_type=$FlowFixMe
|
||||
suppress_type=$FlowFixMeProps
|
||||
suppress_type=$FlowFixMeState
|
||||
suppress_type=$FlowFixMeEmpty
|
||||
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_ios\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
|
||||
|
||||
[lints]
|
||||
all=warn
|
||||
unnecessary-optional-chain=off
|
||||
|
||||
# There is an ESLint rule for this
|
||||
unclear-type=off
|
||||
|
||||
sketchy-null=off
|
||||
sketchy-null-number=warn
|
||||
sketchy-null-mixed=warn
|
||||
sketchy-number=warn
|
||||
untyped-type-import=warn
|
||||
nonstrict-import=warn
|
||||
deprecated-type=error
|
||||
unsafe-getters-setters=warn
|
||||
unnecessary-invariant=warn
|
||||
|
||||
# This is noisy for now. We *do* still want to warn on importing types
|
||||
# from untyped files, which is covered by untyped-type-import
|
||||
untyped-import=off
|
||||
|
||||
[strict]
|
||||
deprecated-type
|
||||
@@ -74,4 +98,7 @@ untyped-import
|
||||
untyped-type-import
|
||||
|
||||
[version]
|
||||
^0.202.0
|
||||
^0.86.0
|
||||
|
||||
[untyped]
|
||||
.*/node_modules/metro/.*
|
||||
|
||||
+59
-32
@@ -3,66 +3,90 @@
|
||||
.*/*[.]ios.js
|
||||
|
||||
; Ignore templates for 'react-native init'
|
||||
<PROJECT_ROOT>/packages/react-native/template/.*
|
||||
.*/local-cli/templates/.*
|
||||
|
||||
; Ignore the Dangerfile
|
||||
<PROJECT_ROOT>/packages/react-native-bots/dangerfile.js
|
||||
<PROJECT_ROOT>/bots/dangerfile.js
|
||||
|
||||
; Ignore "BUCK" generated dirs
|
||||
<PROJECT_ROOT>/\.buckd/
|
||||
|
||||
; Flow doesn't support platforms
|
||||
.*/packages/react-native/Libraries/Utilities/LoadingView.js
|
||||
; Ignore unexpected extra "@providesModule"
|
||||
.*/node_modules/.*/node_modules/fbjs/.*
|
||||
|
||||
.*/node_modules/resolve/test/resolver/malformed_package_json/package\.json$
|
||||
; Ignore duplicate module providers
|
||||
; For RN Apps installed via npm, "Libraries" folder is inside
|
||||
; "node_modules/react-native" but in the source repo it is in the root
|
||||
.*/Libraries/react-native/React.js
|
||||
|
||||
[untyped]
|
||||
.*/node_modules/@react-native-community/cli/.*/.*
|
||||
; Ignore polyfills
|
||||
.*/Libraries/polyfills/.*
|
||||
|
||||
; These should not be required directly
|
||||
; require from fbjs/lib instead: require('fbjs/lib/invariant')
|
||||
.*/node_modules/invariant/.*
|
||||
.*/node_modules/warning/.*
|
||||
|
||||
[include]
|
||||
|
||||
[declarations]
|
||||
.*/node_modules/.*
|
||||
|
||||
[libs]
|
||||
packages/react-native/interface.js
|
||||
packages/react-native/flow/
|
||||
packages/react-native/flow-typed/
|
||||
Libraries/react-native/react-native-interface.js
|
||||
flow/
|
||||
flow-github/
|
||||
|
||||
[options]
|
||||
enums=true
|
||||
|
||||
emoji=true
|
||||
|
||||
exact_by_default=true
|
||||
esproposal.optional_chaining=enable
|
||||
esproposal.nullish_coalescing=enable
|
||||
|
||||
format.bracket_spacing=false
|
||||
|
||||
module.file_ext=.js
|
||||
module.file_ext=.json
|
||||
module.file_ext=.android.js
|
||||
module.system=haste
|
||||
module.system.haste.use_name_reducers=true
|
||||
# keep the following in sync with server/haste/hasteImpl.js
|
||||
# get basename
|
||||
module.system.haste.name_reducers='^.*/\([a-zA-Z0-9$_.-]+\.js\(\.flow\)?\)$' -> '\1'
|
||||
# strip .js or .js.flow suffix
|
||||
module.system.haste.name_reducers='^\(.*\)\.js\(\.flow\)?$' -> '\1'
|
||||
# strip .android suffix
|
||||
module.system.haste.name_reducers='^\(.*\)\.android$' -> '\1'
|
||||
module.system.haste.name_reducers='^\(.*\)\.ios$' -> '\1'
|
||||
module.system.haste.name_reducers='^\(.*\)\.native$' -> '\1'
|
||||
module.system.haste.paths.blacklist=.*/__tests__/.*
|
||||
module.system.haste.paths.blacklist=.*/__mocks__/.*
|
||||
module.system.haste.paths.whitelist=<PROJECT_ROOT>/Libraries/.*
|
||||
module.system.haste.paths.whitelist=<PROJECT_ROOT>/RNTester/.*
|
||||
module.system.haste.paths.whitelist=<PROJECT_ROOT>/IntegrationTests/.*
|
||||
module.system.haste.paths.blacklist=<PROJECT_ROOT>/Libraries/react-native/react-native-implementation.js
|
||||
module.system.haste.paths.blacklist=<PROJECT_ROOT>/Libraries/Animated/src/polyfills/.*
|
||||
|
||||
munge_underscores=true
|
||||
|
||||
module.name_mapper='^react-native$' -> '<PROJECT_ROOT>/packages/react-native/index.js'
|
||||
module.name_mapper='^react-native/\(.*\)$' -> '<PROJECT_ROOT>/packages/react-native\1'
|
||||
module.name_mapper='^@?[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> '<PROJECT_ROOT>/packages/react-native/Libraries/Image/RelativeImageStub'
|
||||
module.name_mapper='^[./a-zA-Z0-9$_-]+\.\(bmp\|gif\|jpg\|jpeg\|png\|psd\|svg\|webp\|m4v\|mov\|mp4\|mpeg\|mpg\|webm\|aac\|aiff\|caf\|m4a\|mp3\|wav\|html\|pdf\)$' -> 'RelativeImageStub'
|
||||
|
||||
suppress_type=$FlowIssue
|
||||
suppress_type=$FlowFixMe
|
||||
suppress_type=$FlowFixMeProps
|
||||
suppress_type=$FlowFixMeState
|
||||
suppress_type=$FlowFixMeEmpty
|
||||
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixMe\\($\\|[^(]\\|(\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_android\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowIssue\\((\\(<VERSION>\\)? *\\(site=[a-z,_]*react_native\\(_android\\)?_\\(oss\\|fb\\)[a-z,_]*\\)?)\\)?:? #[0-9]+
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowFixedInNextDeploy
|
||||
suppress_comment=\\(.\\|\n\\)*\\$FlowExpectedError
|
||||
|
||||
[lints]
|
||||
all=warn
|
||||
unnecessary-optional-chain=off
|
||||
|
||||
# There is an ESLint rule for this
|
||||
unclear-type=off
|
||||
|
||||
sketchy-null=off
|
||||
sketchy-null-number=warn
|
||||
sketchy-null-mixed=warn
|
||||
sketchy-number=warn
|
||||
untyped-type-import=warn
|
||||
nonstrict-import=warn
|
||||
deprecated-type=error
|
||||
unsafe-getters-setters=warn
|
||||
unnecessary-invariant=warn
|
||||
|
||||
# This is noisy for now. We *do* still want to warn on importing types
|
||||
# from untyped files, which is covered by untyped-type-import
|
||||
untyped-import=off
|
||||
|
||||
[strict]
|
||||
deprecated-type
|
||||
@@ -74,4 +98,7 @@ untyped-import
|
||||
untyped-type-import
|
||||
|
||||
[version]
|
||||
^0.202.0
|
||||
^0.86.0
|
||||
|
||||
[untyped]
|
||||
.*/node_modules/metro/.*
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
# Force LF line endings for Bash scripts. On Windows the rest of the source
|
||||
# files will typically have CR+LF endings (Git default on Windows), but Bash
|
||||
# scripts need to have LF endings to work (under Cygwin), thus override to force
|
||||
# that.
|
||||
gradlew text eol=lf
|
||||
*.sh text eol=lf
|
||||
+10
-36
@@ -1,40 +1,14 @@
|
||||
# See https://help.github.com/en/articles/about-code-owners
|
||||
# to learn more about code owners.
|
||||
# Order is important; the last matching pattern takes the most
|
||||
# precedence. You may specify either a GitHub username, or an
|
||||
# email address if you prefer, as the code owner.
|
||||
|
||||
# Any Markdown file anywhere in the repository
|
||||
**/*.md @hramos @cpojer
|
||||
|
||||
# GitHub Settings, Bots
|
||||
/.github/ @hramos
|
||||
/packages/react-native-bots @hramos
|
||||
|
||||
# Continuous Integration
|
||||
/.circleci/ @hramos
|
||||
/.circleci/Dockerfiles @gengjiawen
|
||||
/.appveyor/ @gengjiawen
|
||||
|
||||
# Internals
|
||||
React/Base/* @shergin
|
||||
React/Views/* @shergin
|
||||
React/Modules/* @shergin
|
||||
React/CxxBridge/* @mhorowitz
|
||||
|
||||
# Components and APIs
|
||||
ReactAndroid/src/main/java/com/facebook/react/animated/* @janicduplessis
|
||||
Libraries/Animated/* @janicduplessis
|
||||
Libraries/NativeAnimation/* @janicduplessis
|
||||
Libraries/Image/* @shergin
|
||||
Libraries/Text/* @shergin
|
||||
|
||||
# Modifications to package.json typically require
|
||||
# additional effort from a Facebook employee to land
|
||||
/package.json @hramos @cpojer
|
||||
|
||||
# These should not be modified through a GitHub PR
|
||||
LICENSE* @hramos @cpojer @yungsters
|
||||
|
||||
# The eslint-config-react-native-community package requires manual publishing after merging
|
||||
/packages/eslint-config-react-native-community/* @matt-oakes
|
||||
React/Base/* @shergin
|
||||
React/Views/* @shergin
|
||||
React/Modules/* @shergin
|
||||
React/CxxBridge/* @mhorowitz
|
||||
ReactAndroid/src/main/java/com/facebook/react/animated/* @janicduplessis
|
||||
**/*.md @hramos
|
||||
package.json @hramos
|
||||
local-cli/core/* @grabbou @kureev
|
||||
local-cli/link/* @grabbou @kureev
|
||||
local-cli/unlink/* @grabbou @kureev
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
✋ To keep the backlog clean and actionable, issues will be
|
||||
🚫 closed if they do not follow one of the issue templates:
|
||||
👉 https://github.com/facebook/react-native/issues/new/choose
|
||||
GitHub Issues in the `facebook/react-native` repository are used exclusively for tracking bugs in React Native.
|
||||
|
||||
Please take a look at the issue templates at https://github.com/facebook/react-native/issues/new/choose before submitting a new issue. Following one of the issue templates will ensure maintainers can route your request efficiently. Thanks!
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
name: 🐛 Bug Report
|
||||
about: Report a reproducible bug or regression in the core React Native library.
|
||||
---
|
||||
|
||||
<!-- Requirements: please go through this checklist before opening a new issue -->
|
||||
- [ ] Review the documentation: https://facebook.github.io/react-native
|
||||
- [ ] Search for existing issues: https://github.com/facebook/react-native/issues
|
||||
- [ ] Use the latest React Native release: https://github.com/facebook/react-native/releases
|
||||
|
||||
## Environment
|
||||
Run `react-native info` in your terminal and paste its contents here.
|
||||
|
||||
## Description
|
||||
Describe your issue in detail. Include screenshots if needed. If this is a regression, let us know.
|
||||
|
||||
## Reproducible Demo
|
||||
Let us know how to reproduce the issue. Include a code sample, share a project, or share an app that reproduces the issue using https://snack.expo.io/. Please follow the guidelines for providing a MCVE: https://stackoverflow.com/help/mcve
|
||||
@@ -1,48 +0,0 @@
|
||||
name: 🐛 Bug Report
|
||||
description: Report a reproducible bug or regression in React Native.
|
||||
labels: ["Needs: Triage :mag:"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please provide all the information requested. Issues that do not follow this format are likely to stall.
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: Please provide a clear and concise description of what the bug is. Include screenshots if needed. Test using the [latest React Native release](https://github.com/facebook/react-native/releases/latest) to make sure your issue has not already been fixed.
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: React Native Version
|
||||
description: What is the latest version of react-native that this issue reproduces on? Please only list the highest version you tested. Bear in mind that only issues on [supported versions](https://github.com/reactwg/react-native-releases#which-versions-are-currently-supported) will be looked into.
|
||||
placeholder: ex. 0.71.0
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: react-native-info
|
||||
attributes:
|
||||
label: Output of `npx react-native info`
|
||||
description: Run `npx react-native info` in your terminal, copy and paste the results here.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Provide a detailed list of steps that reproduce the issue.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: extra
|
||||
attributes:
|
||||
label: Snack, code example, screenshot, or link to a repository
|
||||
description: |
|
||||
Please provide a Snack (https://snack.expo.dev/), a link to a repository on GitHub, or provide a minimal code example that reproduces the problem.
|
||||
You may provide a screenshot of the application if you think it is relevant to your bug report.
|
||||
Here are some tips for providing a minimal example: https://stackoverflow.com/help/mcve
|
||||
Please note that a reproducer is **mandatory**. Issues without reproducer are more likely to stall and will be closed.
|
||||
validations:
|
||||
required: true
|
||||
@@ -1,14 +0,0 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: 📃 Documentation Issue
|
||||
url: https://github.com/facebook/react-native-website/issues
|
||||
about: Please report documentation issues in the React Native website repository.
|
||||
- name: 🤔 Questions and Help
|
||||
url: https://reactnative.dev/help
|
||||
about: Looking for help with your app? Please refer to the React Native community's support resources.
|
||||
- name: 💫 New Architecture - Questions & Technical Deep dive insights
|
||||
url: https://github.com/reactwg/react-native-new-architecture
|
||||
about: Questions and doubts related to technical questions for the New Architecture should be directed to the Working Group. Instructions on how to join are available in the README.
|
||||
- name: 🚀 Discussions and Proposals
|
||||
url: https://github.com/react-native-community/discussions-and-proposals
|
||||
about: Discuss the future of React Native in the React Native community's discussions and proposals repository.
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
name: 🗣 Start a Discussion
|
||||
about: Use https://github.com/react-native-community/discussions-and-proposals to propose changes or discuss feature requests.
|
||||
---
|
||||
|
||||
Use https://github.com/react-native-community/discussions-and-proposals to propose changes or discuss feature requests. This helps us ensure bug reports and regressions are given the priority they require.
|
||||
|
||||
You may also use https://discuss.reactjs.org/ for discussions on topics that are not necessarily served by the Bug Report template.
|
||||
|
||||
---
|
||||
|
||||
# For Discussion
|
||||
|
||||
<!--
|
||||
If you feel strongly about having your discussion in the main React Native repository, you may write your proposal here.
|
||||
|
||||
Please note that there is a high probability your issue will be closed by a maintainer, who may kindly ask you to move the discussion elsewhere.
|
||||
-->
|
||||
@@ -0,0 +1,11 @@
|
||||
---
|
||||
name: 📖 Documentation Issue
|
||||
about: Report issues with the docs at https://github.com/facebook/react-native-website/issues.
|
||||
|
||||
---
|
||||
|
||||
--------------^ Click "Preview" for a nicer view!
|
||||
|
||||
GitHub Issues in the `facebook/react-native` repository are used exclusively for tracking bugs in React Native.
|
||||
|
||||
If you would like to report an issue in the React Native documentation, or anything related to the [React Native website](http://facebook.github.io/react-native), please visit https://github.com/facebook/react-native-website/issues.
|
||||
@@ -1,53 +0,0 @@
|
||||
name: 💫 New Architecture - Bug Report
|
||||
description: Report a reproducible bug or a build issue when using the New Architecture (Fabric & TurboModules) in React Native.
|
||||
labels: ["Needs: Triage :mag:", "Type: New Architecture"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please provide all the information requested. Issues that do not follow this format are going to be closed.
|
||||
This issue report is reserved to bug & build issues for users on the New Architecture. If you're not using
|
||||
the New Architecture, please don't open issues on this category.
|
||||
- type: textarea
|
||||
id: description
|
||||
attributes:
|
||||
label: Description
|
||||
description: |
|
||||
Please provide a clear and concise description of what the bug or issue is. Include screenshots if needed.
|
||||
Please make sure you check the New Architecture documentation first, as your issue might
|
||||
already be answered there - https://reactnative.dev/docs/next/new-architecture-intro
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: version
|
||||
attributes:
|
||||
label: React Native Version
|
||||
description: What is the latest version of react-native that this issue reproduces on? Please test against the latest stable version, and list only the highest version you tested. Bug reports against older versions are more likely to stall.
|
||||
placeholder: ex. 0.71.0
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: react-native-info
|
||||
attributes:
|
||||
label: Output of `npx react-native info`
|
||||
description: Run `npx react-native info` in your terminal, copy and paste the results here.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: Steps to reproduce
|
||||
description: Provide a detailed list of steps that reproduce the issue.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: extra
|
||||
attributes:
|
||||
label: Snack, code example, screenshot, or link to a repository
|
||||
description: |
|
||||
Please provide a Snack (https://snack.expo.dev/), a link to a repository on GitHub, or provide a minimal code example that reproduces the problem.
|
||||
You may provide a screenshot of the application if you think it is relevant to your bug report.
|
||||
Here are some tips for providing a minimal example: https://stackoverflow.com/help/mcve
|
||||
Please note that a reproducer is **mandatory**. Issues without reproducer are more likely to stall and will be closed.
|
||||
validations:
|
||||
required: true
|
||||
@@ -0,0 +1,21 @@
|
||||
---
|
||||
name: 💬 Question
|
||||
about: If you need help with your React Native app, the right place to go depends on the type of help that you need.
|
||||
|
||||
---
|
||||
|
||||
--------------^ Click "Preview" for a nicer view!
|
||||
|
||||
GitHub Issues in the `facebook/react-native` repository are used exclusively for tracking bugs in React Native. GitHub may not be the ideal place to ask questions about using React Native, but we have compiled a list of resources that should help.
|
||||
|
||||
### Get help with your React Native app or ask code-level questions
|
||||
|
||||
Many members of the community use Stack Overflow to ask questions. Read through the [existing questions](http://stackoverflow.com/questions/tagged/react-native?sort=frequent) tagged with **react-native** or [ask your own](http://stackoverflow.com/questions/ask?tags=react-native)!
|
||||
|
||||
### Talk about best practices or propose changes to React Native
|
||||
|
||||
For longer-form conversations about React Native, we’ve set up a [discussion forum at **discuss.reactjs.org**](https://discuss.reactjs.org/t/welcome-react-native-community-group/10239). This forum is a great place for discussion about best practices and application architecture as well as the future of React Native.
|
||||
|
||||
### Chat with React and React Native community members
|
||||
|
||||
If you need an answer right away, check out the [Reactiflux Discord](https://discord.gg/0ZcbPKXt5bZjGY5n) community. There are usually a number of React Native experts there who can help out or point you to somewhere you might want to look.
|
||||
@@ -1,46 +0,0 @@
|
||||
name: ⬆️ Upgrade - Build Regression
|
||||
description: If you are upgrading to a new React Native version (stable or pre-release) and encounter a build regression.
|
||||
labels: ["Needs: Triage :mag:", "Type: Upgrade Issue"]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Please use this form to file an issue if you have upgraded or are upgrading to [latest stable release](https://github.com/facebook/react-native/releases/latest) and have experienced a regression (something that used to work in previous version).
|
||||
- type: input
|
||||
id: new-version
|
||||
attributes:
|
||||
label: New Version
|
||||
description: This is the version you are attempting to upgrade to.
|
||||
placeholder: ex. 0.66.1
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: old-version
|
||||
attributes:
|
||||
label: Old Version
|
||||
description: This is the version you were on where the behavior was working.
|
||||
placeholder: ex. 0.65.1
|
||||
validations:
|
||||
required: true
|
||||
- type: input
|
||||
id: target
|
||||
attributes:
|
||||
label: Build Target(s)
|
||||
description: What target(s) are encountering this issue?
|
||||
placeholder: iOS simulator in release flavor
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: react-native-info
|
||||
attributes:
|
||||
label: Output of `react-native info`
|
||||
description: Run `react-native info` in your terminal, copy and paste the results here.
|
||||
validations:
|
||||
required: true
|
||||
- type: textarea
|
||||
id: reproduction
|
||||
attributes:
|
||||
label: Issue and Reproduction Steps
|
||||
description: Please describe the issue and list out commands run to reproduce.
|
||||
validations:
|
||||
required: true
|
||||
@@ -1,21 +1,45 @@
|
||||
<!-- Thanks for submitting a pull request! We appreciate you spending the time to work on these changes. Please provide enough information so that others can review your pull request. The three fields below are mandatory. -->
|
||||
Thank you for sending the PR! We appreciate you spending the time to work on these changes.
|
||||
Help us understand your motivation by explaining why you decided to make this change.
|
||||
|
||||
## Summary
|
||||
If this PR fixes an issue, type "Fixes #issueNumber" to automatically close the issue when the PR is merged.
|
||||
|
||||
<!-- Explain the **motivation** for making this change. What existing problem does the pull request solve? -->
|
||||
_Pull requests that expand test coverage are more likely to get reviewed. Add a test case whenever possible!_
|
||||
|
||||
## Changelog
|
||||
Test Plan:
|
||||
----------
|
||||
Write your test plan here. If you changed any code, please provide us with clear instructions on how you verified your changes work. Bonus points for screenshots and videos!
|
||||
|
||||
<!-- Help reviewers and the release process by writing your own changelog entry.
|
||||
Changelog:
|
||||
----------
|
||||
Help reviewers and the release process by writing your own changelog entry. When the change doesn't impact React Native developers, it may be ommitted from the changelog for brevity. See below for an example.
|
||||
|
||||
Pick one each for the category and type tags:
|
||||
[CATEGORY] [TYPE] - Message
|
||||
|
||||
[ANDROID|GENERAL|IOS|INTERNAL] [BREAKING|ADDED|CHANGED|DEPRECATED|REMOVED|FIXED|SECURITY] - Message
|
||||
<!--
|
||||
|
||||
For more details, see:
|
||||
https://reactnative.dev/contributing/changelogs-in-pull-requests
|
||||
-->
|
||||
CATEGORY may be:
|
||||
|
||||
## Test Plan
|
||||
- [General]
|
||||
- [iOS]
|
||||
- [Android]
|
||||
|
||||
<!-- Demonstrate the code is solid. Example: The exact commands you ran and their output, screenshots / videos if the pull request changes the user interface. -->
|
||||
TYPE may be:
|
||||
|
||||
- [Added] for new features.
|
||||
- [Changed] for changes in existing functionality.
|
||||
- [Deprecated] for soon-to-be removed features.
|
||||
- [Removed] for now removed features.
|
||||
- [Fixed] for any bug fixes.
|
||||
- [Security] in case of vulnerabilities.
|
||||
|
||||
For more detail, see https://keepachangelog.com/en/1.0.0/#how
|
||||
|
||||
MESSAGE may answer "what and why" on a feature level. Use this to briefly tell React Native users about notable changes.
|
||||
|
||||
EXAMPLES:
|
||||
|
||||
[General] [Added] - Add snapToOffsets prop to ScrollView component
|
||||
[General] [Fixed] - Fix various issues in snapToInterval on ScrollView component
|
||||
[iOS] [Fixed] - Fix crash in RCTImagePicker
|
||||
|
||||
-->
|
||||
@@ -1,23 +0,0 @@
|
||||
<!-- Template for pre-release GitHub release -->
|
||||
|
||||
<!-- TODO Post about this release to https://github.com/reactwg/react-native-releases/discussions) -->
|
||||
|
||||
- <!-- TODO List out notable picks for this patch -->
|
||||
|
||||
---
|
||||
|
||||
To test it, run:
|
||||
|
||||
npx react-native init RN__SHORT_VERSION__ --version __VERSION__
|
||||
|
||||
---
|
||||
|
||||
You can participate in the conversation on the status of this release in the [working group](https://github.com/reactwg/react-native-releases/discussions).
|
||||
|
||||
---
|
||||
|
||||
To help you upgrade to this version, you can use the [upgrade helper](https://react-native-community.github.io/upgrade-helper/) ⚛️
|
||||
|
||||
---
|
||||
|
||||
See changes from this release in the [changelog PR](https://github.com/facebook/react-native/labels/%F0%9F%93%9D%20Changelog)
|
||||
@@ -1,35 +0,0 @@
|
||||
Thanks for using React Native! If you need help with your React Native app, the right place to go depends on the type of help that you need.
|
||||
|
||||
|
||||
## 🤔 I have a question or need help with my React Native app.
|
||||
|
||||
If you have a coding question related to React Native, it might be better suited for Stack Overflow. It's a great place to browse through [frequent questions about using React Native](https://stackoverflow.com/questions/tagged/react-native?sort=frequent&pageSize=15), as well as [ask for help with specific questions](https://stackoverflow.com/questions/tagged/react-native).
|
||||
|
||||
[Reactiflux](https://www.reactiflux.com/) is an active community of React and React Native developers. If you are looking for immediate assistance or have a general question about React Native, the #react-native channel is a good place to start.
|
||||
|
||||
|
||||
## 📃 I found something that seems wrong in the documentation.
|
||||
|
||||
The React Native website is hosted on a [separate repository](https://github.com/facebook/react-native-website). If you want to report something that is wrong or missing from the documentation, [please open a new issue there](https://github.com/facebook/react-native-website/issues).
|
||||
|
||||
|
||||
## 🐛 I found a bug in React Native.
|
||||
|
||||
If you want to report a reproducible bug or regression in the React Native library, you can [create a new issue](https://github.com/facebook/react-native/issues/new?labels=Type%3A+Bug+Report&template=bug_report.md). It's a good idea to look through [open issues](https://github.com/facebook/react-native/issues) before doing so, as someone else may have reported a similar issue.
|
||||
|
||||
|
||||
## 🚀 I want to discuss the future of React Native.
|
||||
|
||||
If you'd like to discuss topics related to the future of React Native, please check out the [React Native Community Discussions and Proposals](https://github.com/react-native-community/discussions-and-proposals) repository.
|
||||
|
||||
|
||||
## 💬 I want to talk to other React Native developers.
|
||||
|
||||
If you want to participate in casual discussions about the use of React Native, consider participating in one of the following forums:
|
||||
|
||||
- [Reactiflux Discord Server](https://www.reactiflux.com)
|
||||
- [Spectrum Chat](https://spectrum.chat/react-native)
|
||||
- [React Native Community Facebook Group](https://www.facebook.com/groups/react.native.community)
|
||||
|
||||
|
||||
> For a full list of community resources, check out [React Native's Community page](https://reactnative.dev/help).
|
||||
@@ -0,0 +1,24 @@
|
||||
# Configuration for probot-stale - https://github.com/probot/stale
|
||||
# Number of days of inactivity before an issue becomes stale
|
||||
daysUntilStale: 90
|
||||
# Number of days of inactivity before a stale issue is closed
|
||||
daysUntilClose: 7
|
||||
# Issues with these labels will never be considered stale
|
||||
exemptLabels:
|
||||
- Good first issue
|
||||
- For Discussion
|
||||
- Core Team
|
||||
- "Help Wanted :octocat:"
|
||||
- ":warning:Regression"
|
||||
- ":clock1:PR Pending"
|
||||
# Label to use when marking an issue as stale
|
||||
staleLabel: Stale
|
||||
# Comment to post when marking an issue as stale. Set to `false` to disable
|
||||
markComment: >
|
||||
Hey there, it looks like there has been no activity on this issue recently. Has the issue been fixed, or does it still require the community's attention? This issue may be closed if no further activity occurs.
|
||||
You may also label this issue as "For Discussion" or "Good first issue" and I will leave it open.
|
||||
Thank you for your contributions.
|
||||
# Comment to post when closing a stale issue. Set to `false` to disable
|
||||
closeComment: >
|
||||
Closing this issue after a prolonged period of inactivity. If this issue is still present in the latest release, please feel free to create a new issue with up-to-date information.
|
||||
only: issues
|
||||
@@ -1,137 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
module.exports = async (github, context, label) => {
|
||||
const closeIssue = async () => {
|
||||
await github.rest.issues.update({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
state: 'closed',
|
||||
});
|
||||
};
|
||||
|
||||
const addComment = async comment => {
|
||||
await github.rest.issues.createComment({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: comment,
|
||||
});
|
||||
};
|
||||
|
||||
const requestAuthorFeedback = async () => {
|
||||
// Remove the triage label if it exists (ignore the 404 if not; it's not expected to always be there)
|
||||
try {
|
||||
await github.rest.issues.removeLabel({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
name: 'Needs: Triage :mag:',
|
||||
});
|
||||
} catch {}
|
||||
|
||||
await github.rest.issues.addLabels({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: ['Needs: Author Feedback'],
|
||||
});
|
||||
};
|
||||
|
||||
switch (label) {
|
||||
case 'Type: Invalid':
|
||||
await addComment(
|
||||
`| :warning: | Issue is Invalid |\n` +
|
||||
`| --- | --- |\n` +
|
||||
`| :information_source: | This issue doesn't match any of the expected types for this repository - closing. |`,
|
||||
);
|
||||
await closeIssue();
|
||||
return;
|
||||
case 'Type: Question':
|
||||
await addComment(
|
||||
`| :warning: | Issue is a Question |\n` +
|
||||
`| --- | --- |\n` +
|
||||
`| :information_source: | We are using GitHub issues exclusively to track bugs in React Native. GitHub may not be the ideal place to ask a question, but you can try asking over on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native), or on [Reactiflux](https://www.reactiflux.com/). |`,
|
||||
);
|
||||
await closeIssue();
|
||||
return;
|
||||
case 'Type: Docs':
|
||||
await addComment(
|
||||
`| :warning: | Documentation Issue |\n` +
|
||||
`| --- | --- |\n` +
|
||||
`| :information_source: | Please report documentation issues in the [react-native-website](https://github.com/facebook/react-native-website/issues) repository. |`,
|
||||
);
|
||||
await closeIssue();
|
||||
return;
|
||||
case 'Resolution: For Stack Overflow':
|
||||
await addComment(
|
||||
`| :warning: | Issue is a Question |\n` +
|
||||
`| --- | --- |\n` +
|
||||
`| :information_source: | We are using GitHub issues exclusively to track bugs in the core React Native library. Please try asking over on [Stack Overflow](http://stackoverflow.com/questions/tagged/react-native) as it is better suited for this type of question. |`,
|
||||
);
|
||||
await closeIssue();
|
||||
return;
|
||||
case 'Type: Expo':
|
||||
await addComment(
|
||||
`| :warning: | Issue is Related to Expo |\n` +
|
||||
`| --- | --- |\n` +
|
||||
`| :information_source: | It looks like your issue is related to Expo and not React Native core. Please open your issue in [Expo's repository](https://github.com/expo/expo/issues/new). If you are able to create a repro that showcases that this issue is also happening in React Native vanilla, we will be happy to re-open. |`,
|
||||
);
|
||||
await closeIssue();
|
||||
return;
|
||||
case 'Needs: Issue Template':
|
||||
await addComment(
|
||||
`| :warning: | Missing Required Fields |\n` +
|
||||
`| --- | --- |\n` +
|
||||
`| :information_source: | It looks like your issue may be missing some necessary information. GitHub provides an example template whenever a [new issue is created](https://github.com/facebook/react-native/issues/new?template=bug_report.md). Could you go back and make sure to fill out the template? You may edit this issue, or close it and open a new one. |`,
|
||||
);
|
||||
await requestAuthorFeedback();
|
||||
return;
|
||||
case 'Needs: Environment Info':
|
||||
await addComment(
|
||||
`| :warning: | Missing Environment Information |\n` +
|
||||
`| --- | --- |\n` +
|
||||
`| :information_source: | Your issue may be missing information about your development environment. You can obtain the missing information by running <code>react-native info</code> in a console. |`,
|
||||
);
|
||||
await requestAuthorFeedback();
|
||||
return;
|
||||
case 'Needs: Verify on Latest Version':
|
||||
await addComment(
|
||||
`| :warning: | Newer Version of React Native is Available! |\n` +
|
||||
`| --- | --- |\n` +
|
||||
`| :information_source: | You are on a supported minor version, but it looks like there's a newer patch available. Please [upgrade](https://reactnative.dev/docs/upgrading) to the highest patch for your minor or latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If it does not repro, please let us know so we can close out this issue. This helps us ensure we are looking at issues that still exist in the most recent releases. |`,
|
||||
);
|
||||
return;
|
||||
case 'Needs: Version Info':
|
||||
await addComment(
|
||||
`| :warning: | Add or Reformat Version Info |\n` +
|
||||
`| --- | --- |\n` +
|
||||
`| :information_source: | We could not find or parse the version number of React Native in your issue report. Please use the template, and report your version including major, minor, and patch numbers - e.g. 0.70.2 |`,
|
||||
);
|
||||
await requestAuthorFeedback();
|
||||
return;
|
||||
case 'Needs: Repro':
|
||||
await addComment(
|
||||
`| :warning: | Missing Reproducible Example |\n` +
|
||||
`| --- | --- |\n` +
|
||||
`| :information_source: | It looks like your issue is missing a reproducible example. Please provide a [Snack](https://snack.expo.dev) or a repository that demonstrates the issue you are reporting in a [minimal, complete, and reproducible](https://stackoverflow.com/help/minimal-reproducible-example) manner. |`,
|
||||
);
|
||||
await requestAuthorFeedback();
|
||||
return;
|
||||
case 'Type: Unsupported Version':
|
||||
await addComment(
|
||||
`| :warning: | Unsupported Version of React Native |\n` +
|
||||
`| --- | --- |\n` +
|
||||
`| :information_source: | It looks like your issue or the example you provided uses an [unsupported version of React Native](https://github.com/reactwg/react-native-releases/blob/main/README.md#releases-support-policy). Due to the number of issues we receive, we're currently only accepting new issues against one of the supported versions. Please [upgrade](https://reactnative.dev/docs/upgrading) to latest and verify if the issue persists (alternatively, create a new project and repro the issue in it). If you cannot upgrade, please open your issue on [StackOverflow](https://stackoverflow.com/questions/tagged/react-native) to get further community support. |`,
|
||||
);
|
||||
await requestAuthorFeedback();
|
||||
return;
|
||||
}
|
||||
};
|
||||
@@ -1,22 +0,0 @@
|
||||
name: Apply version label to issue
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened, edited]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
add-version-label-issue:
|
||||
permissions:
|
||||
issues: write # for react-native-community/actions-apply-version-label to label issues
|
||||
runs-on: ubuntu-latest
|
||||
continue-on-error: true
|
||||
if: github.repository == 'facebook/react-native'
|
||||
|
||||
steps:
|
||||
- uses: react-native-community/actions-apply-version-label@v0.0.3
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
required-label: "Type: Upgrade Issue"
|
||||
@@ -1,24 +0,0 @@
|
||||
name: Automatic Rebase
|
||||
on:
|
||||
issue_comment:
|
||||
types: [created]
|
||||
permissions:
|
||||
contents: read
|
||||
jobs:
|
||||
rebase:
|
||||
permissions:
|
||||
contents: write # for cirrus-actions/rebase to push code to rebase
|
||||
pull-requests: read # for cirrus-actions/rebase to get info about PR
|
||||
name: Rebase
|
||||
if: github.event.issue.pull_request != '' && contains(github.event.comment.body, '/rebase')
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout the latest code
|
||||
uses: actions/checkout@v2
|
||||
with:
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
fetch-depth: 0 # otherwise, you will fail to push refs to dest repo
|
||||
- name: Automatic Rebase
|
||||
uses: cirrus-actions/rebase@1.7
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,63 +0,0 @@
|
||||
name: Label closed PR as merged and leave a comment
|
||||
on:
|
||||
push
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
pull-requests: write
|
||||
|
||||
jobs:
|
||||
comment-and-label:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
steps:
|
||||
- uses: actions/github-script@v6
|
||||
with:
|
||||
github-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
script: |
|
||||
if(!context.payload.commits || !context.payload.commits.length) return;
|
||||
const sha = context.payload.commits[0].id;
|
||||
|
||||
const {commit, author} = (await github.rest.repos.getCommit({
|
||||
ref: sha,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
})).data;
|
||||
|
||||
// Looking at the commit message, checks which PR number, if any, was closed by this commit
|
||||
const getClosedPrIfExists = (commit) => {
|
||||
if(!commit || !commit.message) return;
|
||||
const prClosingRegex = /Closes https:\/\/github.com\/facebook\/react-native\/pull\/([0-9]+)|Pull Request resolved: https:\/\/github.com\/facebook\/react-native\/pull\/([0-9]+)/;
|
||||
const prClosingMatch = commit.message.match(prClosingRegex);
|
||||
if(!prClosingMatch || (!prClosingMatch[1] && ! prClosingMatch[2])) return;
|
||||
return prClosingMatch[1] ?? prClosingMatch[2];
|
||||
};
|
||||
|
||||
const closedPrNumber = getClosedPrIfExists(commit);
|
||||
if(!closedPrNumber) return;
|
||||
|
||||
const pr = (await github.rest.pulls.get({
|
||||
pull_number: closedPrNumber,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
})).data;
|
||||
|
||||
// If the PR has already been processed (labeled as Merged), skip it
|
||||
const mergedLabel = "Merged";
|
||||
if(pr.labels && pr.labels.some(label => label.name === mergedLabel)) return;
|
||||
|
||||
const authorName = author?.login ? `@${author.login}` : commit.author.name;
|
||||
|
||||
github.rest.issues.createComment({
|
||||
issue_number: closedPrNumber,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
body: `This pull request was successfully merged by ${authorName} in **${sha}**.\n\n<sup>[When will my fix make it into a release?](https://github.com/facebook/react-native/wiki/Release-FAQ#when-will-my-fix-make-it-into-a-release) | [Upcoming Releases](https://github.com/reactwg/react-native-releases/discussions/categories/releases)</sup>`
|
||||
});
|
||||
|
||||
github.rest.issues.addLabels({
|
||||
issue_number: closedPrNumber,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: [mergedLabel]
|
||||
});
|
||||
@@ -1,28 +0,0 @@
|
||||
name: Run Danger on PR
|
||||
|
||||
on:
|
||||
pull_request_target:
|
||||
types: [opened, edited, reopened, synchronize]
|
||||
|
||||
permissions:
|
||||
actions: write
|
||||
checks: write
|
||||
contents: write
|
||||
issues: write
|
||||
pull-requests: write
|
||||
statuses: write
|
||||
|
||||
jobs:
|
||||
danger:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Run Yarn Install on Root
|
||||
run: yarn install
|
||||
working-directory: .
|
||||
- name: Danger
|
||||
run: yarn danger ci --use-github-checks --failOnErrors
|
||||
working-directory: packages/react-native-bots
|
||||
env:
|
||||
DANGER_GITHUB_API_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -1,28 +0,0 @@
|
||||
name: Issue Needs Attention
|
||||
# This workflow is triggered on issue comments.
|
||||
on:
|
||||
issue_comment:
|
||||
types: created
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
applyNeedsAttentionLabel:
|
||||
permissions:
|
||||
contents: read # for actions/checkout to fetch code
|
||||
issues: write # for hramos/needs-attention to label issues
|
||||
name: Apply Needs Attention Label
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Apply Needs Attention Label
|
||||
uses: hramos/needs-attention@v1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
response-required-label: "Needs: Author Feedback"
|
||||
needs-attention-label: "Needs: Attention"
|
||||
id: needs-attention
|
||||
- name: Result
|
||||
run: echo '${{ steps.needs-attention.outputs.result }}'
|
||||
@@ -1,46 +0,0 @@
|
||||
name: On Issue Labeled
|
||||
# This workflow is triggered when a label is added to an issue.
|
||||
on:
|
||||
issues:
|
||||
types: labeled
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
issues: write
|
||||
|
||||
jobs:
|
||||
# Runs automatic checks on issues labeled with "Needs: Triage",
|
||||
# then invokes actOnLabel to react to any added labels
|
||||
triage-issue:
|
||||
runs-on: ubuntu-latest
|
||||
if: "${{ github.repository == 'facebook/react-native' && contains(github.event.label.name, 'Needs: Triage :mag:') }}"
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
const verifyVersion = require('./.github/workflows/verifyVersion.js')
|
||||
const labelToAdd = await verifyVersion(github, context);
|
||||
|
||||
if(labelToAdd) {
|
||||
await github.rest.issues.addLabels({
|
||||
issue_number: context.issue.number,
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
labels: [labelToAdd]
|
||||
})
|
||||
|
||||
const actOnLabel = require('./.github/workflows/actOnLabel.js')
|
||||
await actOnLabel(github, context, labelToAdd)
|
||||
}
|
||||
# Reacts to the label that triggered this workflow (added manually or via other workflows)
|
||||
act-on-label:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: actions/github-script@v6
|
||||
with:
|
||||
script: |
|
||||
const actOnLabel = require('./.github/workflows/actOnLabel.js')
|
||||
await actOnLabel(github, context, context.payload.label.name)
|
||||
@@ -1,77 +0,0 @@
|
||||
name: Mark stale issues and pull requests
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 0,6,12,18 * * *"
|
||||
jobs:
|
||||
stale:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v5
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 180
|
||||
stale-issue-message: 'This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.'
|
||||
stale-pr-message: 'This PR is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.'
|
||||
close-issue-message: 'This issue was closed because it has been stalled for 7 days with no activity.'
|
||||
close-pr-message: 'This PR was closed because it has been stalled for 7 days with no activity.'
|
||||
exempt-issue-labels: Help Wanted :octocat:, Good first issue, Never gets stale
|
||||
exempt-pr-labels: Help Wanted :octocat:, Good first issue, Never gets stale
|
||||
stale-asc:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v5
|
||||
with:
|
||||
ascending: true
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
days-before-stale: 180
|
||||
stale-issue-message: 'This issue is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.'
|
||||
stale-pr-message: 'This PR is stale because it has been open 180 days with no activity. Remove stale label or comment or this will be closed in 7 days.'
|
||||
close-issue-message: 'This issue was closed because it has been stalled for 7 days with no activity.'
|
||||
close-pr-message: 'This PR was closed because it has been stalled for 7 days with no activity.'
|
||||
exempt-issue-labels: Help Wanted :octocat:, Good first issue, Never gets stale
|
||||
exempt-pr-labels: Help Wanted :octocat:, Good first issue, Never gets stale
|
||||
stale-needs-author-feedback:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v5
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
any-of-labels: 'Needs: Author Feedback'
|
||||
days-before-stale: 24
|
||||
stale-issue-message: "This issue is waiting for author's feedback since 24 days. Please provide the requested feedback or this will be closed in 7 days."
|
||||
stale-pr-message: "This PR is waiting for author's feedback since 24 days. Please provide the requested feedback or this will be closed in 7 days"
|
||||
close-issue-message: "This issue was closed because the author hasn't provided the requested feedback after 7 days."
|
||||
close-pr-message: "This PR was closed because the author hasn't provided the requested feedback after 7 days."
|
||||
exempt-issue-labels: Help Wanted :octocat:, Good first issue, Never gets stale
|
||||
exempt-pr-labels: Help Wanted :octocat:, Good first issue, Never gets stale
|
||||
stale-needs-author-feedback-asc:
|
||||
runs-on: ubuntu-latest
|
||||
if: github.repository == 'facebook/react-native'
|
||||
permissions:
|
||||
issues: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- uses: actions/stale@v5
|
||||
with:
|
||||
ascending: true
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
any-of-labels: 'Needs: Author Feedback'
|
||||
days-before-stale: 24
|
||||
stale-issue-message: "This issue is waiting for author's feedback since 24 days. Please provide the requested feedback or this will be closed in 7 days."
|
||||
stale-pr-message: "This PR is waiting for author's feedback since 24 days. Please provide the requested feedback or this will be closed in 7 days"
|
||||
close-issue-message: "This issue was closed because the author hasn't provided the requested feedback after 7 days."
|
||||
close-pr-message: "This PR was closed because the author hasn't provided the requested feedback after 7 days."
|
||||
exempt-issue-labels: Help Wanted :octocat:, Good first issue, Never gets stale
|
||||
exempt-pr-labels: Help Wanted :octocat:, Good first issue, Never gets stale
|
||||
@@ -1,117 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
module.exports = async (github, context) => {
|
||||
const issue = context.payload.issue;
|
||||
|
||||
// Ignore issues using upgrade template (they use a special label)
|
||||
if (issue.labels.find(label => label.name == 'Type: Upgrade Issue')) {
|
||||
return;
|
||||
}
|
||||
|
||||
const issueVersionUnparsed =
|
||||
getReactNativeVersionFromIssueBodyIfExists(issue);
|
||||
const issueVersion = parseVersionFromString(issueVersionUnparsed);
|
||||
|
||||
// Nightly versions are always supported
|
||||
if (reportedVersionIsNightly(issueVersionUnparsed, issueVersion)) return;
|
||||
|
||||
if (!issueVersion) {
|
||||
return 'Needs: Version Info';
|
||||
}
|
||||
|
||||
// Ensure the version matches one we support
|
||||
const recentReleases = (
|
||||
await github.rest.repos.listReleases({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
})
|
||||
).data.map(release => release.name);
|
||||
|
||||
const latestRelease = (
|
||||
await github.rest.repos.getLatestRelease({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
})
|
||||
).data;
|
||||
const latestVersion = parseVersionFromString(latestRelease.name);
|
||||
|
||||
if (!isVersionSupported(issueVersion, latestVersion)) {
|
||||
return 'Type: Unsupported Version';
|
||||
}
|
||||
|
||||
// We want to encourage users to repro the issue on the highest available patch for the given minor.
|
||||
const latestPatchForVersion = getLatestPatchForVersion(
|
||||
issueVersion,
|
||||
recentReleases,
|
||||
);
|
||||
if (latestPatchForVersion > issueVersion.patch) {
|
||||
return 'Needs: Verify on Latest Version';
|
||||
}
|
||||
};
|
||||
|
||||
// We support N-2 minor versions, and the latest major.
|
||||
function isVersionSupported(actualVersion, latestVersion) {
|
||||
return (
|
||||
actualVersion.major >= latestVersion.major &&
|
||||
actualVersion.minor >= latestVersion.minor - 2
|
||||
);
|
||||
}
|
||||
|
||||
// Assumes that releases are sorted in the order of recency (i.e. most recent releases are earlier in the list)
|
||||
// This enables us to stop looking as soon as we find the first release with a matching major/minor version, since
|
||||
// we know it's the most recent release, therefore the highest patch available.
|
||||
function getLatestPatchForVersion(version, releases) {
|
||||
for (releaseName of releases) {
|
||||
const release = parseVersionFromString(releaseName);
|
||||
if (
|
||||
release &&
|
||||
release.major == version.major &&
|
||||
release.minor == version.minor
|
||||
) {
|
||||
return release.patch;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getReactNativeVersionFromIssueBodyIfExists(issue) {
|
||||
if (!issue || !issue.body) return;
|
||||
const rnVersionRegex = /React Native Version[\r\n]+(?<version>.+)[\r\n]*/;
|
||||
const rnVersionMatch = issue.body.match(rnVersionRegex);
|
||||
if (!rnVersionMatch || !rnVersionMatch.groups.version) return;
|
||||
return rnVersionMatch.groups.version;
|
||||
}
|
||||
|
||||
function reportedVersionIsNightly(unparsedVersionString, version) {
|
||||
if (!unparsedVersionString && !version) return false;
|
||||
const nightlyRegex = /nightly/i;
|
||||
const nightlyMatch = unparsedVersionString.match(nightlyRegex);
|
||||
const versionIsNightly = nightlyMatch && nightlyMatch[0];
|
||||
|
||||
const versionIsZero =
|
||||
version && version.major == 0 && version.minor == 0 && version.patch == 0;
|
||||
|
||||
return versionIsZero || versionIsNightly;
|
||||
}
|
||||
|
||||
function parseVersionFromString(version) {
|
||||
if (!version) return;
|
||||
// This will match the standard x.x.x semver format, as well as the non-standard prerelease x.x.x-rc.x
|
||||
const semverRegex =
|
||||
/(?<major>\d+)\.(?<minor>\d+)\.(?<patch>\d+)(-[rR]{1}[cC]{1}\.(?<prerelease>\d+))?/;
|
||||
const versionMatch = version.match(semverRegex);
|
||||
if (!versionMatch) return;
|
||||
const {major, minor, patch, prerelease} = versionMatch.groups;
|
||||
return {
|
||||
major: parseInt(major),
|
||||
minor: parseInt(minor),
|
||||
patch: parseInt(patch),
|
||||
prerelease: parseInt(prerelease),
|
||||
};
|
||||
}
|
||||
+13
-88
@@ -20,41 +20,21 @@ DerivedData
|
||||
*.ipa
|
||||
*.xcuserstate
|
||||
project.xcworkspace
|
||||
**/.xcode.env.local
|
||||
|
||||
# Gradle
|
||||
/build/
|
||||
/packages/react-native-gradle-plugin/build/
|
||||
/packages/rn-tester/build
|
||||
/packages/rn-tester/android/app/.cxx/
|
||||
/packages/rn-tester/android/app/build/
|
||||
/packages/rn-tester/android/app/gradle/
|
||||
/packages/rn-tester/android/app/gradlew
|
||||
/packages/rn-tester/android/app/gradlew.bat
|
||||
/packages/react-native/ReactAndroid/build/
|
||||
/packages/react-native/ReactAndroid/.cxx/
|
||||
/packages/react-native/ReactAndroid/gradle/
|
||||
/packages/react-native/ReactAndroid/gradlew
|
||||
/packages/react-native/ReactAndroid/gradlew.bat
|
||||
/packages/react-native/ReactAndroid/external-artifacts/build/
|
||||
/packages/react-native/ReactAndroid/external-artifacts/artifacts/
|
||||
/packages/react-native/ReactAndroid/hermes-engine/build/
|
||||
/packages/react-native/ReactAndroid/hermes-engine/.cxx/
|
||||
/packages/react-native/template/android/app/build/
|
||||
/packages/react-native/template/android/build/
|
||||
/RNTester/android/app/build/
|
||||
/RNTester/android/app/gradle/
|
||||
/RNTester/android/app/gradlew
|
||||
/RNTester/android/app/gradlew.bat
|
||||
/ReactAndroid/build/
|
||||
|
||||
# Buck
|
||||
.buckd
|
||||
buck-out
|
||||
/.lsp.buckd
|
||||
/.lsp-buck-out
|
||||
/packages/react-native/ReactAndroid/src/main/jni/prebuilt/lib/
|
||||
/packages/react-native/ReactAndroid/src/main/gen
|
||||
|
||||
# Android Studio
|
||||
.project
|
||||
.settings
|
||||
.classpath
|
||||
/ReactAndroid/src/main/jni/prebuilt/lib/armeabi-v7a/
|
||||
/ReactAndroid/src/main/jni/prebuilt/lib/x86/
|
||||
/ReactAndroid/src/main/gen
|
||||
|
||||
# Watchman
|
||||
.watchmanconfig
|
||||
@@ -64,83 +44,28 @@ buck-out
|
||||
.gradle
|
||||
local.properties
|
||||
*.iml
|
||||
/packages/react-native/android/*
|
||||
!/packages/react-native/android/README.md
|
||||
/android/
|
||||
|
||||
# Node
|
||||
node_modules
|
||||
*.log
|
||||
.nvm
|
||||
/bots/node_modules/
|
||||
package-lock.json
|
||||
|
||||
# OS X
|
||||
.DS_Store
|
||||
|
||||
# Test generated files
|
||||
/packages/react-native/ReactAndroid/src/androidTest/assets/AndroidTestBundle.js
|
||||
/ReactAndroid/src/androidTest/assets/AndroidTestBundle.js
|
||||
*.js.meta
|
||||
|
||||
/coverage
|
||||
/third-party
|
||||
|
||||
# Test Reports
|
||||
/reports
|
||||
|
||||
# Stack Dumps generated when programs crash (Ex. bash.exe.stackdump on Win)
|
||||
*.stackdump
|
||||
|
||||
# Root dir shouldn't have Xcode project
|
||||
/*.xcodeproj
|
||||
|
||||
# ReactCommon subdir shouldn't have Xcode project
|
||||
/packages/react-native/ReactCommon/**/*.xcodeproj
|
||||
|
||||
# Libs that shouldn't have Xcode project
|
||||
/packages/react-native/Libraries/FBLazyVector/**/*.xcodeproj
|
||||
/packages/react-native/Libraries/RCTRequired/**/*.xcodeproj
|
||||
/packages/react-native/React/CoreModules/**/*.xcodeproj
|
||||
/packages/react-native/React/FBReactNativeSpec/**/*.xcodeproj
|
||||
/packages/react-native-codegen/**/*.xcodeproj
|
||||
|
||||
# Ruby Gems (Bundler)
|
||||
/packages/react-native/vendor
|
||||
/packages/react-native/template/vendor
|
||||
.ruby-version
|
||||
/**/.ruby-version
|
||||
./vendor/
|
||||
vendor/
|
||||
|
||||
# iOS / CocoaPods
|
||||
/packages/react-native/template/ios/build/
|
||||
/packages/react-native/template/ios/Pods/
|
||||
/packages/react-native/template/ios/Podfile.lock
|
||||
/packages/rn-tester/Gemfile.lock
|
||||
|
||||
# Ignore RNTester specific Pods, but keep the __offline_mirrors__ here.
|
||||
/packages/rn-tester/Pods/*
|
||||
!/packages/rn-tester/Pods/__offline_mirrors_hermes__
|
||||
!/packages/rn-tester/Pods/__offline_mirrors_jsc__
|
||||
|
||||
# @react-native/codegen
|
||||
/packages/react-native/React/FBReactNativeSpec/FBReactNativeSpec
|
||||
/packages/react-native-codegen/lib
|
||||
/packages/react-native-codegen/tmp/
|
||||
/packages/react-native/ReactCommon/react/renderer/components/rncore/
|
||||
/packages/rn-tester/NativeModuleExample/ScreenshotManagerSpec*
|
||||
/**/RCTThirdPartyFabricComponentsProvider.*
|
||||
|
||||
|
||||
# Additional SDKs
|
||||
/packages/react-native/sdks/download
|
||||
/packages/react-native/sdks/hermes
|
||||
/packages/react-native/sdks/hermesc
|
||||
|
||||
# Visual studio
|
||||
.vscode
|
||||
.vs
|
||||
|
||||
# Android memory profiler files
|
||||
*.hprof
|
||||
|
||||
# Temporary files created by Metro to check the health of the file watcher
|
||||
.metro-health-check*
|
||||
/ReactCommon/**/*.xcodeproj
|
||||
RNTester/build
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
# rnpm
|
||||
/local-cli/rnpm
|
||||
/local-cli/server/middleware/heapCapture/bundle.js
|
||||
@@ -1,8 +0,0 @@
|
||||
{
|
||||
"arrowParens": "avoid",
|
||||
"bracketSameLine": true,
|
||||
"bracketSpacing": false,
|
||||
"requirePragma": true,
|
||||
"singleQuote": true,
|
||||
"trailingComma": "all"
|
||||
}
|
||||
-5537
File diff suppressed because it is too large
Load Diff
+3
-75
@@ -1,77 +1,5 @@
|
||||
# Code of Conduct
|
||||
|
||||
## Our Pledge
|
||||
|
||||
In the interest of fostering an open and welcoming environment, we as
|
||||
contributors and maintainers pledge to make participation in our project and
|
||||
our community a harassment-free experience for everyone, regardless of age, body
|
||||
size, disability, ethnicity, sex characteristics, gender identity and expression,
|
||||
level of experience, education, socio-economic status, nationality, personal
|
||||
appearance, race, religion, or sexual identity and orientation.
|
||||
|
||||
## Our Standards
|
||||
|
||||
Examples of behavior that contributes to creating a positive environment
|
||||
include:
|
||||
|
||||
* Using welcoming and inclusive language
|
||||
* Being respectful of differing viewpoints and experiences
|
||||
* Gracefully accepting constructive criticism
|
||||
* Focusing on what is best for the community
|
||||
* Showing empathy towards other community members
|
||||
|
||||
Examples of unacceptable behavior by participants include:
|
||||
|
||||
* The use of sexualized language or imagery and unwelcome sexual attention or
|
||||
advances
|
||||
* Trolling, insulting/derogatory comments, and personal or political attacks
|
||||
* Public or private harassment
|
||||
* Publishing others' private information, such as a physical or electronic
|
||||
address, without explicit permission
|
||||
* Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
|
||||
## Our Responsibilities
|
||||
|
||||
Project maintainers are responsible for clarifying the standards of acceptable
|
||||
behavior and are expected to take appropriate and fair corrective action in
|
||||
response to any instances of unacceptable behavior.
|
||||
|
||||
Project maintainers have the right and responsibility to remove, edit, or
|
||||
reject comments, commits, code, wiki edits, issues, and other contributions
|
||||
that are not aligned to this Code of Conduct, or to ban temporarily or
|
||||
permanently any contributor for other behaviors that they deem inappropriate,
|
||||
threatening, offensive, or harmful.
|
||||
|
||||
## Scope
|
||||
|
||||
This Code of Conduct applies within all project spaces, and it also applies when
|
||||
an individual is representing the project or its community in public spaces.
|
||||
Examples of representing a project or community include using an official
|
||||
project e-mail address, posting via an official social media account, or acting
|
||||
as an appointed representative at an online or offline event. Representation of
|
||||
a project may be further defined and clarified by project maintainers.
|
||||
|
||||
## Enforcement
|
||||
|
||||
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
||||
reported by contacting the project team at <opensource-conduct@fb.com>. All
|
||||
complaints will be reviewed and investigated and will result in a response that
|
||||
is deemed necessary and appropriate to the circumstances. The project team is
|
||||
obligated to maintain confidentiality with regard to the reporter of an incident.
|
||||
Further details of specific enforcement policies may be posted separately.
|
||||
|
||||
Project maintainers who do not follow or enforce the Code of Conduct in good
|
||||
faith may face temporary or permanent repercussions as determined by other
|
||||
members of the project's leadership.
|
||||
|
||||
## Attribution
|
||||
|
||||
This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 2.1,
|
||||
available at https://www.contributor-covenant.org/version/2/1/code_of_conduct/
|
||||
|
||||
[homepage]: https://www.contributor-covenant.org
|
||||
|
||||
For answers to common questions about this code of conduct, see
|
||||
https://www.contributor-covenant.org/faq
|
||||
|
||||
Facebook has adopted a Code of Conduct that we expect project participants to adhere to.
|
||||
Please read the [full text](https://code.fb.com/codeofconduct/)
|
||||
so that you can understand what actions will and will not be tolerated.
|
||||
|
||||
+52
-4
@@ -1,7 +1,55 @@
|
||||
# Contributing to React Native
|
||||
|
||||
Thank you for your interest in contributing to React Native! From commenting on and triaging issues, to reviewing and sending Pull Requests, all contributions are welcome.
|
||||
We aim to build a vibrant and inclusive [ecosystem of partners, core contributors, and community](ECOSYSTEM.md) that goes beyond the main React Native GitHub repository.
|
||||
We want to make contributing to this project as easy and transparent as possible. Read on to learn more about our development process and how to propose bug fixes and improvements. The [How to Contribute](https://facebook.github.io/react-native/docs/contributing.html) guide on the website goes into more detail for each of these areas.
|
||||
|
||||
To learn more about how to contribute check out the Contributing section on the React Native website:
|
||||
* https://reactnative.dev/contributing/overview
|
||||
## Our Development Process
|
||||
|
||||
Most changes from engineers at Facebook will sync to [GitHub](https://github.com/facebook/react-native) through a bridge with Facebook's internal source control. Changes from the community are handled through GitHub pull requests. Once a change made on GitHub is approved, it will first be imported into Facebook's internal source control. The change will eventually sync back to GitHub as a single commit once it has passed Facebook's internal tests.
|
||||
|
||||
## Pull Requests
|
||||
|
||||
Please make sure the following is done when submitting a pull request:
|
||||
|
||||
1. Fork the repo and create your branch from `master`.
|
||||
2. If you've added code that should be tested, add tests.
|
||||
3. If you've changed APIs, update the documentation.
|
||||
4. Ensure the test suite passes.
|
||||
5. Make sure your code lints.
|
||||
6. If you haven't already, complete the Contributor License Agreement ("CLA").
|
||||
|
||||
## Contributor License Agreement ("CLA")
|
||||
|
||||
In order to accept your pull request, we need you to submit a CLA. You only need to do this once to work on any of Facebook's open source projects.
|
||||
|
||||
Complete your CLA here: <https://code.facebook.com/cla>
|
||||
|
||||
## Issues
|
||||
|
||||
We use GitHub issues to track public bugs. Please ensure your description is clear and has sufficient instructions to be able to reproduce the issue.
|
||||
|
||||
Facebook has a [bounty program](https://www.facebook.com/whitehat/) for the safe disclosure of security bugs. In those cases, please go through the process outlined on that page and do not file a public issue.
|
||||
|
||||
## Coding Style
|
||||
|
||||
We use Prettier to format our JavaScript code. This saves you time and energy as you can let Prettier fix up any formatting issues automatically through its editor integrations, or by manually running `npm run prettier`. We also use a linter to catch styling issues that may exist in your code. You can check the status of your code styling by simply running `npm run lint`.
|
||||
|
||||
However, there are still some styles that the linter cannot pick up, notably in Java or Objective-C code.
|
||||
|
||||
**Objective-C:**
|
||||
|
||||
* Space after `@property` declarations
|
||||
* Brackets on *every* `if`, on the *same* line
|
||||
* `- method`, `@interface`, and `@implementation` brackets on the following line
|
||||
* *Try* to keep it around 80 characters line length (sometimes it's just not possible...)
|
||||
* `*` operator goes with the variable name (e.g. `NSObject *variableName;`)
|
||||
|
||||
**Java:**
|
||||
|
||||
* If a method call spans multiple lines closing bracket is on the same line as the last argument.
|
||||
* If a method header doesn't fit on one line each argument goes on a separate line.
|
||||
* 100 character line length
|
||||
|
||||
## License
|
||||
|
||||
By contributing to React Native, you agree that your contributions will be licensed
|
||||
under the LICENSE file in the root directory of this source tree.
|
||||
|
||||
@@ -0,0 +1,67 @@
|
||||
# Copyright (c) Facebook, Inc. and its affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
# React Native Android Unit Tests
|
||||
#
|
||||
# This image builds upon the React Native Base Android Development Environment
|
||||
# image. Ideally, this image would be rebuilt with any new commit to the master
|
||||
# branch. Doing so will catch issues such as BUCK failing to fetch dependencies
|
||||
# or run tests, as well as unit test failures.
|
||||
FROM reactnativeci/android-base:latest
|
||||
|
||||
LABEL Description="This image prepares and runs React Native's Android tests."
|
||||
LABEL maintainer="Héctor Ramos <hector@fb.com>"
|
||||
|
||||
# set default environment variables
|
||||
ENV GRADLE_OPTS="-Dorg.gradle.daemon=false -Dorg.gradle.jvmargs=\"-Xmx512m -XX:+HeapDumpOnOutOfMemoryError\""
|
||||
ENV JAVA_TOOL_OPTIONS="-Dfile.encoding=UTF8"
|
||||
|
||||
# add ReactAndroid directory
|
||||
ADD .buckconfig /app/.buckconfig
|
||||
ADD .buckjavaargs /app/.buckjavaargs
|
||||
ADD ReactAndroid /app/ReactAndroid
|
||||
ADD ReactCommon /app/ReactCommon
|
||||
ADD ReactNative /app/ReactNative
|
||||
ADD keystores /app/keystores
|
||||
|
||||
# set workdir
|
||||
WORKDIR /app
|
||||
|
||||
# run buck fetches
|
||||
RUN buck fetch ReactAndroid/src/test/java/com/facebook/react/modules
|
||||
RUN buck fetch ReactAndroid/src/main/java/com/facebook/react
|
||||
RUN buck fetch ReactAndroid/src/main/java/com/facebook/react/shell
|
||||
RUN buck fetch ReactAndroid/src/test/...
|
||||
RUN buck fetch ReactAndroid/src/androidTest/...
|
||||
|
||||
# build app
|
||||
RUN buck build ReactAndroid/src/main/java/com/facebook/react
|
||||
RUN buck build ReactAndroid/src/main/java/com/facebook/react/shell
|
||||
|
||||
ADD gradle /app/gradle
|
||||
ADD gradlew /app/gradlew
|
||||
ADD settings.gradle /app/settings.gradle
|
||||
ADD build.gradle /app/build.gradle
|
||||
ADD react.gradle /app/react.gradle
|
||||
|
||||
# run gradle downloads
|
||||
RUN ./gradlew :ReactAndroid:downloadBoost :ReactAndroid:downloadDoubleConversion :ReactAndroid:downloadFolly :ReactAndroid:downloadGlog :ReactAndroid:downloadJSCHeaders
|
||||
|
||||
# compile native libs with Gradle script, we need bridge for unit and integration tests
|
||||
RUN ./gradlew :ReactAndroid:packageReactNdkLibsForBuck -Pjobs=1
|
||||
|
||||
# add all react-native code
|
||||
ADD . /app
|
||||
WORKDIR /app
|
||||
|
||||
# build node dependencies
|
||||
RUN curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | apt-key add -
|
||||
RUN echo "deb https://dl.yarnpkg.com/debian/ stable main" | tee /etc/apt/sources.list.d/yarn.list
|
||||
RUN apt-get install apt-transport-https
|
||||
RUN apt-get update
|
||||
RUN apt-get install yarn
|
||||
RUN yarn
|
||||
|
||||
WORKDIR /app
|
||||
@@ -0,0 +1,83 @@
|
||||
# Copyright (c) Facebook, Inc. and its affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
# React Native Base Android Development Environment
|
||||
#
|
||||
# This image provides a base Android development environment for React Native,
|
||||
# including, but not limited to, the Android SDK, Android NDK, Node, and BUCK.
|
||||
# These are required in order to run React Native's Android unit and integration
|
||||
# tests.
|
||||
#
|
||||
# This image is not currently built automatically as part of React Native's CI
|
||||
# infrastructure. It should not be necessary to rebuild this image while the
|
||||
# Android dependencies (Android SDK version, build tools version, etc) remain
|
||||
# equal. The operations performed to build this image are those that tend to
|
||||
# remain stable across commits in any given React Native release.
|
||||
|
||||
FROM library/ubuntu:16.04
|
||||
|
||||
LABEL Description="This image provides a base Android development environment for React Native, and may be used to run tests."
|
||||
LABEL maintainer="Héctor Ramos <hector@fb.com>"
|
||||
|
||||
# set default build arguments
|
||||
ARG SDK_VERSION=sdk-tools-linux-3859397.zip
|
||||
ARG ANDROID_BUILD_VERSION=28
|
||||
ARG ANDROID_TOOLS_VERSION=28.0.3
|
||||
ARG BUCK_VERSION=v2018.10.29.01
|
||||
ARG NDK_VERSION=17c
|
||||
ARG NODE_VERSION=8.10.0
|
||||
ARG WATCHMAN_VERSION=4.9.0
|
||||
|
||||
# set default environment variables
|
||||
ENV ADB_INSTALL_TIMEOUT=10
|
||||
ENV PATH=${PATH}:/opt/buck/bin/
|
||||
ENV ANDROID_HOME=/opt/android
|
||||
ENV ANDROID_SDK_HOME=${ANDROID_HOME}
|
||||
ENV PATH=${PATH}:${ANDROID_HOME}/tools:${ANDROID_HOME}/tools/bin:${ANDROID_HOME}/platform-tools
|
||||
ENV ANDROID_NDK=/opt/ndk/android-ndk-r$NDK_VERSION
|
||||
ENV PATH=${PATH}:${ANDROID_NDK}
|
||||
|
||||
# install system dependencies
|
||||
RUN apt-get update && apt-get install ant autoconf automake curl g++ gcc git libqt5widgets5 lib32z1 lib32stdc++6 make maven npm openjdk-8* python-dev python3-dev qml-module-qtquick-controls qtdeclarative5-dev unzip -y
|
||||
|
||||
# configure npm
|
||||
RUN npm config set spin=false && \
|
||||
npm config set progress=false
|
||||
|
||||
# install node
|
||||
RUN npm install n -g
|
||||
RUN n $NODE_VERSION
|
||||
|
||||
# download buck
|
||||
RUN git clone https://github.com/facebook/buck.git /opt/buck --branch $BUCK_VERSION --depth=1
|
||||
WORKDIR /opt/buck
|
||||
|
||||
# build buck
|
||||
RUN ant
|
||||
|
||||
# Full reference at https://dl.google.com/android/repository/repository2-1.xml
|
||||
# download and unpack android
|
||||
RUN mkdir /opt/android && \
|
||||
cd /opt/android && \
|
||||
curl --silent https://dl.google.com/android/repository/${SDK_VERSION} > android.zip && \
|
||||
unzip android.zip && \
|
||||
rm android.zip
|
||||
|
||||
# download and unpack NDK
|
||||
RUN mkdir /opt/ndk && \
|
||||
cd /opt/ndk && \
|
||||
curl --silent https://dl.google.com/android/repository/android-ndk-r$NDK_VERSION-linux-x86_64.zip > ndk.zip && \
|
||||
unzip ndk.zip && \
|
||||
rm ndk.zip
|
||||
|
||||
# Add android SDK tools
|
||||
RUN sdkmanager "system-images;android-19;google_apis;armeabi-v7a" \
|
||||
"platforms;android-$ANDROID_BUILD_VERSION" \
|
||||
"build-tools;$ANDROID_TOOLS_VERSION" \
|
||||
"add-ons;addon-google_apis-google-23" \
|
||||
"extras;android;m2repository"
|
||||
|
||||
# clean up unnecessary directories
|
||||
RUN rm -rf /opt/android/system-images/android-19/default/x86
|
||||
@@ -0,0 +1,24 @@
|
||||
# Copyright (c) Facebook, Inc. and its affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
FROM library/node:6.9.2
|
||||
|
||||
ENV YARN_VERSION=0.27.5
|
||||
|
||||
# install dependencies
|
||||
RUN apt-get update && apt-get install ocaml libelf-dev -y
|
||||
RUN npm install yarn@$YARN_VERSION -g
|
||||
|
||||
# add code
|
||||
RUN mkdir /app
|
||||
ADD . /app
|
||||
|
||||
WORKDIR /app
|
||||
RUN yarn install --ignore-engines
|
||||
|
||||
WORKDIR website
|
||||
RUN yarn install --ignore-engines --ignore-platform
|
||||
|
||||
WORKDIR /app
|
||||
+3
-3
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -80,13 +80,13 @@ if (test_opts.COUNT != null && test_opts.OFFSET != null) {
|
||||
}
|
||||
}
|
||||
|
||||
async.mapSeries(testClasses, (clazz, callback) => {
|
||||
return async.mapSeries(testClasses, (clazz, callback) => {
|
||||
if (clazz.length > max_test_class_length) {
|
||||
max_test_class_length = clazz.length;
|
||||
}
|
||||
|
||||
return async.retry(test_opts.RETRIES, (retryCb) => {
|
||||
const test_process = child_process.spawn('./.circleci/Dockerfiles/scripts/run-instrumentation-tests-via-adb-shell.sh', [test_opts.PACKAGE, clazz], {
|
||||
const test_process = child_process.spawn('./ContainerShip/scripts/run-instrumentation-tests-via-adb-shell.sh', [test_opts.PACKAGE, clazz], {
|
||||
stdio: 'inherit',
|
||||
});
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (c) Facebook, Inc. and its affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
#
|
||||
|
||||
# for buck gen
|
||||
mount -o remount,exec /dev/shm
|
||||
|
||||
AVD_UUID=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1)
|
||||
|
||||
# create virtual device
|
||||
echo no | android create avd -n "$AVD_UUID" -f -t android-19 --abi default/armeabi-v7a
|
||||
|
||||
# emulator setup
|
||||
emulator64-arm -avd $AVD_UUID -no-skin -no-audio -no-window -no-boot-anim &
|
||||
bootanim=""
|
||||
until [[ "$bootanim" =~ "stopped" ]]; do
|
||||
sleep 5
|
||||
bootanim=$(adb -e shell getprop init.svc.bootanim 2>&1)
|
||||
echo "boot animation status=$bootanim"
|
||||
done
|
||||
|
||||
set -x
|
||||
|
||||
# solve issue with max user watches limit
|
||||
echo 65536 | tee -a /proc/sys/fs/inotify/max_user_watches
|
||||
watchman shutdown-server
|
||||
|
||||
# integration tests
|
||||
# build JS bundle for instrumentation tests
|
||||
node local-cli/cli.js bundle --platform android --dev true --entry-file ReactAndroid/src/androidTest/js/TestBundle.js --bundle-output ReactAndroid/src/androidTest/assets/AndroidTestBundle.js
|
||||
|
||||
# build test APK
|
||||
# shellcheck disable=SC1091
|
||||
source ./scripts/android-setup.sh && NO_BUCKD=1 retry3 buck install ReactAndroid/src/androidTest/buck-runner:instrumentation-tests --config build.threads=1
|
||||
|
||||
# run installed apk with tests
|
||||
node ./ContainerShip/scripts/run-android-ci-instrumentation-tests.js "$*"
|
||||
exit $?
|
||||
+3
-1
@@ -1,8 +1,10 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
#
|
||||
# Copyright (c) Facebook, Inc. and its affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
#
|
||||
|
||||
# set default environment variables
|
||||
UNIT_TESTS_BUILD_THREADS="${UNIT_TESTS_BUILD_THREADS:-1}"
|
||||
+29
-6
@@ -1,8 +1,10 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
#
|
||||
# Copyright (c) Facebook, Inc. and its affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
#
|
||||
|
||||
set -ex
|
||||
|
||||
@@ -20,6 +22,8 @@ AVD_UUID=$(< /dev/urandom tr -dc 'a-zA-Z0-9' | fold -w 8 | head -n 1)
|
||||
ANDROID_NPM_DEPS="appium@1.5.1 mocha@2.4.5 wd@0.3.11 colors@1.0.3 pretty-data2@0.40.1"
|
||||
CLI_PACKAGE="$ROOT/react-native-cli/react-native-cli-*.tgz"
|
||||
PACKAGE="$ROOT/react-native-*.tgz"
|
||||
# Version of react-native-dummy to test against
|
||||
REACT_DUMMY_PLATFORM=react-native-dummy@0.1.0
|
||||
|
||||
# solve issue with max user watches limit
|
||||
echo 65536 | tee -a /proc/sys/fs/inotify/max_user_watches
|
||||
@@ -67,6 +71,11 @@ while :; do
|
||||
shift
|
||||
;;
|
||||
|
||||
--tvos)
|
||||
RUN_IOS=1
|
||||
shift
|
||||
;;
|
||||
|
||||
*)
|
||||
break
|
||||
esac
|
||||
@@ -86,8 +95,8 @@ function e2e_suite() {
|
||||
# To make sure we actually installed the local version
|
||||
# of react-native, we will create a temp file inside the template
|
||||
# and check that it exists after `react-native init
|
||||
IOS_MARKER="$(mktemp "$ROOT"/template/ios/HelloWorld/XXXXXXXX)"
|
||||
ANDROID_MARKER="$(mktemp "$ROOT"/template/android/XXXXXXXX)"
|
||||
IOS_MARKER="$(mktemp "$ROOT"/local-cli/templates/HelloWorld/ios/HelloWorld/XXXXXXXX)"
|
||||
ANDROID_MARKER="$(mktemp "$ROOT"/local-cli/templates/HelloWorld/android/XXXXXXXX)"
|
||||
|
||||
# install CLI
|
||||
cd react-native-cli
|
||||
@@ -109,7 +118,7 @@ function e2e_suite() {
|
||||
|
||||
# create virtual device
|
||||
if ! android list avd | grep "$AVD_UUID" > /dev/null; then
|
||||
echo no | android create avd -n "$AVD_UUID" -f -t android-21 --abi default/armeabi-v7a
|
||||
echo no | android create avd -n "$AVD_UUID" -f -t android-19 --abi default/armeabi-v7a
|
||||
fi
|
||||
|
||||
# newline at end of adb devices call and first line is headers
|
||||
@@ -141,7 +150,7 @@ function e2e_suite() {
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! (cd packages/react-native && FILENAME=$(npm pack | tail -1) && mv "$FILENAME" ../../)
|
||||
if ! npm pack
|
||||
then
|
||||
echo "Failed to pack react-native"
|
||||
return 1
|
||||
@@ -194,7 +203,7 @@ function e2e_suite() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "Starting Metro"
|
||||
echo "Starting packager server"
|
||||
npm start >> /dev/null &
|
||||
SERVER_PID=$!
|
||||
sleep 15
|
||||
@@ -241,6 +250,20 @@ function e2e_suite() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! retry "$RETRY_COUNT" npm install --save "$REACT_DUMMY_PLATFORM" --silent >> /dev/null
|
||||
then
|
||||
echo "Failed to install react-native-dummy"
|
||||
echo "Most common reason is npm registry connectivity, try again"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if ! react-native bundle --max-workers 1 --platform dummy --dev true --entry-file index.js --bundle-output dummy-bundle.js
|
||||
then
|
||||
echo "Could not build dummy bundle"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# directory cleanup
|
||||
rm "$IOS_MARKER"
|
||||
rm "$ANDROID_MARKER"
|
||||
+3
-1
@@ -1,8 +1,10 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
#
|
||||
# Copyright (c) Facebook, Inc. and its affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
#
|
||||
|
||||
# shellcheck disable=SC1117
|
||||
# Python script to run instrumentation tests, copied from https://github.com/circleci/circle-dummy-android
|
||||
@@ -0,0 +1,96 @@
|
||||
# Dockerfile Tests
|
||||
|
||||
This is a high level overview of the test configuration using docker. It explains how to run the tests locally
|
||||
and how they integrate with the Jenkins Pipeline script to run the automated tests on ContainerShip <https://www.containership.io/>.
|
||||
|
||||
## Docker Installation
|
||||
|
||||
It is required to have Docker running on your machine in order to build and run the tests in the Dockerfiles.
|
||||
See <https://docs.docker.com/engine/installation/> for more information on how to install.
|
||||
|
||||
## Convenience NPM Run Scripts
|
||||
|
||||
We have added a number of default run scripts to the `package.json` file to simplify building and running your tests.
|
||||
|
||||
`npm run docker-setup-android` - Pulls down the base android docker image used for running the tests
|
||||
|
||||
`npm run docker-build-android` - Builds the docker image used to run the tests
|
||||
|
||||
`npm run test-android-run-unit` - Runs all the unit tests that have been built in the latest react/android docker image (note: you need to run test-android-build before executing this, if the image does not exist it will fail)
|
||||
|
||||
`npm run test-android-run-instrumentation` - Runs all the instrumentation tests that have been built in the latest react/android docker image (note: you need to run test-android-build before executing this, if the image does not exist it will fail). You can also pass additional flags to filter which tests instrumentation tests are run. Ex: `npm run test-android-run-instrumentation -- --filter=TestIdTestCase` to only run the TestIdTestCase instrumentation test. See below for more information
|
||||
on the instrumentation test flags.
|
||||
|
||||
`npm run test-android-run-e2e` - Runs all the end to end tests that have been built in the latest react/android docker image (note: you need to run test-android-build before executing this, if the image does not exist it will fail)
|
||||
|
||||
`npm run test-android-unit` - Builds and runs the android unit tests.
|
||||
|
||||
`npm run test-android-instrumentation` - Builds and runs the android instrumentation tests.
|
||||
|
||||
`npm run test-android-e2e` - Builds and runs the android end to end tests.
|
||||
|
||||
## Detailed Android Setup
|
||||
|
||||
There are two Dockerfiles for use with the Android codebase.
|
||||
|
||||
The `Dockerfile.android-base` contains all the necessary prerequisites required to run the React Android tests. It is
|
||||
separated out into a separate Dockerfile because these are dependencies that rarely change and also because it is quite
|
||||
a beastly image since it contains all the Android dependencies for running android and the emulators (~9GB).
|
||||
|
||||
The good news is you should rarely have to build or pull down the base image! All iterative code updates happen as
|
||||
part of the `Dockerfile.android` image build.
|
||||
|
||||
So step one...
|
||||
|
||||
`docker pull containership/android-base:latest`
|
||||
|
||||
This will take quite some time depending on your connection and you need to ensure you have ~10GB of free disk space.
|
||||
|
||||
Once this is done, you can run tests locally by executing two simple commands:
|
||||
|
||||
1. `docker build -t react/android -f ./ContainerShip/Dockerfile.android .`
|
||||
2. `docker run --cap-add=SYS_ADMIN -it react/android bash ContainerShip/scripts/run-android-docker-unit-tests.sh`
|
||||
|
||||
> Note: `--cap-add=SYS_ADMIN` flag is required for the `ContainerShip/scripts/run-android-docker-unit-tests.sh` and
|
||||
`ContainerShip/scripts/run-android-docker-instrumentation-tests.sh` in order to allow the remounting of `/dev/shm` as writeable
|
||||
so the `buck` build system may write temporary output to that location
|
||||
|
||||
Every time you make any modifications to the codebase, you should re-run the `docker build ...` command in order for your
|
||||
updates to be included in your local docker image.
|
||||
|
||||
The following shell scripts have been provided for android testing:
|
||||
|
||||
`ContainerShip/scripts/run-android-docker-unit-tests.sh` - Runs the standard android unit tests
|
||||
|
||||
`ContainerShip/scripts/run-android-docker-instrumentation-tests.sh` - Runs the android instrumentation tests on the emulator. *Note* that these
|
||||
tests take quite some time to run so there are various flags you can pass in order to filter which tests are run (see below)
|
||||
|
||||
`ContainerShip/scripts/run-ci-e2e-tests.sh` - Runs the android end to end tests
|
||||
|
||||
#### ContainerShip/scripts/run-android-docker-instrumentation-tests.sh
|
||||
|
||||
The instrumentation test script accepts the following flags in order to customize the execution of the tests:
|
||||
|
||||
`--filter` - A regex that filters which instrumentation tests will be run. (Defaults to .*)
|
||||
|
||||
`--package` - Name of the java package containing the instrumentation tests (Defaults to com.facebook.react.tests)
|
||||
|
||||
`--path` - Path to the directory containing the instrumentation tests. (Defaults to ./ReactAndroid/src/androidTest/java/com/facebook/react/tests)
|
||||
|
||||
`--retries` - Number of times to retry a failed test before declaring a failure (Defaults to 2)
|
||||
|
||||
For example, if locally you only wanted to run the InitialPropsTestCase, you could do the following:
|
||||
|
||||
`docker run --cap-add=SYS_ADMIN -it react/android bash ContainerShip/scripts/run-android-docker-instrumentation-tests.sh --filter="InitialPropsTestCase"`
|
||||
|
||||
# Javascript Setup
|
||||
|
||||
There is a single Dockerfile for use with the javascript codebase.
|
||||
|
||||
The `Dockerfile.javascript` base requires all the necessary dependencies for running Javascript tests.
|
||||
|
||||
Any time you make an update to the codebase, you can build and run the javascript tests with the following three commands:
|
||||
|
||||
1. `docker build -t react/js -f ./ContainerShip/Dockerfile.javascript .`
|
||||
2. `docker run -it react/js yarn test --maxWorkers=4`
|
||||
3. `docker run -it react/js yarn run flow -- check`
|
||||
@@ -1,74 +0,0 @@
|
||||
# The React Native Ecosystem
|
||||
|
||||
We aim to build a vibrant and inclusive ecosystem of partners, core contributors, and community that goes beyond the main React Native GitHub repository. This document explains the roles and responsibilities of various stakeholders and provides guidelines for the community organization. The structure outlined in this document has been in place for a while but had not been written down before.
|
||||
|
||||
There are three types of stakeholders:
|
||||
|
||||
* **Partners:** Companies significantly invested in React Native and take responsibility for the React Native vision and community.
|
||||
* **Core Contributors:** Individual people who contribute to the React Native project.
|
||||
* **Community Contributors:** Individuals who support projects in the [react-native-community](https://github.com/react-native-community) organization.
|
||||
|
||||
## Partners
|
||||
|
||||
Partners are companies that are significantly invested in React Native and demonstrate ownership. Informed by their use of React Native, they push for improvements of the core and/or the ecosystem around it. Examples of this may include large scale contributions to `react-native` or owning essential tools or libraries.
|
||||
|
||||
Partners think of React Native as a product; they understand the trade offs that the project makes as well as future plans and goals. Together we shape the vision for React Native to make it the best way to build applications.
|
||||
|
||||
Baseline responsibilities of partners include:
|
||||
* Attending monthly meeting
|
||||
* Contributing to the release process. Examples include being a [community releaser](https://reactnative.dev/contributing/release-roles-responsibilities#release-role-2-community-releaser), testing new releases, technical support for release issues.
|
||||
* Engage on the core contributor Discord
|
||||
|
||||
Our current partners and other areas of ownership:
|
||||
* **[Coinbase](https://www.coinbase.com/):** Publishes [posts](https://blog.coinbase.com/tagged/react-native) advocating React Native usage. Supports `@react-native-community/datetimepicker` and other community modules to migrate to the new architecture. Supports releases in testing and feedback.
|
||||
* **[Callstack](https://callstack.com/):** Maintains the [React Native CLI](https://github.com/react-native-community/react-native-cli) and [other community libraries](https://github.com/callstack), organizes [React Native EU](https://react-native.eu/) and hosts [The React Native Show podcast](https://www.callstack.com/podcast-react-native-show)
|
||||
* **[Expo](https://expo.dev/):** Builds [Expo Go and SDK](https://github.com/expo/expo), [Snack](https://snack.expo.dev/), and [Expo Application Services](https://expo.dev/eas). Maintains [React Native Directory](https://reactnative.directory/), stewards [React Navigation](https://reactnavigation.org/) along with other partners.
|
||||
* **[Infinite Red](https://infinite.red/):** Maintains the [ignite cli/boilerplate](https://github.com/infinitered/ignite), organizes [Chain React Conf](https://cr.infinite.red/), hosts the [React Native Radio podcast](https://reactnativeradio.com), publishes the [React Native Newsletter](https://reactnativenewsletter.com)
|
||||
* **[Meta](https://opensource.fb.com/):** Oversees the React Native product and maintains the [React Native core repo](https://reactnative.dev/)
|
||||
* **[Microsoft](https://twitter.com/ReactNativeMSFT):** Develops [React Native Windows](https://github.com/Microsoft/react-native-windows) and [React Native macOS](https://github.com/microsoft/react-native-macos) for building apps that target Windows and macOS; maintains [rnx-kit](https://github.com/microsoft/rnx-kit), [react-native-test-app](https://github.com/microsoft/react-native-test-app) and coordinates cross-companies efforts such as the [bundle working group](https://github.com/microsoft/rnx-kit/discussions/categories/bundle-working-group).
|
||||
* **[Shopify](https://www.shopify.com/):** Maintains React Native open source libraries such as [flash-list](https://github.com/Shopify/flash-list) or [@shopify/react-native-skia](https://github.com/Shopify/react-native-skia) and sponsors Software Mansion.
|
||||
* **[Software Mansion](https://swmansion.com/):** Maintain core infrastructure including JSC, Animated, and other popular third-party plugins and organizes [App.js Conf](https://appjs.co/)
|
||||
* **[Wix.com](https://wix.engineering/open-source):** Maintains a variety of React Native open source projects ([see all](https://github.com/orgs/wix/repositories?q=react-native)), including: [Detox](https://wix.github.io/Detox/) end-to-end testing library for React Native apps, [RN UILib](https://wix.github.io/react-native-ui-lib/), [RN Navigation](https://wix.github.io/react-native-navigation/), [RN Calendars](https://wix.github.io/react-native-calendars/) and [RN Notifications](https://github.com/wix/react-native-notifications).
|
||||
|
||||
This list may fluctuate in response to newcomers who meet our partner definition. In terms of open source work, pull requests from partners are commonly prioritized. When you are contributing to React Native, you'll most likely meet somebody who works at one of the partner companies and who is a core contributor:
|
||||
|
||||
## Core Contributors
|
||||
|
||||
Core contributors are individuals who contribute to the React Native project. A core contributor is somebody who displayed a lasting commitment to the evolution and maintenance of React Native. The work done by core contributors includes responsibilities mentioned in the “Partners” section above, and concretely means that they:
|
||||
|
||||
* Consistently contribute high quality changes, fixes and improvements
|
||||
* Actively review changes and provide quality feedback to contributors
|
||||
* Manage the release process of React Native by maintaining release branches, communicating changes to users and publishing releases
|
||||
* Love to help out other users with issues on GitHub
|
||||
* Mentor and encourage first time contributors
|
||||
* Identify React Native community members who could be effective core contributors
|
||||
* Help build an inclusive community with people from all backgrounds
|
||||
* Are great at communicating with other contributors and the community in general
|
||||
|
||||
These are behaviors we have observed in our existing core contributors. They aren't strict rules but rather outline their usual responsibilities. We do not expect every core contributor to do all of the above things all the time. Most importantly, we want to create a supportive and friendly environment that fosters collaboration. Above all else, **we are always polite and friendly.**
|
||||
|
||||
Core contributor status is attained after consistently contributing and taking on the responsibilities outlined above and granted by other core contributors. Similarly, after a long period of inactivity (~6 months or more), a core contributor may be contacted to understand if they’re still interested in being part of the program.
|
||||
|
||||
You can use this [form](https://forms.gle/4jpA4QeNUvAUDnNe8) to either:
|
||||
* Apply yourself to become a Core Contributor. Make sure to include a list of valuable contributions you did to the React Native repository and ecosystem.
|
||||
* Nominate someone to become a Core Contributor.
|
||||
|
||||
As a core contributor, you will have access to the core contributor Discord which is used for light-weight coordination and discussion.
|
||||
|
||||
**We aim to make contributing to React Native as easy and transparent as possible.** We have discussion groups dedicated to the [new architecture rollout](https://github.com/reactwg/react-native-new-architecture), [releases](https://github.com/reactwg/react-native-releases), and [general questions and proposals](https://github.com/react-native-community/discussions-and-proposals). We are always looking for active, enthusiastic members of the React Native community to become core contributors.
|
||||
|
||||
## Community Contributors
|
||||
|
||||
Community contributors are individuals who support projects in the [react-native-community](https://github.com/react-native-community) organization. This organization exists as an incubator for high quality components that extend the capabilities of React Native with functionality that many but not all applications require. Meta engineers will provide guidance to help build a vibrant community of people and components that make React Native better.
|
||||
|
||||
This structure has multiple benefits:
|
||||
|
||||
* Keep the core of React Native small, which improves performance and reduces the surface area
|
||||
* Provide visibility to projects through shared representation, for example on the React Native website or on Twitter
|
||||
* Ensure a consistent and high standard for code, documentation, user experience, stability and contributions for third-party components
|
||||
* Upgrade the most important components right away when we make breaking changes and move the ecosystem forward at a fast pace
|
||||
* Find new maintainers for projects that are important but were abandoned by previous owners
|
||||
|
||||
Additionally, some companies may choose to sponsor the development of one or many of the packages that are part of the community organization. They will commit to maintain projects, triage issues, fix bugs and develop features. In turn, they will be able to gain visibility for their work, for example through a mention of active maintainers in the README of individual projects after a consistent period of contributions. Such a mention may be removed if maintainers abandon the project.
|
||||
|
||||
If you are working on a popular component and would like to move it to the React Native community, please create an issue on the [discussions-and-proposals repository](https://github.com/react-native-community/discussions-and-proposals).
|
||||
@@ -1,7 +0,0 @@
|
||||
source 'https://rubygems.org'
|
||||
|
||||
# You may use http://rbenv.org/ or https://rvm.io/ to install and use this version
|
||||
ruby ">= 2.6.10"
|
||||
|
||||
gem 'cocoapods', '~> 1.12'
|
||||
gem 'activesupport', '>= 6.1.7.3', '< 7.1.0'
|
||||
-105
@@ -1,105 +0,0 @@
|
||||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
CFPropertyList (3.0.7)
|
||||
base64
|
||||
nkf
|
||||
rexml
|
||||
activesupport (7.0.8.4)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (>= 1.6, < 2)
|
||||
minitest (>= 5.1)
|
||||
tzinfo (~> 2.0)
|
||||
addressable (2.8.7)
|
||||
public_suffix (>= 2.0.2, < 7.0)
|
||||
algoliasearch (1.27.5)
|
||||
httpclient (~> 2.8, >= 2.8.3)
|
||||
json (>= 1.5.1)
|
||||
atomos (0.1.3)
|
||||
base64 (0.2.0)
|
||||
claide (1.1.0)
|
||||
cocoapods (1.15.2)
|
||||
addressable (~> 2.8)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
cocoapods-core (= 1.15.2)
|
||||
cocoapods-deintegrate (>= 1.0.3, < 2.0)
|
||||
cocoapods-downloader (>= 2.1, < 3.0)
|
||||
cocoapods-plugins (>= 1.0.0, < 2.0)
|
||||
cocoapods-search (>= 1.0.0, < 2.0)
|
||||
cocoapods-trunk (>= 1.6.0, < 2.0)
|
||||
cocoapods-try (>= 1.1.0, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
escape (~> 0.0.4)
|
||||
fourflusher (>= 2.3.0, < 3.0)
|
||||
gh_inspector (~> 1.0)
|
||||
molinillo (~> 0.8.0)
|
||||
nap (~> 1.0)
|
||||
ruby-macho (>= 2.3.0, < 3.0)
|
||||
xcodeproj (>= 1.23.0, < 2.0)
|
||||
cocoapods-core (1.15.2)
|
||||
activesupport (>= 5.0, < 8)
|
||||
addressable (~> 2.8)
|
||||
algoliasearch (~> 1.0)
|
||||
concurrent-ruby (~> 1.1)
|
||||
fuzzy_match (~> 2.0.4)
|
||||
nap (~> 1.0)
|
||||
netrc (~> 0.11)
|
||||
public_suffix (~> 4.0)
|
||||
typhoeus (~> 1.0)
|
||||
cocoapods-deintegrate (1.0.5)
|
||||
cocoapods-downloader (2.1)
|
||||
cocoapods-plugins (1.0.0)
|
||||
nap
|
||||
cocoapods-search (1.0.1)
|
||||
cocoapods-trunk (1.6.0)
|
||||
nap (>= 0.8, < 2.0)
|
||||
netrc (~> 0.11)
|
||||
cocoapods-try (1.2.0)
|
||||
colored2 (3.1.2)
|
||||
concurrent-ruby (1.3.3)
|
||||
escape (0.0.4)
|
||||
ethon (0.16.0)
|
||||
ffi (>= 1.15.0)
|
||||
ffi (1.17.0)
|
||||
fourflusher (2.3.1)
|
||||
fuzzy_match (2.0.4)
|
||||
gh_inspector (1.1.3)
|
||||
httpclient (2.8.3)
|
||||
i18n (1.14.5)
|
||||
concurrent-ruby (~> 1.0)
|
||||
json (2.7.2)
|
||||
minitest (5.24.1)
|
||||
molinillo (0.8.0)
|
||||
nanaimo (0.3.0)
|
||||
nap (1.1.0)
|
||||
netrc (0.11.0)
|
||||
nkf (0.2.0)
|
||||
public_suffix (4.0.7)
|
||||
rexml (3.2.9)
|
||||
strscan
|
||||
ruby-macho (2.5.1)
|
||||
strscan (3.1.0)
|
||||
typhoeus (1.4.1)
|
||||
ethon (>= 0.9.0)
|
||||
tzinfo (2.0.6)
|
||||
concurrent-ruby (~> 1.0)
|
||||
xcodeproj (1.24.0)
|
||||
CFPropertyList (>= 2.3.3, < 4.0)
|
||||
atomos (~> 0.1.3)
|
||||
claide (>= 1.0.2, < 2.0)
|
||||
colored2 (~> 3.1)
|
||||
nanaimo (~> 0.3.0)
|
||||
rexml (~> 3.2.4)
|
||||
|
||||
PLATFORMS
|
||||
ruby
|
||||
|
||||
DEPENDENCIES
|
||||
activesupport (>= 6.1.7.3, < 7.1.0)
|
||||
cocoapods (~> 1.12)
|
||||
|
||||
RUBY VERSION
|
||||
ruby 3.0.6p216
|
||||
|
||||
BUNDLED WITH
|
||||
2.4.13
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -8,21 +8,17 @@
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
import invariant from 'invariant';
|
||||
import NativeAccessibilityManager from 'react-native/Libraries/Components/AccessibilityInfo/NativeAccessibilityManager';
|
||||
import {DeviceEventEmitter, NativeModules, View} from 'react-native';
|
||||
import * as React from 'react';
|
||||
'use strict';
|
||||
|
||||
const {TestModule} = NativeModules;
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
const {View} = ReactNative;
|
||||
const RCTDeviceEventEmitter = require('RCTDeviceEventEmitter');
|
||||
const {TestModule, AccessibilityManager} = ReactNative.NativeModules;
|
||||
|
||||
class AccessibilityManagerTest extends React.Component<{...}> {
|
||||
componentDidMount(): void {
|
||||
invariant(
|
||||
NativeAccessibilityManager,
|
||||
"NativeAccessibilityManager doesn't exist",
|
||||
);
|
||||
|
||||
NativeAccessibilityManager.setAccessibilityContentSizeMultipliers({
|
||||
class AccessibilityManagerTest extends React.Component<{}> {
|
||||
componentDidMount() {
|
||||
AccessibilityManager.setAccessibilityContentSizeMultipliers({
|
||||
extraSmall: 1.0,
|
||||
small: 2.0,
|
||||
medium: 3.0,
|
||||
@@ -36,7 +32,7 @@ class AccessibilityManagerTest extends React.Component<{...}> {
|
||||
accessibilityExtraExtraLarge: 11.0,
|
||||
accessibilityExtraExtraExtraLarge: 12.0,
|
||||
});
|
||||
DeviceEventEmitter.addListener('didUpdateDimensions', update => {
|
||||
RCTDeviceEventEmitter.addListener('didUpdateDimensions', update => {
|
||||
TestModule.markTestPassed(update.window.fontScale === 4.0);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -15,23 +15,18 @@ const ReactNative = require('react-native');
|
||||
const {NativeAppEventEmitter, StyleSheet, Text, View} = ReactNative;
|
||||
const {TestModule} = ReactNative.NativeModules;
|
||||
|
||||
const deepDiffer = require('react-native/Libraries/Utilities/differ/deepDiffer');
|
||||
const deepDiffer = require('deepDiffer');
|
||||
|
||||
const TEST_PAYLOAD = {foo: 'bar'};
|
||||
|
||||
type AppEvent = {
|
||||
data: Object,
|
||||
ts: number,
|
||||
...
|
||||
};
|
||||
type AppEvent = {data: Object, ts: number};
|
||||
type State = {
|
||||
sent: 'none' | AppEvent,
|
||||
received: 'none' | AppEvent,
|
||||
elapsed?: string,
|
||||
...
|
||||
};
|
||||
|
||||
class AppEventsTest extends React.Component<{...}, State> {
|
||||
class AppEventsTest extends React.Component<{}, State> {
|
||||
state: State = {sent: 'none', received: 'none'};
|
||||
|
||||
componentDidMount() {
|
||||
@@ -41,7 +36,7 @@ class AppEventsTest extends React.Component<{...}, State> {
|
||||
this.setState({sent: event});
|
||||
}
|
||||
|
||||
receiveEvent: (event: any) => void = (event: any) => {
|
||||
receiveEvent = (event: any) => {
|
||||
if (deepDiffer(event.data, TEST_PAYLOAD)) {
|
||||
throw new Error('Received wrong event: ' + JSON.stringify(event));
|
||||
}
|
||||
@@ -51,7 +46,7 @@ class AppEventsTest extends React.Component<{...}, State> {
|
||||
});
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text>{JSON.stringify(this.state, null, ' ')}</Text>
|
||||
|
||||
@@ -0,0 +1,217 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
const {AsyncStorage, Text, View, StyleSheet} = ReactNative;
|
||||
const {TestModule} = ReactNative.NativeModules;
|
||||
|
||||
const deepDiffer = require('deepDiffer');
|
||||
|
||||
const DEBUG = false;
|
||||
|
||||
const KEY_1 = 'key_1';
|
||||
const VAL_1 = 'val_1';
|
||||
const KEY_2 = 'key_2';
|
||||
const VAL_2 = 'val_2';
|
||||
const KEY_MERGE = 'key_merge';
|
||||
const VAL_MERGE_1 = {foo: 1, bar: {hoo: 1, boo: 1}, moo: {a: 3}};
|
||||
const VAL_MERGE_2 = {bar: {hoo: 2}, baz: 2, moo: {a: 3}};
|
||||
const VAL_MERGE_EXPECT = {foo: 1, bar: {hoo: 2, boo: 1}, baz: 2, moo: {a: 3}};
|
||||
|
||||
// setup in componentDidMount
|
||||
let done = (result: ?boolean) => {};
|
||||
let updateMessage = (message: string) => {};
|
||||
|
||||
function runTestCase(description: string, fn) {
|
||||
updateMessage(description);
|
||||
fn();
|
||||
}
|
||||
|
||||
function expectTrue(condition: boolean, message: string) {
|
||||
if (!condition) {
|
||||
throw new Error(message);
|
||||
}
|
||||
}
|
||||
|
||||
function expectEqual(lhs, rhs, testname: string) {
|
||||
expectTrue(
|
||||
!deepDiffer(lhs, rhs),
|
||||
'Error in test ' +
|
||||
testname +
|
||||
': expected\n' +
|
||||
JSON.stringify(rhs) +
|
||||
'\ngot\n' +
|
||||
JSON.stringify(lhs),
|
||||
);
|
||||
}
|
||||
|
||||
function expectAsyncNoError(place, err) {
|
||||
if (err instanceof Error) {
|
||||
err = err.message;
|
||||
}
|
||||
expectTrue(
|
||||
err === null,
|
||||
'Unexpected error in ' + place + ': ' + JSON.stringify(err),
|
||||
);
|
||||
}
|
||||
|
||||
function testSetAndGet() {
|
||||
AsyncStorage.setItem(KEY_1, VAL_1, err1 => {
|
||||
expectAsyncNoError('testSetAndGet/setItem', err1);
|
||||
AsyncStorage.getItem(KEY_1, (err2, result) => {
|
||||
expectAsyncNoError('testSetAndGet/getItem', err2);
|
||||
expectEqual(result, VAL_1, 'testSetAndGet setItem');
|
||||
updateMessage('get(key_1) correctly returned ' + result);
|
||||
runTestCase('should get null for missing key', testMissingGet);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testMissingGet() {
|
||||
AsyncStorage.getItem(KEY_2, (err, result) => {
|
||||
expectAsyncNoError('testMissingGet/setItem', err);
|
||||
expectEqual(result, null, 'testMissingGet');
|
||||
updateMessage('missing get(key_2) correctly returned ' + result);
|
||||
runTestCase('check set twice results in a single key', testSetTwice);
|
||||
});
|
||||
}
|
||||
|
||||
function testSetTwice() {
|
||||
AsyncStorage.setItem(KEY_1, VAL_1, () => {
|
||||
AsyncStorage.setItem(KEY_1, VAL_1, () => {
|
||||
AsyncStorage.getItem(KEY_1, (err, result) => {
|
||||
expectAsyncNoError('testSetTwice/setItem', err);
|
||||
expectEqual(result, VAL_1, 'testSetTwice');
|
||||
updateMessage('setTwice worked as expected');
|
||||
runTestCase('test removeItem', testRemoveItem);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testRemoveItem() {
|
||||
AsyncStorage.setItem(KEY_1, VAL_1, () => {
|
||||
AsyncStorage.setItem(KEY_2, VAL_2, () => {
|
||||
AsyncStorage.getAllKeys((err, result) => {
|
||||
expectAsyncNoError('testRemoveItem/getAllKeys', err);
|
||||
expectTrue(
|
||||
result.indexOf(KEY_1) >= 0 && result.indexOf(KEY_2) >= 0,
|
||||
'Missing KEY_1 or KEY_2 in ' + '(' + result + ')',
|
||||
);
|
||||
updateMessage('testRemoveItem - add two items');
|
||||
AsyncStorage.removeItem(KEY_1, err2 => {
|
||||
expectAsyncNoError('testRemoveItem/removeItem', err2);
|
||||
updateMessage('delete successful ');
|
||||
AsyncStorage.getItem(KEY_1, (err3, result2) => {
|
||||
expectAsyncNoError('testRemoveItem/getItem', err3);
|
||||
expectEqual(
|
||||
result2,
|
||||
null,
|
||||
'testRemoveItem: key_1 present after delete',
|
||||
);
|
||||
updateMessage('key properly removed ');
|
||||
AsyncStorage.getAllKeys((err4, result3) => {
|
||||
expectAsyncNoError('testRemoveItem/getAllKeys', err4);
|
||||
expectTrue(
|
||||
result3.indexOf(KEY_1) === -1,
|
||||
'Unexpected: KEY_1 present in ' + result3,
|
||||
);
|
||||
updateMessage('proper length returned.');
|
||||
runTestCase('should merge values', testMerge);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testMerge() {
|
||||
AsyncStorage.setItem(KEY_MERGE, JSON.stringify(VAL_MERGE_1), err1 => {
|
||||
expectAsyncNoError('testMerge/setItem', err1);
|
||||
AsyncStorage.mergeItem(KEY_MERGE, JSON.stringify(VAL_MERGE_2), err2 => {
|
||||
expectAsyncNoError('testMerge/mergeItem', err2);
|
||||
AsyncStorage.getItem(KEY_MERGE, (err3, result) => {
|
||||
expectAsyncNoError('testMerge/setItem', err3);
|
||||
expectEqual(JSON.parse(result), VAL_MERGE_EXPECT, 'testMerge');
|
||||
updateMessage('objects deeply merged\nDone!');
|
||||
runTestCase('multi set and get', testOptimizedMultiGet);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testOptimizedMultiGet() {
|
||||
let batch = [[KEY_1, VAL_1], [KEY_2, VAL_2]];
|
||||
let keys = batch.map(([key, value]) => key);
|
||||
AsyncStorage.multiSet(batch, err1 => {
|
||||
// yes, twice on purpose
|
||||
[1, 2].forEach(i => {
|
||||
expectAsyncNoError(`${i} testOptimizedMultiGet/multiSet`, err1);
|
||||
AsyncStorage.multiGet(keys, (err2, result) => {
|
||||
expectAsyncNoError(`${i} testOptimizedMultiGet/multiGet`, err2);
|
||||
expectEqual(result, batch, `${i} testOptimizedMultiGet multiGet`);
|
||||
updateMessage(
|
||||
'multiGet([key_1, key_2]) correctly returned ' +
|
||||
JSON.stringify(result),
|
||||
);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
class AsyncStorageTest extends React.Component<{}, $FlowFixMeState> {
|
||||
state = {
|
||||
messages: 'Initializing...',
|
||||
done: false,
|
||||
};
|
||||
|
||||
componentDidMount() {
|
||||
done = () =>
|
||||
this.setState({done: true}, () => {
|
||||
TestModule.markTestCompleted();
|
||||
});
|
||||
updateMessage = msg => {
|
||||
this.setState({messages: this.state.messages.concat('\n' + msg)});
|
||||
DEBUG && console.log(msg);
|
||||
};
|
||||
AsyncStorage.clear(testSetAndGet);
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text>
|
||||
{/* $FlowFixMe(>=0.54.0 site=react_native_fb,react_native_oss) This
|
||||
* comment suppresses an error found when Flow v0.54 was deployed.
|
||||
* To see the error delete this comment and run Flow. */
|
||||
this.constructor.displayName + ': '}
|
||||
{this.state.done ? 'Done' : 'Testing...'}
|
||||
{'\n\n' + this.state.messages}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
const styles = StyleSheet.create({
|
||||
container: {
|
||||
backgroundColor: 'white',
|
||||
padding: 40,
|
||||
},
|
||||
});
|
||||
|
||||
AsyncStorageTest.displayName = 'AsyncStorageTest';
|
||||
|
||||
module.exports = AsyncStorageTest;
|
||||
@@ -1,32 +0,0 @@
|
||||
load("@fbsource//tools/build_defs:js_library_glob.bzl", "js_library_glob")
|
||||
load("@fbsource//tools/build_defs/oss:metro_defs.bzl", "rn_library")
|
||||
|
||||
# This file was generated by running
|
||||
# js1 build buckfiles
|
||||
|
||||
rn_library(
|
||||
name = "IntegrationTests",
|
||||
srcs = js_library_glob(
|
||||
[
|
||||
"**/*",
|
||||
],
|
||||
excludes = [
|
||||
"**/__*__/**",
|
||||
"**/*.command",
|
||||
"**/*.md",
|
||||
"websocket_integration_test_server.js",
|
||||
],
|
||||
),
|
||||
labels = [
|
||||
"pfh:ReactNative_CommonInfrastructurePlaceholder",
|
||||
],
|
||||
skip_processors = True,
|
||||
visibility = ["PUBLIC"],
|
||||
deps = [
|
||||
"//xplat/js:node_modules__invariant",
|
||||
"//xplat/js:node_modules__nullthrows",
|
||||
"//xplat/js/RKJSModules/vendor/react:react",
|
||||
"//xplat/js/react-native-github:react-native",
|
||||
"//xplat/js/react-native-github/packages/assets:assets",
|
||||
],
|
||||
)
|
||||
@@ -1,87 +0,0 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict-local
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
import type {ExtendedError} from 'react-native/Libraries/Core/ExtendedError';
|
||||
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
const parseErrorStack = require('react-native/Libraries/Core/Devtools/parseErrorStack');
|
||||
const {View} = ReactNative;
|
||||
|
||||
const {TestModule} = ReactNative.NativeModules;
|
||||
|
||||
class GlobalEvalWithSourceUrlTest extends React.Component<{...}> {
|
||||
componentDidMount(): void {
|
||||
if (typeof global.globalEvalWithSourceUrl !== 'function') {
|
||||
throw new Error(
|
||||
'Expected to find globalEvalWithSourceUrl function on global object but found ' +
|
||||
typeof global.globalEvalWithSourceUrl,
|
||||
);
|
||||
}
|
||||
const value = global.globalEvalWithSourceUrl('42');
|
||||
if (value !== 42) {
|
||||
throw new Error(
|
||||
'Expected globalEvalWithSourceUrl(expression) to return a value',
|
||||
);
|
||||
}
|
||||
let syntaxError: ?ExtendedError;
|
||||
try {
|
||||
global.globalEvalWithSourceUrl('{');
|
||||
} catch (e) {
|
||||
syntaxError = e;
|
||||
}
|
||||
if (!syntaxError) {
|
||||
throw new Error(
|
||||
'Expected globalEvalWithSourceUrl to throw on a syntax error',
|
||||
);
|
||||
}
|
||||
// Hermes throws an Error instead of a SyntaxError
|
||||
// https://github.com/facebook/hermes/issues/400
|
||||
if (
|
||||
syntaxError.jsEngine !== 'hermes' &&
|
||||
!(syntaxError instanceof SyntaxError)
|
||||
) {
|
||||
throw new Error(
|
||||
'Expected globalEvalWithSourceUrl to throw SyntaxError on a syntax error',
|
||||
);
|
||||
}
|
||||
const url = 'http://example.com/foo.js';
|
||||
let error;
|
||||
try {
|
||||
global.globalEvalWithSourceUrl('throw new Error()', url);
|
||||
} catch (e) {
|
||||
error = e;
|
||||
}
|
||||
if (!error) {
|
||||
throw new Error(
|
||||
'Expected globalEvalWithSourceUrl to throw an Error object',
|
||||
);
|
||||
}
|
||||
const parsedStack = parseErrorStack(error?.stack);
|
||||
if (parsedStack[0].file !== url) {
|
||||
throw new Error(
|
||||
`Expected first eval stack frame to be in ${url} but found ${String(
|
||||
parsedStack[0].file,
|
||||
)}`,
|
||||
);
|
||||
}
|
||||
TestModule.markTestCompleted();
|
||||
}
|
||||
|
||||
render(): React.Node {
|
||||
return <View />;
|
||||
}
|
||||
}
|
||||
|
||||
GlobalEvalWithSourceUrlTest.displayName = 'GlobalEvalWithSourceUrlTest';
|
||||
|
||||
module.exports = GlobalEvalWithSourceUrlTest;
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -27,19 +27,18 @@ const {TestModule} = ReactNative.NativeModules;
|
||||
|
||||
const TESTS = ['only-if-cached', 'default', 'reload', 'force-cache'];
|
||||
|
||||
type Props = {...};
|
||||
type Props = {};
|
||||
type State = {
|
||||
'only-if-cached'?: boolean,
|
||||
default?: boolean,
|
||||
reload?: boolean,
|
||||
'force-cache'?: boolean,
|
||||
...
|
||||
};
|
||||
|
||||
class ImageCachePolicyTest extends React.Component<Props, $FlowFixMeState> {
|
||||
state: $FlowFixMe | {...} = {};
|
||||
state = {};
|
||||
|
||||
shouldComponentUpdate(nextProps: Props, nextState: State): boolean {
|
||||
shouldComponentUpdate(nextProps: Props, nextState: State) {
|
||||
const results: Array<?boolean> = TESTS.map(x => nextState[x]);
|
||||
|
||||
if (!results.includes(undefined)) {
|
||||
@@ -57,14 +56,14 @@ class ImageCachePolicyTest extends React.Component<Props, $FlowFixMeState> {
|
||||
this.setState({[name]: pass});
|
||||
}
|
||||
|
||||
render(): React.Node {
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text>Hello</Text>
|
||||
<Image
|
||||
source={{
|
||||
uri:
|
||||
'https://raw.githubusercontent.com/facebook/react-native/HEAD/Libraries/NewAppScreen/components/logo.png?cacheBust=notinCache' +
|
||||
'https://facebook.github.io/react-native/img/favicon.png?cacheBust=notinCache' +
|
||||
Date.now(),
|
||||
cache: 'only-if-cached',
|
||||
}}
|
||||
@@ -75,7 +74,7 @@ class ImageCachePolicyTest extends React.Component<Props, $FlowFixMeState> {
|
||||
<Image
|
||||
source={{
|
||||
uri:
|
||||
'https://raw.githubusercontent.com/facebook/react-native/HEAD/Libraries/NewAppScreen/components/logo.png?cacheBust=notinCache' +
|
||||
'https://facebook.github.io/react-native/img/favicon.png?cacheBust=notinCache' +
|
||||
Date.now(),
|
||||
cache: 'default',
|
||||
}}
|
||||
@@ -86,7 +85,7 @@ class ImageCachePolicyTest extends React.Component<Props, $FlowFixMeState> {
|
||||
<Image
|
||||
source={{
|
||||
uri:
|
||||
'https://raw.githubusercontent.com/facebook/react-native/HEAD/Libraries/NewAppScreen/components/logo.png?cacheBust=notinCache' +
|
||||
'https://facebook.github.io/react-native/img/favicon.png?cacheBust=notinCache' +
|
||||
Date.now(),
|
||||
cache: 'reload',
|
||||
}}
|
||||
@@ -97,7 +96,7 @@ class ImageCachePolicyTest extends React.Component<Props, $FlowFixMeState> {
|
||||
<Image
|
||||
source={{
|
||||
uri:
|
||||
'https://raw.githubusercontent.com/facebook/react-native/HEAD/Libraries/NewAppScreen/components/logo.png?cacheBust=notinCache' +
|
||||
'https://facebook.github.io/react-native/img/favicon.png?cacheBust=notinCache' +
|
||||
Date.now(),
|
||||
cache: 'force-cache',
|
||||
}}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -15,18 +15,18 @@ const ReactNative = require('react-native');
|
||||
const {Image} = ReactNative;
|
||||
const {TestModule} = ReactNative.NativeModules;
|
||||
|
||||
class ImageSnapshotTest extends React.Component<{...}> {
|
||||
componentDidMount(): void {
|
||||
class ImageSnapshotTest extends React.Component<{}> {
|
||||
componentDidMount() {
|
||||
if (!TestModule.verifySnapshot) {
|
||||
throw new Error('TestModule.verifySnapshot not defined.');
|
||||
}
|
||||
}
|
||||
|
||||
done: (success: boolean) => void = (success: boolean) => {
|
||||
done = (success: boolean) => {
|
||||
TestModule.markTestPassed(success);
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
render() {
|
||||
return (
|
||||
<Image
|
||||
source={require('./blue_square.png')}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -10,9 +10,9 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const requestAnimationFrame = require('fbjs/lib/requestAnimationFrame');
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
|
||||
const {Text, View, StyleSheet} = ReactNative;
|
||||
const {TestModule} = ReactNative.NativeModules;
|
||||
|
||||
@@ -26,7 +26,7 @@ type State = {|
|
||||
|};
|
||||
|
||||
class IntegrationTestHarnessTest extends React.Component<Props, State> {
|
||||
state: State = {
|
||||
state = {
|
||||
done: false,
|
||||
};
|
||||
|
||||
@@ -38,7 +38,7 @@ class IntegrationTestHarnessTest extends React.Component<Props, State> {
|
||||
}
|
||||
}
|
||||
|
||||
runTest: () => void = () => {
|
||||
runTest = () => {
|
||||
if (this.props.shouldThrow) {
|
||||
throw new Error('Throwing error because shouldThrow');
|
||||
}
|
||||
@@ -52,18 +52,14 @@ class IntegrationTestHarnessTest extends React.Component<Props, State> {
|
||||
});
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text>
|
||||
{
|
||||
/* $FlowFixMe[incompatible-type] (>=0.54.0 site=react_native_fb,react_
|
||||
* native_oss) This comment suppresses an error found when Flow v0.54
|
||||
* was deployed. To see the error delete this comment and run Flow.
|
||||
*/
|
||||
// $FlowFixMe[unsafe-addition]
|
||||
this.constructor.displayName + ': '
|
||||
}
|
||||
{/* $FlowFixMe(>=0.54.0 site=react_native_fb,react_native_oss) This
|
||||
* comment suppresses an error found when Flow v0.54 was deployed.
|
||||
* To see the error delete this comment and run Flow. */
|
||||
this.constructor.displayName + ': '}
|
||||
{this.state.done ? 'Done' : 'Testing...'}
|
||||
</Text>
|
||||
</View>
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -10,53 +10,58 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
require('react-native/Libraries/Core/InitializeCore');
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
const {AppRegistry, ScrollView, StyleSheet, Text, TouchableOpacity, View} =
|
||||
ReactNative;
|
||||
const {
|
||||
AppRegistry,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} = ReactNative;
|
||||
|
||||
// Keep this list in sync with RNTesterIntegrationTests.m
|
||||
const TESTS = [
|
||||
require('./IntegrationTestHarnessTest'),
|
||||
require('./TimersTest'),
|
||||
require('./AsyncStorageTest'),
|
||||
require('./LayoutEventsTest'),
|
||||
require('./AppEventsTest'),
|
||||
require('./SimpleSnapshotTest'),
|
||||
require('./ImageCachePolicyTest'),
|
||||
require('./ImageSnapshotTest'),
|
||||
require('./PromiseTest'),
|
||||
require('./WebViewTest'),
|
||||
require('./SyncMethodTest'),
|
||||
require('./WebSocketTest'),
|
||||
require('./AccessibilityManagerTest'),
|
||||
require('./GlobalEvalWithSourceUrlTest'),
|
||||
];
|
||||
|
||||
TESTS.forEach(
|
||||
/* $FlowFixMe[incompatible-call] (>=0.54.0 site=react_native_fb,react_native_
|
||||
* oss) This comment suppresses an error found when Flow v0.54 was deployed.
|
||||
* To see the error delete this comment and run Flow. */
|
||||
/* $FlowFixMe(>=0.54.0 site=react_native_fb,react_native_oss) This comment
|
||||
* suppresses an error found when Flow v0.54 was deployed. To see the error
|
||||
* delete this comment and run Flow. */
|
||||
test => AppRegistry.registerComponent(test.displayName, () => test),
|
||||
);
|
||||
|
||||
// Modules required for integration tests
|
||||
require('./LoggingTestModule');
|
||||
require('LoggingTestModule');
|
||||
|
||||
type Test = any;
|
||||
|
||||
class IntegrationTestsApp extends React.Component<{...}, $FlowFixMeState> {
|
||||
state: {test: ?Test} = {
|
||||
class IntegrationTestsApp extends React.Component<{}, $FlowFixMeState> {
|
||||
state = {
|
||||
test: (null: ?Test),
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
render() {
|
||||
if (this.state.test) {
|
||||
return (
|
||||
<ScrollView>
|
||||
{/* $FlowFixMe[type-as-value] (>=0.53.0 site=react_native_fb,react_
|
||||
* native_oss) This comment suppresses an error when upgrading
|
||||
* Flow's support for React. To see the error delete this comment
|
||||
* and run Flow. */}
|
||||
{/* $FlowFixMe(>=0.53.0 site=react_native_fb,react_native_oss) This
|
||||
* comment suppresses an error when upgrading Flow's support for
|
||||
* React. To see the error delete this comment and run Flow. */}
|
||||
<this.state.test />
|
||||
</ScrollView>
|
||||
);
|
||||
@@ -73,10 +78,6 @@ class IntegrationTestsApp extends React.Component<{...}, $FlowFixMeState> {
|
||||
{TESTS.map(test => [
|
||||
<TouchableOpacity
|
||||
onPress={() => this.setState({test})}
|
||||
/* $FlowFixMe[incompatible-type] (>=0.115.0 site=react_native_fb)
|
||||
* This comment suppresses an error found when Flow v0.115 was
|
||||
* deployed. To see the error, delete this comment and run Flow.
|
||||
*/
|
||||
style={styles.row}>
|
||||
<Text style={styles.testName}>{test.displayName}</Text>
|
||||
</TouchableOpacity>,
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict-local
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
@@ -15,18 +15,15 @@ const ReactNative = require('react-native');
|
||||
const {Image, LayoutAnimation, StyleSheet, Text, View} = ReactNative;
|
||||
const {TestModule} = ReactNative.NativeModules;
|
||||
|
||||
import type {ViewStyleProp} from 'react-native/Libraries/StyleSheet/StyleSheet';
|
||||
import type {ViewStyleProp} from 'StyleSheet';
|
||||
|
||||
const deepDiffer = require('react-native/Libraries/Utilities/differ/deepDiffer');
|
||||
const deepDiffer = require('deepDiffer');
|
||||
|
||||
function debug(...args: Array<void | Layout | string>) {
|
||||
function debug(...args) {
|
||||
// console.log.apply(null, arguments);
|
||||
}
|
||||
|
||||
import type {
|
||||
Layout,
|
||||
LayoutEvent,
|
||||
} from 'react-native/Libraries/Types/CoreEventTypes';
|
||||
import type {Layout, LayoutEvent} from 'CoreEventTypes';
|
||||
|
||||
type Props = $ReadOnly<{||}>;
|
||||
|
||||
@@ -38,7 +35,6 @@ type State = {
|
||||
viewLayout?: Layout,
|
||||
viewStyle?: ViewStyleProp,
|
||||
containerStyle?: ViewStyleProp,
|
||||
...
|
||||
};
|
||||
|
||||
class LayoutEventsTest extends React.Component<Props, State> {
|
||||
@@ -59,7 +55,7 @@ class LayoutEventsTest extends React.Component<Props, State> {
|
||||
this.setState({viewStyle: {margin: 60}});
|
||||
}
|
||||
|
||||
addWrapText: () => void = () => {
|
||||
addWrapText = () => {
|
||||
debug('addWrapText invoked');
|
||||
this.setState(
|
||||
{extraText: ' And a bunch more text to wrap around a few lines.'},
|
||||
@@ -67,14 +63,14 @@ class LayoutEventsTest extends React.Component<Props, State> {
|
||||
);
|
||||
};
|
||||
|
||||
changeContainer: () => void = () => {
|
||||
changeContainer = () => {
|
||||
debug('changeContainer invoked');
|
||||
this.setState({containerStyle: {width: 280}}, () =>
|
||||
this.checkLayout(TestModule.markTestCompleted),
|
||||
);
|
||||
};
|
||||
|
||||
checkLayout: (next?: ?() => void) => void = (next?: ?() => void) => {
|
||||
checkLayout = (next?: ?() => void) => {
|
||||
const view = this._view;
|
||||
const txt = this._txt;
|
||||
const img = this._img;
|
||||
@@ -118,25 +114,22 @@ class LayoutEventsTest extends React.Component<Props, State> {
|
||||
}
|
||||
}
|
||||
|
||||
onViewLayout: (e: LayoutEvent) => void = (e: LayoutEvent) => {
|
||||
// $FlowFixMe[incompatible-call]
|
||||
onViewLayout = (e: LayoutEvent) => {
|
||||
debug('received view layout event\n', e.nativeEvent);
|
||||
this.setState({viewLayout: e.nativeEvent.layout}, this.checkLayout);
|
||||
};
|
||||
|
||||
onTextLayout: (e: LayoutEvent) => void = (e: LayoutEvent) => {
|
||||
// $FlowFixMe[incompatible-call]
|
||||
onTextLayout = (e: LayoutEvent) => {
|
||||
debug('received text layout event\n', e.nativeEvent);
|
||||
this.setState({textLayout: e.nativeEvent.layout}, this.checkLayout);
|
||||
};
|
||||
|
||||
onImageLayout: (e: LayoutEvent) => void = (e: LayoutEvent) => {
|
||||
// $FlowFixMe[incompatible-call]
|
||||
onImageLayout = (e: LayoutEvent) => {
|
||||
debug('received image layout event\n', e.nativeEvent);
|
||||
this.setState({imageLayout: e.nativeEvent.layout}, this.checkLayout);
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
render() {
|
||||
const viewStyle = [styles.view, this.state.viewStyle];
|
||||
const textLayout = this.state.textLayout || {width: '?', height: '?'};
|
||||
const imageLayout = this.state.imageLayout || {x: '?', y: '?'};
|
||||
@@ -200,5 +193,4 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
LayoutEventsTest.displayName = 'LayoutEventsTest';
|
||||
module.exports = LayoutEventsTest;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -9,29 +9,30 @@
|
||||
|
||||
'use strict';
|
||||
|
||||
const BatchedBridge = require('react-native/Libraries/BatchedBridge/BatchedBridge');
|
||||
const BatchedBridge = require('BatchedBridge');
|
||||
|
||||
const invariant = require('invariant');
|
||||
const warning = require('fbjs/lib/warning');
|
||||
const invariant = require('fbjs/lib/invariant');
|
||||
|
||||
const LoggingTestModule = {
|
||||
logToConsole: function (str) {
|
||||
logToConsole: function(str) {
|
||||
console.log(str);
|
||||
},
|
||||
logToConsoleAfterWait: function (str, timeout_ms) {
|
||||
setTimeout(function () {
|
||||
logToConsoleAfterWait: function(str, timeout_ms) {
|
||||
setTimeout(function() {
|
||||
console.log(str);
|
||||
}, timeout_ms);
|
||||
},
|
||||
warning: function (str) {
|
||||
console.warn(str);
|
||||
warning: function(str) {
|
||||
warning(false, str);
|
||||
},
|
||||
invariant: function (str) {
|
||||
invariant: function(str) {
|
||||
invariant(false, str);
|
||||
},
|
||||
logErrorToConsole: function (str) {
|
||||
logErrorToConsole: function(str) {
|
||||
console.error(str);
|
||||
},
|
||||
throwError: function (str) {
|
||||
throwError: function(str) {
|
||||
throw new Error(str);
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -15,11 +15,11 @@ const ReactNative = require('react-native');
|
||||
const {View} = ReactNative;
|
||||
const {TestModule} = ReactNative.NativeModules;
|
||||
|
||||
class PromiseTest extends React.Component<{...}> {
|
||||
shouldResolve: boolean = false;
|
||||
shouldReject: boolean = false;
|
||||
shouldSucceedAsync: boolean = false;
|
||||
shouldThrowAsync: boolean = false;
|
||||
class PromiseTest extends React.Component<{}> {
|
||||
shouldResolve = false;
|
||||
shouldReject = false;
|
||||
shouldSucceedAsync = false;
|
||||
shouldThrowAsync = false;
|
||||
|
||||
componentDidMount() {
|
||||
Promise.all([
|
||||
@@ -37,19 +37,19 @@ class PromiseTest extends React.Component<{...}> {
|
||||
);
|
||||
}
|
||||
|
||||
testShouldResolve: () => any = () => {
|
||||
testShouldResolve = () => {
|
||||
return TestModule.shouldResolve()
|
||||
.then(() => (this.shouldResolve = true))
|
||||
.catch(() => (this.shouldResolve = false));
|
||||
};
|
||||
|
||||
testShouldReject: () => any = () => {
|
||||
testShouldReject = () => {
|
||||
return TestModule.shouldReject()
|
||||
.then(() => (this.shouldReject = false))
|
||||
.catch(() => (this.shouldReject = true));
|
||||
};
|
||||
|
||||
testShouldSucceedAsync: () => Promise<any> = async (): Promise<any> => {
|
||||
testShouldSucceedAsync = async (): Promise<any> => {
|
||||
try {
|
||||
await TestModule.shouldResolve();
|
||||
this.shouldSucceedAsync = true;
|
||||
@@ -58,7 +58,7 @@ class PromiseTest extends React.Component<{...}> {
|
||||
}
|
||||
};
|
||||
|
||||
testShouldThrowAsync: () => Promise<any> = async (): Promise<any> => {
|
||||
testShouldThrowAsync = async (): Promise<any> => {
|
||||
try {
|
||||
await TestModule.shouldReject();
|
||||
this.shouldThrowAsync = false;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -12,8 +12,14 @@
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
|
||||
const {AppRegistry, ScrollView, StyleSheet, Text, TouchableOpacity, View} =
|
||||
ReactNative;
|
||||
const {
|
||||
AppRegistry,
|
||||
ScrollView,
|
||||
StyleSheet,
|
||||
Text,
|
||||
TouchableOpacity,
|
||||
View,
|
||||
} = ReactNative;
|
||||
|
||||
/* Keep this list in sync with RCTRootViewIntegrationTests.m */
|
||||
const TESTS = [
|
||||
|
||||
@@ -1,21 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict-local
|
||||
* @flow
|
||||
*/
|
||||
|
||||
const RCTNativeAppEventEmitter = require('react-native/Libraries/EventEmitter/RCTNativeAppEventEmitter');
|
||||
'use strict';
|
||||
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
const RCTNativeAppEventEmitter = require('RCTNativeAppEventEmitter');
|
||||
|
||||
const {View} = ReactNative;
|
||||
|
||||
const {TestModule} = ReactNative.NativeModules;
|
||||
import {type EventSubscription} from 'react-native/Libraries/vendor/emitter/EventEmitter';
|
||||
import type EmitterSubscription from 'EmitterSubscription';
|
||||
|
||||
const reactViewWidth = 101;
|
||||
const reactViewHeight = 102;
|
||||
@@ -31,9 +33,9 @@ type State = {|
|
||||
|
||||
class ReactContentSizeUpdateTest extends React.Component<Props, State> {
|
||||
_timeoutID: ?TimeoutID = null;
|
||||
_subscription: ?EventSubscription = null;
|
||||
_subscription: ?EmitterSubscription = null;
|
||||
|
||||
state: State = {
|
||||
state = {
|
||||
height: reactViewHeight,
|
||||
width: reactViewWidth,
|
||||
};
|
||||
@@ -68,9 +70,7 @@ class ReactContentSizeUpdateTest extends React.Component<Props, State> {
|
||||
});
|
||||
}
|
||||
|
||||
rootViewDidChangeIntrinsicSize: (intrinsicSize: State) => void = (
|
||||
intrinsicSize: State,
|
||||
) => {
|
||||
rootViewDidChangeIntrinsicSize = (intrinsicSize: State) => {
|
||||
if (
|
||||
intrinsicSize.height === newReactViewHeight &&
|
||||
intrinsicSize.width === newReactViewWidth
|
||||
@@ -79,7 +79,7 @@ class ReactContentSizeUpdateTest extends React.Component<Props, State> {
|
||||
}
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
render() {
|
||||
return (
|
||||
<View style={{height: this.state.height, width: this.state.width}} />
|
||||
);
|
||||
|
||||
@@ -1,34 +1,38 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict-local
|
||||
* @flow
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error
|
||||
* found when Flow v0.54 was deployed. To see the error delete this comment and
|
||||
* run Flow. */
|
||||
const requestAnimationFrame = require('fbjs/lib/requestAnimationFrame');
|
||||
|
||||
const {StyleSheet, View} = ReactNative;
|
||||
const {TestModule} = ReactNative.NativeModules;
|
||||
|
||||
class SimpleSnapshotTest extends React.Component<{...}> {
|
||||
componentDidMount(): void {
|
||||
class SimpleSnapshotTest extends React.Component<{}> {
|
||||
componentDidMount() {
|
||||
if (!TestModule.verifySnapshot) {
|
||||
throw new Error('TestModule.verifySnapshot not defined.');
|
||||
}
|
||||
requestAnimationFrame(() => TestModule.verifySnapshot(this.done));
|
||||
}
|
||||
|
||||
done: (success: boolean) => void = (success: boolean) => {
|
||||
done = (success: boolean) => {
|
||||
TestModule.markTestPassed(success);
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<View style={styles.box1} />
|
||||
|
||||
@@ -1,20 +1,22 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
* @flow strict-local
|
||||
* @flow
|
||||
*/
|
||||
|
||||
const RCTNativeAppEventEmitter = require('react-native/Libraries/EventEmitter/RCTNativeAppEventEmitter');
|
||||
'use strict';
|
||||
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
const RCTNativeAppEventEmitter = require('RCTNativeAppEventEmitter');
|
||||
const {View} = ReactNative;
|
||||
|
||||
const {TestModule} = ReactNative.NativeModules;
|
||||
import {type EventSubscription} from 'react-native/Libraries/vendor/emitter/EventEmitter';
|
||||
import type EmitterSubscription from 'EmitterSubscription';
|
||||
|
||||
const reactViewWidth = 111;
|
||||
const reactViewHeight = 222;
|
||||
@@ -29,7 +31,7 @@ type Props = $ReadOnly<{|
|
||||
|}>;
|
||||
|
||||
class SizeFlexibilityUpdateTest extends React.Component<Props> {
|
||||
_subscription: ?EventSubscription = null;
|
||||
_subscription: ?EmitterSubscription = null;
|
||||
|
||||
UNSAFE_componentWillMount() {
|
||||
this._subscription = RCTNativeAppEventEmitter.addListener(
|
||||
@@ -44,16 +46,15 @@ class SizeFlexibilityUpdateTest extends React.Component<Props> {
|
||||
}
|
||||
}
|
||||
|
||||
markPassed: () => void = () => {
|
||||
markPassed = () => {
|
||||
TestModule.markTestPassed(true);
|
||||
finalState = true;
|
||||
};
|
||||
|
||||
rootViewDidChangeIntrinsicSize: (intrinsicSize: {
|
||||
height: number,
|
||||
rootViewDidChangeIntrinsicSize = (intrinsicSize: {
|
||||
width: number,
|
||||
...
|
||||
}) => void = (intrinsicSize: {width: number, height: number, ...}) => {
|
||||
height: number,
|
||||
}) => {
|
||||
if (finalState) {
|
||||
// If a test reaches its final state, it is not expected to do anything more
|
||||
TestModule.markTestPassed(false);
|
||||
@@ -98,7 +99,7 @@ class SizeFlexibilityUpdateTest extends React.Component<Props> {
|
||||
}
|
||||
};
|
||||
|
||||
render(): React.Node {
|
||||
render() {
|
||||
return <View style={{height: reactViewHeight, width: reactViewWidth}} />;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -16,31 +16,17 @@ const {View} = ReactNative;
|
||||
|
||||
const {TestModule, RNTesterTestModule} = ReactNative.NativeModules;
|
||||
|
||||
class SyncMethodTest extends React.Component<{...}> {
|
||||
componentDidMount(): void {
|
||||
class SyncMethodTest extends React.Component<{}> {
|
||||
componentDidMount() {
|
||||
if (
|
||||
RNTesterTestModule.echoString('test string value') !== 'test string value'
|
||||
) {
|
||||
throw new Error('Something wrong with echoString sync method');
|
||||
throw new Error('Something wrong with sync method export');
|
||||
}
|
||||
if (RNTesterTestModule.methodThatReturnsNil() != null) {
|
||||
throw new Error('Something wrong with methodThatReturnsNil sync method');
|
||||
throw new Error('Something wrong with sync method export');
|
||||
}
|
||||
let response;
|
||||
RNTesterTestModule.methodThatCallsCallbackWithString('test', echo => {
|
||||
response = echo;
|
||||
});
|
||||
requestAnimationFrame(() => {
|
||||
if (response === 'test') {
|
||||
TestModule.markTestCompleted();
|
||||
} else {
|
||||
throw new Error(
|
||||
'Something wrong with methodThatCallsCallbackWithString sync method, ' +
|
||||
'got response ' +
|
||||
JSON.stringify(response),
|
||||
);
|
||||
}
|
||||
});
|
||||
TestModule.markTestCompleted();
|
||||
}
|
||||
|
||||
render(): React.Node {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -33,13 +33,13 @@ class TimersTest extends React.Component<Props, State> {
|
||||
_immediateIDs: Set<ImmediateID> = new Set();
|
||||
_animationFrameIDs: Set<AnimationFrameID> = new Set();
|
||||
|
||||
state: State = {
|
||||
state = {
|
||||
count: 0,
|
||||
done: false,
|
||||
};
|
||||
|
||||
setTimeout(fn: () => void, time: number): TimeoutID {
|
||||
const id: TimeoutID = setTimeout(() => {
|
||||
const id = setTimeout(() => {
|
||||
this._timeoutIDs.delete(id);
|
||||
fn();
|
||||
}, time);
|
||||
@@ -70,7 +70,7 @@ class TimersTest extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
setImmediate(fn: () => void): ImmediateID {
|
||||
const id: any = setImmediate(() => {
|
||||
const id = setImmediate(() => {
|
||||
this._immediateIDs.delete(id);
|
||||
fn();
|
||||
});
|
||||
@@ -81,7 +81,7 @@ class TimersTest extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
requestAnimationFrame(fn: () => void): AnimationFrameID {
|
||||
const id: AnimationFrameID = requestAnimationFrame(() => {
|
||||
const id = requestAnimationFrame(() => {
|
||||
this._animationFrameIDs.delete(id);
|
||||
fn();
|
||||
});
|
||||
@@ -97,46 +97,36 @@ class TimersTest extends React.Component<Props, State> {
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this.setTimeout(this.testSetTimeout0, 1000);
|
||||
}
|
||||
|
||||
testSetTimeout0() {
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this.setTimeout(this.testSetTimeout1, 0);
|
||||
}
|
||||
|
||||
testSetTimeout1() {
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this.setTimeout(this.testSetTimeout50, 1);
|
||||
}
|
||||
|
||||
testSetTimeout50() {
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this.setTimeout(this.testRequestAnimationFrame, 50);
|
||||
}
|
||||
|
||||
testRequestAnimationFrame() {
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this.requestAnimationFrame(this.testSetInterval0);
|
||||
}
|
||||
|
||||
testSetInterval0() {
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this._nextTest = this.testSetInterval20;
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this._interval = this.setInterval(this._incrementInterval, 0);
|
||||
}
|
||||
|
||||
testSetInterval20() {
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this._nextTest = this.testSetImmediate;
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this._interval = this.setInterval(this._incrementInterval, 20);
|
||||
}
|
||||
|
||||
testSetImmediate() {
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this.setImmediate(this.testClearTimeout0);
|
||||
}
|
||||
|
||||
@@ -149,7 +139,6 @@ class TimersTest extends React.Component<Props, State> {
|
||||
testClearTimeout30() {
|
||||
const timeout = this.setTimeout(() => this._fail('testClearTimeout30'), 30);
|
||||
this.clearTimeout(timeout);
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this.setTimeout(this.testClearMulti, 50);
|
||||
}
|
||||
|
||||
@@ -167,7 +156,6 @@ class TimersTest extends React.Component<Props, State> {
|
||||
fails.forEach(timeout => this.clearTimeout(timeout));
|
||||
this.setTimeout(() => this.clearTimeout(delayClear), 20);
|
||||
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this.setTimeout(this.testOrdering, 50);
|
||||
}
|
||||
|
||||
@@ -203,7 +191,6 @@ class TimersTest extends React.Component<Props, State> {
|
||||
),
|
||||
25,
|
||||
);
|
||||
// $FlowFixMe[method-unbinding] added when improving typing for this parameters
|
||||
this.setTimeout(this.done, 50);
|
||||
}
|
||||
|
||||
@@ -241,7 +228,7 @@ class TimersTest extends React.Component<Props, State> {
|
||||
}
|
||||
}
|
||||
|
||||
render(): React.Node {
|
||||
render() {
|
||||
return (
|
||||
<View style={styles.container}>
|
||||
<Text>
|
||||
@@ -253,7 +240,7 @@ class TimersTest extends React.Component<Props, State> {
|
||||
);
|
||||
}
|
||||
|
||||
_incrementInterval(): void {
|
||||
_incrementInterval() {
|
||||
if (this.state.count > 3) {
|
||||
throw new Error('interval incremented past end.');
|
||||
}
|
||||
@@ -262,7 +249,6 @@ class TimersTest extends React.Component<Props, State> {
|
||||
this.clearInterval(this._interval);
|
||||
this._interval = null;
|
||||
}
|
||||
// $FlowFixMe[method-unbinding]
|
||||
this.setState({count: 0}, this._nextTest);
|
||||
return;
|
||||
}
|
||||
@@ -281,5 +267,4 @@ const styles = StyleSheet.create({
|
||||
},
|
||||
});
|
||||
|
||||
TimersTest.displayName = 'TimersTest';
|
||||
module.exports = TimersTest;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -28,10 +28,9 @@ type State = {
|
||||
lastMessage: ?string | ?ArrayBuffer,
|
||||
testMessage: string,
|
||||
testExpectedResponse: string,
|
||||
...
|
||||
};
|
||||
|
||||
class WebSocketTest extends React.Component<{...}, State> {
|
||||
class WebSocketTest extends React.Component<{}, State> {
|
||||
state: State = {
|
||||
url: DEFAULT_WS_URL,
|
||||
fetchStatus: null,
|
||||
@@ -45,7 +44,7 @@ class WebSocketTest extends React.Component<{...}, State> {
|
||||
|
||||
_waitFor = (condition: any, timeout: any, callback: any) => {
|
||||
let remaining = timeout;
|
||||
const timeoutFunction = function () {
|
||||
const timeoutFunction = function() {
|
||||
if (condition()) {
|
||||
callback(true);
|
||||
return;
|
||||
@@ -69,11 +68,11 @@ class WebSocketTest extends React.Component<{...}, State> {
|
||||
});
|
||||
};
|
||||
|
||||
_socketIsConnected = (): boolean => {
|
||||
_socketIsConnected = () => {
|
||||
return this.state.socketState === 1; //'OPEN'
|
||||
};
|
||||
|
||||
_socketIsDisconnected = (): boolean => {
|
||||
_socketIsDisconnected = () => {
|
||||
return this.state.socketState === 3; //'CLOSED'
|
||||
};
|
||||
|
||||
@@ -106,7 +105,7 @@ class WebSocketTest extends React.Component<{...}, State> {
|
||||
this._sendText(this.state.testMessage);
|
||||
};
|
||||
|
||||
_receivedTestExpectedResponse = (): boolean => {
|
||||
_receivedTestExpectedResponse = () => {
|
||||
return this.state.lastMessage === this.state.testExpectedResponse;
|
||||
};
|
||||
|
||||
@@ -114,7 +113,7 @@ class WebSocketTest extends React.Component<{...}, State> {
|
||||
this.testConnect();
|
||||
}
|
||||
|
||||
testConnect: () => void = () => {
|
||||
testConnect = () => {
|
||||
this._connect();
|
||||
this._waitFor(this._socketIsConnected, 5, connectSucceeded => {
|
||||
if (!connectSucceeded) {
|
||||
@@ -125,7 +124,7 @@ class WebSocketTest extends React.Component<{...}, State> {
|
||||
});
|
||||
};
|
||||
|
||||
testSendAndReceive: () => void = () => {
|
||||
testSendAndReceive = () => {
|
||||
this._sendTestMessage();
|
||||
this._waitFor(this._receivedTestExpectedResponse, 5, messageReceived => {
|
||||
if (!messageReceived) {
|
||||
@@ -136,7 +135,7 @@ class WebSocketTest extends React.Component<{...}, State> {
|
||||
});
|
||||
};
|
||||
|
||||
testDisconnect: () => void = () => {
|
||||
testDisconnect = () => {
|
||||
this._disconnect();
|
||||
this._waitFor(this._socketIsDisconnected, 5, disconnectSucceeded => {
|
||||
TestModule.markTestPassed(disconnectSucceeded);
|
||||
|
||||
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
const React = require('react');
|
||||
const ReactNative = require('react-native');
|
||||
const {WebView} = ReactNative;
|
||||
|
||||
const {TestModule} = ReactNative.NativeModules;
|
||||
|
||||
class WebViewTest extends React.Component {
|
||||
render() {
|
||||
let firstMessageReceived = false;
|
||||
let secondMessageReceived = false;
|
||||
function processMessage(e) {
|
||||
const message = e.nativeEvent.data;
|
||||
if (message === 'First') {
|
||||
firstMessageReceived = true;
|
||||
}
|
||||
if (message === 'Second') {
|
||||
secondMessageReceived = true;
|
||||
}
|
||||
|
||||
// got both messages
|
||||
if (firstMessageReceived && secondMessageReceived) {
|
||||
TestModule.markTestPassed(true);
|
||||
}
|
||||
// wait for next message
|
||||
else if (firstMessageReceived && !secondMessageReceived) {
|
||||
return;
|
||||
}
|
||||
// first message got lost
|
||||
else if (!firstMessageReceived && secondMessageReceived) {
|
||||
throw new Error('First message got lost');
|
||||
}
|
||||
}
|
||||
const html =
|
||||
'Hello world' +
|
||||
'<script>' +
|
||||
"window.setTimeout(function(){window.postMessage('First'); window.postMessage('Second')}, 0)" +
|
||||
'</script>';
|
||||
|
||||
// fail if messages didn't get through;
|
||||
window.setTimeout(function() {
|
||||
throw new Error(
|
||||
firstMessageReceived
|
||||
? 'Both messages got lost'
|
||||
: 'Second message got lost',
|
||||
);
|
||||
}, 10000);
|
||||
|
||||
const source = {
|
||||
html: html,
|
||||
};
|
||||
|
||||
return (
|
||||
<WebView
|
||||
source={source}
|
||||
onMessage={processMessage}
|
||||
originWhitelist={['about:blank']}
|
||||
/>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
WebViewTest.displayName = 'WebViewTest';
|
||||
|
||||
module.exports = WebViewTest;
|
||||
+18
@@ -0,0 +1,18 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Copyright (c) Facebook, Inc. and its affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
# Set terminal title
|
||||
echo -en "\033]0;Web Socket Test Server\a"
|
||||
clear
|
||||
|
||||
THIS_DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd)
|
||||
pushd "$THIS_DIR"
|
||||
./websocket_integration_test_server.js
|
||||
popd
|
||||
|
||||
echo "Process terminated. Press <enter> to close the window"
|
||||
read
|
||||
@@ -1,12 +0,0 @@
|
||||
#!/bin/bash
|
||||
# Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
#
|
||||
# This source code is licensed under the MIT license found in the
|
||||
# LICENSE file in the root directory of this source tree.
|
||||
|
||||
THIS_DIR=$(cd -P "$(dirname "$(readlink "${BASH_SOURCE[0]}" || echo "${BASH_SOURCE[0]}")")" && pwd)
|
||||
pushd "$THIS_DIR" || exit
|
||||
./websocket_integration_test_server.js
|
||||
popd || exit
|
||||
|
||||
echo "Process terminated."
|
||||
@@ -1,6 +1,7 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Copyright (c) Meta Platforms, Inc. and affiliates.
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
@@ -8,11 +9,13 @@
|
||||
* @flow
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
/* eslint-env node */
|
||||
|
||||
/* $FlowFixMe(>=0.54.0 site=react_native_oss) This comment suppresses an error
|
||||
* found when Flow v0.54 was deployed. To see the error delete this comment and
|
||||
* run Flow. */
|
||||
const WebSocket = require('ws');
|
||||
|
||||
console.log(`\
|
||||
@@ -31,6 +34,7 @@ server.on('connection', ws => {
|
||||
console.log('WebSocket integration test server exit');
|
||||
process.exit(0);
|
||||
}
|
||||
console.log('Cookie:', ws.upgradeReq.headers.cookie);
|
||||
ws.send(message + '_response');
|
||||
});
|
||||
|
||||
|
||||
Vendored
+206
@@ -0,0 +1,206 @@
|
||||
import groovy.json.JsonSlurperClassic
|
||||
|
||||
def runPipeline() {
|
||||
try {
|
||||
ansiColor('xterm') {
|
||||
runStages();
|
||||
}
|
||||
} catch(err) {
|
||||
echo "Error: ${err}"
|
||||
currentBuild.result = "FAILED"
|
||||
}
|
||||
}
|
||||
|
||||
def pullDockerImage(imageName) {
|
||||
def result = sh(script: "docker pull ${imageName}", returnStatus: true)
|
||||
|
||||
if (result != 0) {
|
||||
throw new Exception("Failed to pull image[${imageName}]")
|
||||
}
|
||||
}
|
||||
|
||||
def buildDockerfile(dockerfilePath = "Dockerfile", imageName) {
|
||||
def buildCmd = "docker build -f ${dockerfilePath} -t ${imageName} ."
|
||||
echo "${buildCmd}"
|
||||
|
||||
def result = sh(script: buildCmd, returnStatus: true)
|
||||
|
||||
if (result != 0) {
|
||||
throw new Exception("Failed to build image[${imageName}] from '${dockerfilePath}'")
|
||||
}
|
||||
}
|
||||
|
||||
def runCmdOnDockerImage(imageName, cmd, run_opts = '') {
|
||||
def result = sh(script: "docker run ${run_opts} -i ${imageName} sh -c '${cmd}'", returnStatus: true)
|
||||
|
||||
if(result != 0) {
|
||||
throw new Exception("Failed to run cmd[${cmd}] on image[${imageName}]")
|
||||
}
|
||||
}
|
||||
|
||||
def calculateGithubInfo() {
|
||||
return [
|
||||
branch: env.BRANCH_NAME,
|
||||
sha: sh(returnStdout: true, script: 'git rev-parse HEAD').trim(),
|
||||
tag: null,
|
||||
isPR: "${env.CHANGE_URL}".contains('/pull/')
|
||||
]
|
||||
}
|
||||
|
||||
def getParallelInstrumentationTests(testDir, parallelCount, imageName) {
|
||||
def integrationTests = [:]
|
||||
def testCount = sh(script: "ls ${testDir} | wc -l", returnStdout: true).trim().toInteger()
|
||||
def testPerParallel = testCount.intdiv(parallelCount) + 1
|
||||
|
||||
def ignoredTests = 'CatalystNativeJavaToJSReturnValuesTestCase|CatalystUIManagerTestCase|CatalystMeasureLayoutTest|CatalystNativeJavaToJSArgumentsTestCase|CatalystNativeJSToJavaParametersTestCase|ReactScrollViewTestCase|ReactHorizontalScrollViewTestCase|ViewRenderingTestCase';
|
||||
|
||||
for (def x = 0; (x*testPerParallel) < testCount; x++) {
|
||||
def offset = x
|
||||
integrationTests["android integration tests: ${offset}"] = {
|
||||
run: {
|
||||
runCmdOnDockerImage(imageName, "bash /app/ContainerShip/scripts/run-android-docker-instrumentation-tests.sh --offset=${offset} --count=${testPerParallel} --ignore=\"${ignoredTests}\"", '--privileged --rm')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return integrationTests
|
||||
}
|
||||
|
||||
def runStages() {
|
||||
def buildInfo = [
|
||||
image: [
|
||||
name: "facebook/react-native",
|
||||
tag: null
|
||||
],
|
||||
scm: [
|
||||
branch: null,
|
||||
sha: null,
|
||||
tag: null,
|
||||
isPR: false
|
||||
]
|
||||
]
|
||||
|
||||
node {
|
||||
def jsDockerBuild, androidDockerBuild
|
||||
def jsTag, androidTag, jsImageName, androidImageName, parallelInstrumentationTests
|
||||
|
||||
try {
|
||||
stage('Setup') {
|
||||
parallel(
|
||||
'pull images': {
|
||||
pullDockerImage('containership/android-base:latest')
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
stage('Build') {
|
||||
checkout scm
|
||||
|
||||
def githubInfo = calculateGithubInfo()
|
||||
buildInfo.scm.branch = githubInfo.branch
|
||||
buildInfo.scm.sha = githubInfo.sha
|
||||
buildInfo.scm.tag = githubInfo.tag
|
||||
buildInfo.scm.isPR = githubInfo.isPR
|
||||
buildInfo.image.tag = "${buildInfo.scm.sha}-${env.BUILD_TAG.replace(" ", "-").replace("/", "-").replace("%2F", "-")}"
|
||||
|
||||
jsTag = "${buildInfo.image.tag}"
|
||||
androidTag = "${buildInfo.image.tag}"
|
||||
jsImageName = "${buildInfo.image.name}-js:${jsTag}"
|
||||
androidImageName = "${buildInfo.image.name}-android:${androidTag}"
|
||||
|
||||
parallelInstrumentationTests = getParallelInstrumentationTests('./ReactAndroid/src/androidTest/java/com/facebook/react/tests', 3, androidImageName)
|
||||
|
||||
parallel(
|
||||
'javascript build': {
|
||||
jsDockerBuild = docker.build("${jsImageName}", "-f ContainerShip/Dockerfile.javascript .")
|
||||
},
|
||||
'android build': {
|
||||
androidDockerBuild = docker.build("${androidImageName}", "-f ContainerShip/Dockerfile.android .")
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
stage('Tests JS') {
|
||||
try {
|
||||
parallel(
|
||||
'javascript flow': {
|
||||
runCmdOnDockerImage(jsImageName, 'yarn run flow -- check', '--rm')
|
||||
},
|
||||
'javascript tests': {
|
||||
runCmdOnDockerImage(jsImageName, 'yarn test --maxWorkers=4', '--rm')
|
||||
},
|
||||
'documentation tests': {
|
||||
runCmdOnDockerImage(jsImageName, 'cd website && yarn test', '--rm')
|
||||
},
|
||||
'documentation generation': {
|
||||
runCmdOnDockerImage(jsImageName, 'cd website && node ./server/generate.js', '--rm')
|
||||
}
|
||||
)
|
||||
} catch(e) {
|
||||
currentBuild.result = "FAILED"
|
||||
echo "Test JS Stage Error: ${e}"
|
||||
}
|
||||
}
|
||||
|
||||
stage('Tests Android') {
|
||||
try {
|
||||
parallel(
|
||||
'android unit tests': {
|
||||
runCmdOnDockerImage(androidImageName, 'bash /app/ContainerShip/scripts/run-android-docker-unit-tests.sh', '--privileged --rm')
|
||||
},
|
||||
'android e2e tests': {
|
||||
runCmdOnDockerImage(androidImageName, 'bash /app/ContainerShip/scripts/run-ci-e2e-tests.sh --android --js', '--privileged --rm')
|
||||
}
|
||||
)
|
||||
} catch(e) {
|
||||
currentBuild.result = "FAILED"
|
||||
echo "Tests Android Stage Error: ${e}"
|
||||
}
|
||||
}
|
||||
|
||||
stage('Tests Android Instrumentation') {
|
||||
// run all tests in parallel
|
||||
try {
|
||||
parallel(parallelInstrumentationTests)
|
||||
} catch(e) {
|
||||
currentBuild.result = "FAILED"
|
||||
echo "Tests Android Instrumentation Stage Error: ${e}"
|
||||
}
|
||||
}
|
||||
|
||||
stage('Cleanup') {
|
||||
cleanupImage(jsDockerBuild)
|
||||
cleanupImage(androidDockerBuild)
|
||||
}
|
||||
} catch(err) {
|
||||
cleanupImage(jsDockerBuild)
|
||||
cleanupImage(androidDockerBuild)
|
||||
|
||||
throw err
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
def isMasterBranch() {
|
||||
return env.GIT_BRANCH == 'master'
|
||||
}
|
||||
|
||||
def gitCommit() {
|
||||
return sh(returnStdout: true, script: 'git rev-parse HEAD').trim()
|
||||
}
|
||||
|
||||
def cleanupImage(image) {
|
||||
if (image) {
|
||||
try {
|
||||
sh "docker ps -a | awk '{ print \$1,\$2 }' | grep ${image.id} | awk '{print \$1 }' | xargs -I {} docker rm {}"
|
||||
sh "docker rmi -f ${image.id}"
|
||||
} catch(e) {
|
||||
echo "Error cleaning up ${image.id}"
|
||||
echo "${e}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
runPipeline()
|
||||
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) Facebook, Inc. and its affiliates.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -0,0 +1,514 @@
|
||||
// !$*UTF8*$!
|
||||
{
|
||||
archiveVersion = 1;
|
||||
classes = {
|
||||
};
|
||||
objectVersion = 46;
|
||||
objects = {
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
0CF68B051AF0549300FF9E5C /* ARTGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68ADE1AF0549300FF9E5C /* ARTGroup.m */; };
|
||||
0CF68B061AF0549300FF9E5C /* ARTNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE01AF0549300FF9E5C /* ARTNode.m */; };
|
||||
0CF68B071AF0549300FF9E5C /* ARTRenderable.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE21AF0549300FF9E5C /* ARTRenderable.m */; };
|
||||
0CF68B081AF0549300FF9E5C /* ARTShape.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE41AF0549300FF9E5C /* ARTShape.m */; };
|
||||
0CF68B091AF0549300FF9E5C /* ARTSurfaceView.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE61AF0549300FF9E5C /* ARTSurfaceView.m */; };
|
||||
0CF68B0A1AF0549300FF9E5C /* ARTText.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE81AF0549300FF9E5C /* ARTText.m */; };
|
||||
0CF68B0B1AF0549300FF9E5C /* ARTBrush.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AEC1AF0549300FF9E5C /* ARTBrush.m */; };
|
||||
0CF68B0C1AF0549300FF9E5C /* ARTLinearGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AEE1AF0549300FF9E5C /* ARTLinearGradient.m */; };
|
||||
0CF68B0D1AF0549300FF9E5C /* ARTPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF01AF0549300FF9E5C /* ARTPattern.m */; };
|
||||
0CF68B0E1AF0549300FF9E5C /* ARTRadialGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF21AF0549300FF9E5C /* ARTRadialGradient.m */; };
|
||||
0CF68B0F1AF0549300FF9E5C /* ARTSolidColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF41AF0549300FF9E5C /* ARTSolidColor.m */; };
|
||||
0CF68B101AF0549300FF9E5C /* RCTConvert+ART.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF71AF0549300FF9E5C /* RCTConvert+ART.m */; };
|
||||
0CF68B111AF0549300FF9E5C /* ARTGroupManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AFA1AF0549300FF9E5C /* ARTGroupManager.m */; };
|
||||
0CF68B121AF0549300FF9E5C /* ARTNodeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AFC1AF0549300FF9E5C /* ARTNodeManager.m */; };
|
||||
0CF68B131AF0549300FF9E5C /* ARTRenderableManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AFE1AF0549300FF9E5C /* ARTRenderableManager.m */; };
|
||||
0CF68B141AF0549300FF9E5C /* ARTShapeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68B001AF0549300FF9E5C /* ARTShapeManager.m */; };
|
||||
0CF68B151AF0549300FF9E5C /* ARTSurfaceViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68B021AF0549300FF9E5C /* ARTSurfaceViewManager.m */; };
|
||||
0CF68B161AF0549300FF9E5C /* ARTTextManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68B041AF0549300FF9E5C /* ARTTextManager.m */; };
|
||||
325CF7AD1E5F2ABA00AC9606 /* ARTBrush.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AEC1AF0549300FF9E5C /* ARTBrush.m */; };
|
||||
325CF7AE1E5F2ABA00AC9606 /* ARTLinearGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AEE1AF0549300FF9E5C /* ARTLinearGradient.m */; };
|
||||
325CF7AF1E5F2ABA00AC9606 /* ARTPattern.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF01AF0549300FF9E5C /* ARTPattern.m */; };
|
||||
325CF7B01E5F2ABA00AC9606 /* ARTRadialGradient.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF21AF0549300FF9E5C /* ARTRadialGradient.m */; };
|
||||
325CF7B11E5F2ABA00AC9606 /* ARTSolidColor.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF41AF0549300FF9E5C /* ARTSolidColor.m */; };
|
||||
325CF7B21E5F2ABA00AC9606 /* ARTGroupManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AFA1AF0549300FF9E5C /* ARTGroupManager.m */; };
|
||||
325CF7B31E5F2ABA00AC9606 /* ARTNodeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AFC1AF0549300FF9E5C /* ARTNodeManager.m */; };
|
||||
325CF7B41E5F2ABA00AC9606 /* ARTRenderableManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AFE1AF0549300FF9E5C /* ARTRenderableManager.m */; };
|
||||
325CF7B51E5F2ABA00AC9606 /* ARTShapeManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68B001AF0549300FF9E5C /* ARTShapeManager.m */; };
|
||||
325CF7B61E5F2ABA00AC9606 /* ARTSurfaceViewManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68B021AF0549300FF9E5C /* ARTSurfaceViewManager.m */; };
|
||||
325CF7B71E5F2ABA00AC9606 /* ARTTextManager.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68B041AF0549300FF9E5C /* ARTTextManager.m */; };
|
||||
325CF7B81E5F2ABA00AC9606 /* ARTGroup.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68ADE1AF0549300FF9E5C /* ARTGroup.m */; };
|
||||
325CF7B91E5F2ABA00AC9606 /* ARTNode.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE01AF0549300FF9E5C /* ARTNode.m */; };
|
||||
325CF7BA1E5F2ABA00AC9606 /* ARTRenderable.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE21AF0549300FF9E5C /* ARTRenderable.m */; };
|
||||
325CF7BB1E5F2ABA00AC9606 /* ARTShape.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE41AF0549300FF9E5C /* ARTShape.m */; };
|
||||
325CF7BC1E5F2ABA00AC9606 /* ARTSurfaceView.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE61AF0549300FF9E5C /* ARTSurfaceView.m */; };
|
||||
325CF7BD1E5F2ABA00AC9606 /* ARTText.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AE81AF0549300FF9E5C /* ARTText.m */; };
|
||||
325CF7BE1E5F2ABA00AC9606 /* RCTConvert+ART.m in Sources */ = {isa = PBXBuildFile; fileRef = 0CF68AF71AF0549300FF9E5C /* RCTConvert+ART.m */; };
|
||||
/* End PBXBuildFile section */
|
||||
|
||||
/* Begin PBXCopyFilesBuildPhase section */
|
||||
0CF68ABF1AF0540F00FF9E5C /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "include/$(PRODUCT_NAME)";
|
||||
dstSubfolderSpec = 16;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
323A12851E5F266B004975B8 /* CopyFiles */ = {
|
||||
isa = PBXCopyFilesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
dstPath = "include/$(PRODUCT_NAME)";
|
||||
dstSubfolderSpec = 16;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXCopyFilesBuildPhase section */
|
||||
|
||||
/* Begin PBXFileReference section */
|
||||
0CF68AC11AF0540F00FF9E5C /* libART.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = libART.a; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
0CF68ADB1AF0549300FF9E5C /* ARTCGFloatArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTCGFloatArray.h; sourceTree = "<group>"; };
|
||||
0CF68ADC1AF0549300FF9E5C /* ARTContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTContainer.h; sourceTree = "<group>"; };
|
||||
0CF68ADD1AF0549300FF9E5C /* ARTGroup.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTGroup.h; sourceTree = "<group>"; };
|
||||
0CF68ADE1AF0549300FF9E5C /* ARTGroup.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTGroup.m; sourceTree = "<group>"; };
|
||||
0CF68ADF1AF0549300FF9E5C /* ARTNode.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTNode.h; sourceTree = "<group>"; };
|
||||
0CF68AE01AF0549300FF9E5C /* ARTNode.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTNode.m; sourceTree = "<group>"; };
|
||||
0CF68AE11AF0549300FF9E5C /* ARTRenderable.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTRenderable.h; sourceTree = "<group>"; };
|
||||
0CF68AE21AF0549300FF9E5C /* ARTRenderable.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTRenderable.m; sourceTree = "<group>"; };
|
||||
0CF68AE31AF0549300FF9E5C /* ARTShape.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTShape.h; sourceTree = "<group>"; };
|
||||
0CF68AE41AF0549300FF9E5C /* ARTShape.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTShape.m; sourceTree = "<group>"; };
|
||||
0CF68AE51AF0549300FF9E5C /* ARTSurfaceView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTSurfaceView.h; sourceTree = "<group>"; };
|
||||
0CF68AE61AF0549300FF9E5C /* ARTSurfaceView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTSurfaceView.m; sourceTree = "<group>"; };
|
||||
0CF68AE71AF0549300FF9E5C /* ARTText.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTText.h; sourceTree = "<group>"; };
|
||||
0CF68AE81AF0549300FF9E5C /* ARTText.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTText.m; sourceTree = "<group>"; };
|
||||
0CF68AE91AF0549300FF9E5C /* ARTTextFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTTextFrame.h; sourceTree = "<group>"; };
|
||||
0CF68AEB1AF0549300FF9E5C /* ARTBrush.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTBrush.h; sourceTree = "<group>"; };
|
||||
0CF68AEC1AF0549300FF9E5C /* ARTBrush.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTBrush.m; sourceTree = "<group>"; };
|
||||
0CF68AED1AF0549300FF9E5C /* ARTLinearGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTLinearGradient.h; sourceTree = "<group>"; };
|
||||
0CF68AEE1AF0549300FF9E5C /* ARTLinearGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTLinearGradient.m; sourceTree = "<group>"; };
|
||||
0CF68AEF1AF0549300FF9E5C /* ARTPattern.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTPattern.h; sourceTree = "<group>"; };
|
||||
0CF68AF01AF0549300FF9E5C /* ARTPattern.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTPattern.m; sourceTree = "<group>"; };
|
||||
0CF68AF11AF0549300FF9E5C /* ARTRadialGradient.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTRadialGradient.h; sourceTree = "<group>"; };
|
||||
0CF68AF21AF0549300FF9E5C /* ARTRadialGradient.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTRadialGradient.m; sourceTree = "<group>"; };
|
||||
0CF68AF31AF0549300FF9E5C /* ARTSolidColor.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTSolidColor.h; sourceTree = "<group>"; };
|
||||
0CF68AF41AF0549300FF9E5C /* ARTSolidColor.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTSolidColor.m; sourceTree = "<group>"; };
|
||||
0CF68AF61AF0549300FF9E5C /* RCTConvert+ART.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "RCTConvert+ART.h"; sourceTree = "<group>"; };
|
||||
0CF68AF71AF0549300FF9E5C /* RCTConvert+ART.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "RCTConvert+ART.m"; sourceTree = "<group>"; };
|
||||
0CF68AF91AF0549300FF9E5C /* ARTGroupManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTGroupManager.h; sourceTree = "<group>"; };
|
||||
0CF68AFA1AF0549300FF9E5C /* ARTGroupManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTGroupManager.m; sourceTree = "<group>"; };
|
||||
0CF68AFB1AF0549300FF9E5C /* ARTNodeManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTNodeManager.h; sourceTree = "<group>"; };
|
||||
0CF68AFC1AF0549300FF9E5C /* ARTNodeManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTNodeManager.m; sourceTree = "<group>"; };
|
||||
0CF68AFD1AF0549300FF9E5C /* ARTRenderableManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTRenderableManager.h; sourceTree = "<group>"; };
|
||||
0CF68AFE1AF0549300FF9E5C /* ARTRenderableManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTRenderableManager.m; sourceTree = "<group>"; };
|
||||
0CF68AFF1AF0549300FF9E5C /* ARTShapeManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTShapeManager.h; sourceTree = "<group>"; };
|
||||
0CF68B001AF0549300FF9E5C /* ARTShapeManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTShapeManager.m; sourceTree = "<group>"; };
|
||||
0CF68B011AF0549300FF9E5C /* ARTSurfaceViewManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTSurfaceViewManager.h; sourceTree = "<group>"; };
|
||||
0CF68B021AF0549300FF9E5C /* ARTSurfaceViewManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTSurfaceViewManager.m; sourceTree = "<group>"; };
|
||||
0CF68B031AF0549300FF9E5C /* ARTTextManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ARTTextManager.h; sourceTree = "<group>"; };
|
||||
0CF68B041AF0549300FF9E5C /* ARTTextManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ARTTextManager.m; sourceTree = "<group>"; };
|
||||
323A12871E5F266B004975B8 /* libART-tvOS.a */ = {isa = PBXFileReference; explicitFileType = archive.ar; includeInIndex = 0; path = "libART-tvOS.a"; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
/* End PBXFileReference section */
|
||||
|
||||
/* Begin PBXFrameworksBuildPhase section */
|
||||
0CF68ABE1AF0540F00FF9E5C /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
323A12841E5F266B004975B8 /* Frameworks */ = {
|
||||
isa = PBXFrameworksBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXFrameworksBuildPhase section */
|
||||
|
||||
/* Begin PBXGroup section */
|
||||
0CF68AB81AF0540F00FF9E5C = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0CF68AEA1AF0549300FF9E5C /* Brushes */,
|
||||
0CF68AF81AF0549300FF9E5C /* ViewManagers */,
|
||||
0CF68ADB1AF0549300FF9E5C /* ARTCGFloatArray.h */,
|
||||
0CF68ADC1AF0549300FF9E5C /* ARTContainer.h */,
|
||||
0CF68ADD1AF0549300FF9E5C /* ARTGroup.h */,
|
||||
0CF68ADE1AF0549300FF9E5C /* ARTGroup.m */,
|
||||
0CF68ADF1AF0549300FF9E5C /* ARTNode.h */,
|
||||
0CF68AE01AF0549300FF9E5C /* ARTNode.m */,
|
||||
0CF68AE11AF0549300FF9E5C /* ARTRenderable.h */,
|
||||
0CF68AE21AF0549300FF9E5C /* ARTRenderable.m */,
|
||||
0CF68AE31AF0549300FF9E5C /* ARTShape.h */,
|
||||
0CF68AE41AF0549300FF9E5C /* ARTShape.m */,
|
||||
0CF68AE51AF0549300FF9E5C /* ARTSurfaceView.h */,
|
||||
0CF68AE61AF0549300FF9E5C /* ARTSurfaceView.m */,
|
||||
0CF68AE71AF0549300FF9E5C /* ARTText.h */,
|
||||
0CF68AE81AF0549300FF9E5C /* ARTText.m */,
|
||||
0CF68AE91AF0549300FF9E5C /* ARTTextFrame.h */,
|
||||
0CF68AF61AF0549300FF9E5C /* RCTConvert+ART.h */,
|
||||
0CF68AF71AF0549300FF9E5C /* RCTConvert+ART.m */,
|
||||
0CF68AC21AF0540F00FF9E5C /* Products */,
|
||||
);
|
||||
indentWidth = 2;
|
||||
sourceTree = "<group>";
|
||||
tabWidth = 2;
|
||||
usesTabs = 0;
|
||||
};
|
||||
0CF68AC21AF0540F00FF9E5C /* Products */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0CF68AC11AF0540F00FF9E5C /* libART.a */,
|
||||
323A12871E5F266B004975B8 /* libART-tvOS.a */,
|
||||
);
|
||||
name = Products;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0CF68AEA1AF0549300FF9E5C /* Brushes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0CF68AEB1AF0549300FF9E5C /* ARTBrush.h */,
|
||||
0CF68AEC1AF0549300FF9E5C /* ARTBrush.m */,
|
||||
0CF68AED1AF0549300FF9E5C /* ARTLinearGradient.h */,
|
||||
0CF68AEE1AF0549300FF9E5C /* ARTLinearGradient.m */,
|
||||
0CF68AEF1AF0549300FF9E5C /* ARTPattern.h */,
|
||||
0CF68AF01AF0549300FF9E5C /* ARTPattern.m */,
|
||||
0CF68AF11AF0549300FF9E5C /* ARTRadialGradient.h */,
|
||||
0CF68AF21AF0549300FF9E5C /* ARTRadialGradient.m */,
|
||||
0CF68AF31AF0549300FF9E5C /* ARTSolidColor.h */,
|
||||
0CF68AF41AF0549300FF9E5C /* ARTSolidColor.m */,
|
||||
);
|
||||
path = Brushes;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
0CF68AF81AF0549300FF9E5C /* ViewManagers */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
0CF68AF91AF0549300FF9E5C /* ARTGroupManager.h */,
|
||||
0CF68AFA1AF0549300FF9E5C /* ARTGroupManager.m */,
|
||||
0CF68AFB1AF0549300FF9E5C /* ARTNodeManager.h */,
|
||||
0CF68AFC1AF0549300FF9E5C /* ARTNodeManager.m */,
|
||||
0CF68AFD1AF0549300FF9E5C /* ARTRenderableManager.h */,
|
||||
0CF68AFE1AF0549300FF9E5C /* ARTRenderableManager.m */,
|
||||
0CF68AFF1AF0549300FF9E5C /* ARTShapeManager.h */,
|
||||
0CF68B001AF0549300FF9E5C /* ARTShapeManager.m */,
|
||||
0CF68B011AF0549300FF9E5C /* ARTSurfaceViewManager.h */,
|
||||
0CF68B021AF0549300FF9E5C /* ARTSurfaceViewManager.m */,
|
||||
0CF68B031AF0549300FF9E5C /* ARTTextManager.h */,
|
||||
0CF68B041AF0549300FF9E5C /* ARTTextManager.m */,
|
||||
);
|
||||
path = ViewManagers;
|
||||
sourceTree = "<group>";
|
||||
};
|
||||
/* End PBXGroup section */
|
||||
|
||||
/* Begin PBXNativeTarget section */
|
||||
0CF68AC01AF0540F00FF9E5C /* ART */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 0CF68AD51AF0540F00FF9E5C /* Build configuration list for PBXNativeTarget "ART" */;
|
||||
buildPhases = (
|
||||
0CF68ABD1AF0540F00FF9E5C /* Sources */,
|
||||
0CF68ABE1AF0540F00FF9E5C /* Frameworks */,
|
||||
0CF68ABF1AF0540F00FF9E5C /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = ART;
|
||||
productName = ART;
|
||||
productReference = 0CF68AC11AF0540F00FF9E5C /* libART.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
323A12861E5F266B004975B8 /* ART-tvOS */ = {
|
||||
isa = PBXNativeTarget;
|
||||
buildConfigurationList = 323A128D1E5F266B004975B8 /* Build configuration list for PBXNativeTarget "ART-tvOS" */;
|
||||
buildPhases = (
|
||||
323A12831E5F266B004975B8 /* Sources */,
|
||||
323A12841E5F266B004975B8 /* Frameworks */,
|
||||
323A12851E5F266B004975B8 /* CopyFiles */,
|
||||
);
|
||||
buildRules = (
|
||||
);
|
||||
dependencies = (
|
||||
);
|
||||
name = "ART-tvOS";
|
||||
productName = "ART-tvOS";
|
||||
productReference = 323A12871E5F266B004975B8 /* libART-tvOS.a */;
|
||||
productType = "com.apple.product-type.library.static";
|
||||
};
|
||||
/* End PBXNativeTarget section */
|
||||
|
||||
/* Begin PBXProject section */
|
||||
0CF68AB91AF0540F00FF9E5C /* Project object */ = {
|
||||
isa = PBXProject;
|
||||
attributes = {
|
||||
LastUpgradeCheck = 0940;
|
||||
TargetAttributes = {
|
||||
0CF68AC01AF0540F00FF9E5C = {
|
||||
CreatedOnToolsVersion = 6.2;
|
||||
};
|
||||
323A12861E5F266B004975B8 = {
|
||||
CreatedOnToolsVersion = 6.2;
|
||||
ProvisioningStyle = Automatic;
|
||||
};
|
||||
};
|
||||
};
|
||||
buildConfigurationList = 0CF68ABC1AF0540F00FF9E5C /* Build configuration list for PBXProject "ART" */;
|
||||
compatibilityVersion = "Xcode 3.2";
|
||||
developmentRegion = English;
|
||||
hasScannedForEncodings = 0;
|
||||
knownRegions = (
|
||||
en,
|
||||
);
|
||||
mainGroup = 0CF68AB81AF0540F00FF9E5C;
|
||||
productRefGroup = 0CF68AC21AF0540F00FF9E5C /* Products */;
|
||||
projectDirPath = "";
|
||||
projectRoot = "";
|
||||
targets = (
|
||||
0CF68AC01AF0540F00FF9E5C /* ART */,
|
||||
323A12861E5F266B004975B8 /* ART-tvOS */,
|
||||
);
|
||||
};
|
||||
/* End PBXProject section */
|
||||
|
||||
/* Begin PBXSourcesBuildPhase section */
|
||||
0CF68ABD1AF0540F00FF9E5C /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
0CF68B161AF0549300FF9E5C /* ARTTextManager.m in Sources */,
|
||||
0CF68B111AF0549300FF9E5C /* ARTGroupManager.m in Sources */,
|
||||
0CF68B0D1AF0549300FF9E5C /* ARTPattern.m in Sources */,
|
||||
0CF68B0A1AF0549300FF9E5C /* ARTText.m in Sources */,
|
||||
0CF68B121AF0549300FF9E5C /* ARTNodeManager.m in Sources */,
|
||||
0CF68B051AF0549300FF9E5C /* ARTGroup.m in Sources */,
|
||||
0CF68B131AF0549300FF9E5C /* ARTRenderableManager.m in Sources */,
|
||||
0CF68B091AF0549300FF9E5C /* ARTSurfaceView.m in Sources */,
|
||||
0CF68B0E1AF0549300FF9E5C /* ARTRadialGradient.m in Sources */,
|
||||
0CF68B151AF0549300FF9E5C /* ARTSurfaceViewManager.m in Sources */,
|
||||
0CF68B081AF0549300FF9E5C /* ARTShape.m in Sources */,
|
||||
0CF68B071AF0549300FF9E5C /* ARTRenderable.m in Sources */,
|
||||
0CF68B101AF0549300FF9E5C /* RCTConvert+ART.m in Sources */,
|
||||
0CF68B061AF0549300FF9E5C /* ARTNode.m in Sources */,
|
||||
0CF68B0F1AF0549300FF9E5C /* ARTSolidColor.m in Sources */,
|
||||
0CF68B0C1AF0549300FF9E5C /* ARTLinearGradient.m in Sources */,
|
||||
0CF68B0B1AF0549300FF9E5C /* ARTBrush.m in Sources */,
|
||||
0CF68B141AF0549300FF9E5C /* ARTShapeManager.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
323A12831E5F266B004975B8 /* Sources */ = {
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
325CF7B71E5F2ABA00AC9606 /* ARTTextManager.m in Sources */,
|
||||
325CF7B21E5F2ABA00AC9606 /* ARTGroupManager.m in Sources */,
|
||||
325CF7AF1E5F2ABA00AC9606 /* ARTPattern.m in Sources */,
|
||||
325CF7BD1E5F2ABA00AC9606 /* ARTText.m in Sources */,
|
||||
325CF7B31E5F2ABA00AC9606 /* ARTNodeManager.m in Sources */,
|
||||
325CF7B81E5F2ABA00AC9606 /* ARTGroup.m in Sources */,
|
||||
325CF7B41E5F2ABA00AC9606 /* ARTRenderableManager.m in Sources */,
|
||||
325CF7BC1E5F2ABA00AC9606 /* ARTSurfaceView.m in Sources */,
|
||||
325CF7B01E5F2ABA00AC9606 /* ARTRadialGradient.m in Sources */,
|
||||
325CF7B61E5F2ABA00AC9606 /* ARTSurfaceViewManager.m in Sources */,
|
||||
325CF7BB1E5F2ABA00AC9606 /* ARTShape.m in Sources */,
|
||||
325CF7BA1E5F2ABA00AC9606 /* ARTRenderable.m in Sources */,
|
||||
325CF7BE1E5F2ABA00AC9606 /* RCTConvert+ART.m in Sources */,
|
||||
325CF7B91E5F2ABA00AC9606 /* ARTNode.m in Sources */,
|
||||
325CF7B11E5F2ABA00AC9606 /* ARTSolidColor.m in Sources */,
|
||||
325CF7AE1E5F2ABA00AC9606 /* ARTLinearGradient.m in Sources */,
|
||||
325CF7AD1E5F2ABA00AC9606 /* ARTBrush.m in Sources */,
|
||||
325CF7B51E5F2ABA00AC9606 /* ARTShapeManager.m in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
/* End PBXSourcesBuildPhase section */
|
||||
|
||||
/* Begin XCBuildConfiguration section */
|
||||
0CF68AD31AF0540F00FF9E5C /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
"$(inherited)",
|
||||
);
|
||||
GCC_SYMBOLS_PRIVATE_EXTERN = NO;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
MTL_ENABLE_DEBUG_INFO = YES;
|
||||
ONLY_ACTIVE_ARCH = YES;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
0CF68AD41AF0540F00FF9E5C /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
ALWAYS_SEARCH_USER_PATHS = NO;
|
||||
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
|
||||
CLANG_CXX_LIBRARY = "libc++";
|
||||
CLANG_ENABLE_MODULES = YES;
|
||||
CLANG_ENABLE_OBJC_ARC = YES;
|
||||
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
|
||||
CLANG_WARN_BOOL_CONVERSION = YES;
|
||||
CLANG_WARN_COMMA = YES;
|
||||
CLANG_WARN_CONSTANT_CONVERSION = YES;
|
||||
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
|
||||
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
|
||||
CLANG_WARN_EMPTY_BODY = YES;
|
||||
CLANG_WARN_ENUM_CONVERSION = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_INT_CONVERSION = YES;
|
||||
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
|
||||
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
|
||||
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
|
||||
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
|
||||
CLANG_WARN_STRICT_PROTOTYPES = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
CLANG_WARN_UNREACHABLE_CODE = YES;
|
||||
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
|
||||
COPY_PHASE_STRIP = NO;
|
||||
ENABLE_NS_ASSERTIONS = NO;
|
||||
ENABLE_STRICT_OBJC_MSGSEND = YES;
|
||||
GCC_C_LANGUAGE_STANDARD = gnu99;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_UNDECLARED_SELECTOR = YES;
|
||||
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
|
||||
GCC_WARN_UNUSED_FUNCTION = YES;
|
||||
GCC_WARN_UNUSED_VARIABLE = YES;
|
||||
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
|
||||
MTL_ENABLE_DEBUG_INFO = NO;
|
||||
SDKROOT = iphoneos;
|
||||
SKIP_INSTALL = YES;
|
||||
VALIDATE_PRODUCT = YES;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
0CF68AD61AF0540F00FF9E5C /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
0CF68AD71AF0540F00FF9E5C /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
323A128E1E5F266B004975B8 /* Debug */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
DEBUG_INFORMATION_FORMAT = dwarf;
|
||||
ENABLE_TESTABILITY = YES;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = appletvos;
|
||||
SKIP_INSTALL = YES;
|
||||
TVOS_DEPLOYMENT_TARGET = 9.2;
|
||||
};
|
||||
name = Debug;
|
||||
};
|
||||
323A128F1E5F266B004975B8 /* Release */ = {
|
||||
isa = XCBuildConfiguration;
|
||||
buildSettings = {
|
||||
CLANG_ANALYZER_NONNULL = YES;
|
||||
CLANG_WARN_DOCUMENTATION_COMMENTS = YES;
|
||||
CLANG_WARN_INFINITE_RECURSION = YES;
|
||||
CLANG_WARN_SUSPICIOUS_MOVE = YES;
|
||||
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
OTHER_LDFLAGS = "-ObjC";
|
||||
PRODUCT_NAME = "$(TARGET_NAME)";
|
||||
SDKROOT = appletvos;
|
||||
SKIP_INSTALL = YES;
|
||||
TVOS_DEPLOYMENT_TARGET = 9.2;
|
||||
};
|
||||
name = Release;
|
||||
};
|
||||
/* End XCBuildConfiguration section */
|
||||
|
||||
/* Begin XCConfigurationList section */
|
||||
0CF68ABC1AF0540F00FF9E5C /* Build configuration list for PBXProject "ART" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
0CF68AD31AF0540F00FF9E5C /* Debug */,
|
||||
0CF68AD41AF0540F00FF9E5C /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
0CF68AD51AF0540F00FF9E5C /* Build configuration list for PBXNativeTarget "ART" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
0CF68AD61AF0540F00FF9E5C /* Debug */,
|
||||
0CF68AD71AF0540F00FF9E5C /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
323A128D1E5F266B004975B8 /* Build configuration list for PBXNativeTarget "ART-tvOS" */ = {
|
||||
isa = XCConfigurationList;
|
||||
buildConfigurations = (
|
||||
323A128E1E5F266B004975B8 /* Debug */,
|
||||
323A128F1E5F266B004975B8 /* Release */,
|
||||
);
|
||||
defaultConfigurationIsVisible = 0;
|
||||
defaultConfigurationName = Release;
|
||||
};
|
||||
/* End XCConfigurationList section */
|
||||
};
|
||||
rootObject = 0CF68AB91AF0540F00FF9E5C /* Project object */;
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
// A little helper to make sure we have the right memory allocation ready for use.
|
||||
// We assume that we will only this in one place so no reference counting is necessary.
|
||||
// Needs to be freed when dealloced.
|
||||
|
||||
// This is fragile since this relies on these values not getting reused. Consider
|
||||
// wrapping these in an Obj-C class or some ARC hackery to get refcounting.
|
||||
|
||||
typedef struct {
|
||||
size_t count;
|
||||
CGFloat *array;
|
||||
} ARTCGFloatArray;
|
||||
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@protocol ARTContainer <NSObject>
|
||||
|
||||
// This is used as a hook for child to mark it's parent as dirty.
|
||||
// This bubbles up to the root which gets marked as dirty.
|
||||
- (void)invalidate;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "ARTContainer.h"
|
||||
#import "ARTNode.h"
|
||||
|
||||
@interface ARTGroup : ARTNode <ARTContainer>
|
||||
|
||||
@property (nonatomic, assign) CGRect clipping;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,24 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "ARTGroup.h"
|
||||
|
||||
@implementation ARTGroup
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
|
||||
if (!CGRectIsEmpty(self.clipping)) {
|
||||
CGContextClipToRect(context, self.clipping);
|
||||
}
|
||||
|
||||
for (ARTNode *node in self.subviews) {
|
||||
[node renderTo:context];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,30 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <React/UIView+React.h>
|
||||
|
||||
/**
|
||||
* ART nodes are implemented as empty UIViews but this is just an implementation detail to fit
|
||||
* into the existing view management. They should also be shadow views and painted on a background
|
||||
* thread.
|
||||
*/
|
||||
|
||||
@interface ARTNode : UIView
|
||||
|
||||
@property (nonatomic, assign) CGFloat opacity;
|
||||
|
||||
- (void)invalidate;
|
||||
- (void)renderTo:(CGContextRef)context;
|
||||
|
||||
/**
|
||||
* renderTo will take opacity into account and draw renderLayerTo off-screen if there is opacity
|
||||
* specified, then composite that onto the context. renderLayerTo always draws at opacity=1.
|
||||
* @abstract
|
||||
*/
|
||||
- (void)renderLayerTo:(CGContextRef)context;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,80 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "ARTNode.h"
|
||||
|
||||
#import "ARTContainer.h"
|
||||
|
||||
@implementation ARTNode
|
||||
|
||||
- (void)insertReactSubview:(UIView *)subview atIndex:(NSInteger)atIndex
|
||||
{
|
||||
[super insertReactSubview:subview atIndex:atIndex];
|
||||
[self insertSubview:subview atIndex:atIndex];
|
||||
[self invalidate];
|
||||
}
|
||||
|
||||
- (void)removeReactSubview:(UIView *)subview
|
||||
{
|
||||
[super removeReactSubview:subview];
|
||||
[self invalidate];
|
||||
}
|
||||
|
||||
- (void)didUpdateReactSubviews
|
||||
{
|
||||
// Do nothing, as subviews are inserted by insertReactSubview:
|
||||
}
|
||||
|
||||
- (void)setOpacity:(CGFloat)opacity
|
||||
{
|
||||
[self invalidate];
|
||||
_opacity = opacity;
|
||||
}
|
||||
|
||||
- (void)setTransform:(CGAffineTransform)transform
|
||||
{
|
||||
[self invalidate];
|
||||
super.transform = transform;
|
||||
}
|
||||
|
||||
- (void)invalidate
|
||||
{
|
||||
id<ARTContainer> container = (id<ARTContainer>)self.superview;
|
||||
[container invalidate];
|
||||
}
|
||||
|
||||
- (void)renderTo:(CGContextRef)context
|
||||
{
|
||||
if (self.opacity <= 0) {
|
||||
// Nothing to paint
|
||||
return;
|
||||
}
|
||||
if (self.opacity >= 1) {
|
||||
// Just paint at full opacity
|
||||
CGContextSaveGState(context);
|
||||
CGContextConcatCTM(context, self.transform);
|
||||
CGContextSetAlpha(context, 1);
|
||||
[self renderLayerTo:context];
|
||||
CGContextRestoreGState(context);
|
||||
return;
|
||||
}
|
||||
// This needs to be painted on a layer before being composited.
|
||||
CGContextSaveGState(context);
|
||||
CGContextConcatCTM(context, self.transform);
|
||||
CGContextSetAlpha(context, self.opacity);
|
||||
CGContextBeginTransparencyLayer(context, NULL);
|
||||
[self renderLayerTo:context];
|
||||
CGContextEndTransparencyLayer(context);
|
||||
CGContextRestoreGState(context);
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
// abstract
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,23 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "ARTBrush.h"
|
||||
#import "ARTCGFloatArray.h"
|
||||
#import "ARTNode.h"
|
||||
|
||||
@interface ARTRenderable : ARTNode
|
||||
|
||||
@property (nonatomic, strong) ARTBrush *fill;
|
||||
@property (nonatomic, assign) CGColorRef stroke;
|
||||
@property (nonatomic, assign) CGFloat strokeWidth;
|
||||
@property (nonatomic, assign) CGLineCap strokeCap;
|
||||
@property (nonatomic, assign) CGLineJoin strokeJoin;
|
||||
@property (nonatomic, assign) ARTCGFloatArray strokeDash;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,87 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "ARTRenderable.h"
|
||||
|
||||
@implementation ARTRenderable
|
||||
|
||||
- (void)setFill:(ARTBrush *)fill
|
||||
{
|
||||
[self invalidate];
|
||||
_fill = fill;
|
||||
}
|
||||
|
||||
- (void)setStroke:(CGColorRef)stroke
|
||||
{
|
||||
if (stroke == _stroke) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
CGColorRelease(_stroke);
|
||||
_stroke = CGColorRetain(stroke);
|
||||
}
|
||||
|
||||
- (void)setStrokeWidth:(CGFloat)strokeWidth
|
||||
{
|
||||
[self invalidate];
|
||||
_strokeWidth = strokeWidth;
|
||||
}
|
||||
|
||||
- (void)setStrokeCap:(CGLineCap)strokeCap
|
||||
{
|
||||
[self invalidate];
|
||||
_strokeCap = strokeCap;
|
||||
}
|
||||
|
||||
- (void)setStrokeJoin:(CGLineJoin)strokeJoin
|
||||
{
|
||||
[self invalidate];
|
||||
_strokeJoin = strokeJoin;
|
||||
}
|
||||
|
||||
- (void)setStrokeDash:(ARTCGFloatArray)strokeDash
|
||||
{
|
||||
if (strokeDash.array == _strokeDash.array) {
|
||||
return;
|
||||
}
|
||||
if (_strokeDash.array) {
|
||||
free(_strokeDash.array);
|
||||
}
|
||||
[self invalidate];
|
||||
_strokeDash = strokeDash;
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGColorRelease(_stroke);
|
||||
if (_strokeDash.array) {
|
||||
free(_strokeDash.array);
|
||||
}
|
||||
}
|
||||
|
||||
- (void)renderTo:(CGContextRef)context
|
||||
{
|
||||
if (self.opacity <= 0 || self.opacity >= 1 || (self.fill && self.stroke)) {
|
||||
// If we have both fill and stroke, we will need to paint this using normal compositing
|
||||
[super renderTo: context];
|
||||
return;
|
||||
}
|
||||
// This is a terminal with only one painting. Therefore we don't need to paint this
|
||||
// off-screen. We can just composite it straight onto the buffer.
|
||||
CGContextSaveGState(context);
|
||||
CGContextConcatCTM(context, self.transform);
|
||||
CGContextSetAlpha(context, self.opacity);
|
||||
[self renderLayerTo:context];
|
||||
CGContextRestoreGState(context);
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
// abstract
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,84 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*
|
||||
* @format
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
// TODO: Move this into an ART mode called "serialized" or something
|
||||
|
||||
const Class = require('art/core/class.js');
|
||||
const Path = require('art/core/path.js');
|
||||
|
||||
const MOVE_TO = 0;
|
||||
const CLOSE = 1;
|
||||
const LINE_TO = 2;
|
||||
const CURVE_TO = 3;
|
||||
const ARC = 4;
|
||||
|
||||
const SerializablePath = Class(Path, {
|
||||
initialize: function(path) {
|
||||
this.reset();
|
||||
if (path instanceof SerializablePath) {
|
||||
this.path = path.path.slice(0);
|
||||
} else if (path) {
|
||||
if (path.applyToPath) {
|
||||
path.applyToPath(this);
|
||||
} else {
|
||||
this.push(path);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
onReset: function() {
|
||||
this.path = [];
|
||||
},
|
||||
|
||||
onMove: function(sx, sy, x, y) {
|
||||
this.path.push(MOVE_TO, x, y);
|
||||
},
|
||||
|
||||
onLine: function(sx, sy, x, y) {
|
||||
this.path.push(LINE_TO, x, y);
|
||||
},
|
||||
|
||||
onBezierCurve: function(sx, sy, p1x, p1y, p2x, p2y, x, y) {
|
||||
this.path.push(CURVE_TO, p1x, p1y, p2x, p2y, x, y);
|
||||
},
|
||||
|
||||
_arcToBezier: Path.prototype.onArc,
|
||||
|
||||
onArc: function(sx, sy, ex, ey, cx, cy, rx, ry, sa, ea, ccw, rotation) {
|
||||
if (rx !== ry || rotation) {
|
||||
return this._arcToBezier(
|
||||
sx,
|
||||
sy,
|
||||
ex,
|
||||
ey,
|
||||
cx,
|
||||
cy,
|
||||
rx,
|
||||
ry,
|
||||
sa,
|
||||
ea,
|
||||
ccw,
|
||||
rotation,
|
||||
);
|
||||
}
|
||||
this.path.push(ARC, cx, cy, rx, sa, ea, ccw ? 0 : 1);
|
||||
},
|
||||
|
||||
onClose: function() {
|
||||
this.path.push(CLOSE);
|
||||
},
|
||||
|
||||
toJSON: function() {
|
||||
return this.path;
|
||||
},
|
||||
});
|
||||
|
||||
module.exports = SerializablePath;
|
||||
@@ -0,0 +1,16 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "ARTRenderable.h"
|
||||
|
||||
@interface ARTShape : ARTRenderable
|
||||
|
||||
@property (nonatomic, assign) CGPathRef d;
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,66 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import "ARTShape.h"
|
||||
|
||||
@implementation ARTShape
|
||||
|
||||
- (void)setD:(CGPathRef)d
|
||||
{
|
||||
if (d == _d) {
|
||||
return;
|
||||
}
|
||||
[self invalidate];
|
||||
CGPathRelease(_d);
|
||||
_d = CGPathRetain(d);
|
||||
}
|
||||
|
||||
- (void)dealloc
|
||||
{
|
||||
CGPathRelease(_d);
|
||||
}
|
||||
|
||||
- (void)renderLayerTo:(CGContextRef)context
|
||||
{
|
||||
if ((!self.fill && !self.stroke) || !self.d) {
|
||||
return;
|
||||
}
|
||||
|
||||
CGPathDrawingMode mode = kCGPathStroke;
|
||||
if (self.fill) {
|
||||
if ([self.fill applyFillColor:context]) {
|
||||
mode = kCGPathFill;
|
||||
} else {
|
||||
CGContextSaveGState(context);
|
||||
CGContextAddPath(context, self.d);
|
||||
CGContextClip(context);
|
||||
[self.fill paint:context];
|
||||
CGContextRestoreGState(context);
|
||||
if (!self.stroke) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (self.stroke) {
|
||||
CGContextSetStrokeColorWithColor(context, self.stroke);
|
||||
CGContextSetLineWidth(context, self.strokeWidth);
|
||||
CGContextSetLineCap(context, self.strokeCap);
|
||||
CGContextSetLineJoin(context, self.strokeJoin);
|
||||
ARTCGFloatArray dash = self.strokeDash;
|
||||
if (dash.count) {
|
||||
CGContextSetLineDash(context, 0, dash.array, dash.count);
|
||||
}
|
||||
if (mode == kCGPathFill) {
|
||||
mode = kCGPathFillStroke;
|
||||
}
|
||||
}
|
||||
|
||||
CGContextAddPath(context, self.d);
|
||||
CGContextDrawPath(context, mode);
|
||||
}
|
||||
|
||||
@end
|
||||
@@ -0,0 +1,14 @@
|
||||
/**
|
||||
* Copyright (c) Facebook, Inc. and its affiliates.
|
||||
*
|
||||
* This source code is licensed under the MIT license found in the
|
||||
* LICENSE file in the root directory of this source tree.
|
||||
*/
|
||||
|
||||
#import <UIKit/UIKit.h>
|
||||
|
||||
#import "ARTContainer.h"
|
||||
|
||||
@interface ARTSurfaceView : UIView <ARTContainer>
|
||||
|
||||
@end
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user