mirror of
https://github.com/status-im/react-native.git
synced 2025-01-16 20:44:10 +00:00
e2b25c8c9d
Summary: Packager can take a long time to load and the progress is usually displayed in another window (Terminal). I'm adding support for showing a UI inside React Native app for packager's progress when loading a bundle. This is how it will work: 1. React Native sends request to packager with `Accept: multipart/mixed` header. 2. Packager will detect that header to detect that client supports progress events and will reply with `Content-Type: multipart/mixed`. 3. While building the bundle it will emit chunks with small metadata (like `{progress: 0.3}`). In the end it will send the last chunk with the content of the bundle. 4. RN runtime will be receiving the events, for each progress event it will update the UI. The last chunk will be the actual bundle which will end the download process. This workflow is totally backwards-compatible -- normally RN doesn't set the `Accept` header. Reviewed By: mmmulani Differential Revision: D3845684 fbshipit-source-id: 5b3d2c5a4c6f4718d7e5de060d98f17491e82aba
108 lines
4.0 KiB
Objective-C
108 lines
4.0 KiB
Objective-C
/**
|
|
* The examples provided by Facebook are for non-commercial testing and
|
|
* evaluation purposes only.
|
|
*
|
|
* Facebook reserves all rights not expressly granted.
|
|
*
|
|
* 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 NON INFRINGEMENT. IN NO EVENT SHALL
|
|
* FACEBOOK 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.
|
|
*/
|
|
|
|
#import <XCTest/XCTest.h>
|
|
#import "RCTUtils.h"
|
|
#import "RCTMultipartStreamReader.h"
|
|
|
|
@interface RCTMultipartStreamReaderTests : XCTestCase
|
|
|
|
@end
|
|
|
|
@implementation RCTMultipartStreamReaderTests
|
|
|
|
- (void)testSimpleCase {
|
|
NSString *response =
|
|
@"preable, should be ignored\r\n"
|
|
@"--sample_boundary\r\n"
|
|
@"Content-Type: application/json; charset=utf-8\r\n"
|
|
@"Content-Length: 2\r\n\r\n"
|
|
@"{}\r\n"
|
|
@"--sample_boundary--\r\n"
|
|
@"epilogue, should be ignored";
|
|
|
|
NSInputStream *inputStream = [NSInputStream inputStreamWithData:[response dataUsingEncoding:NSUTF8StringEncoding]];
|
|
RCTMultipartStreamReader *reader = [[RCTMultipartStreamReader alloc] initWithInputStream:inputStream boundary:@"sample_boundary"];
|
|
__block NSInteger count = 0;
|
|
BOOL success = [reader readAllParts:^(NSDictionary *headers, NSData *content, BOOL done) {
|
|
XCTAssertTrue(done);
|
|
XCTAssertEqualObjects(headers[@"Content-Type"], @"application/json; charset=utf-8");
|
|
XCTAssertEqualObjects([[NSString alloc] initWithData:content encoding:NSUTF8StringEncoding], @"{}");
|
|
count++;
|
|
}];
|
|
XCTAssertTrue(success);
|
|
XCTAssertEqual(count, 1);
|
|
}
|
|
|
|
- (void)testMultipleParts {
|
|
NSString *response =
|
|
@"preable, should be ignored\r\n"
|
|
@"--sample_boundary\r\n"
|
|
@"1\r\n"
|
|
@"--sample_boundary\r\n"
|
|
@"2\r\n"
|
|
@"--sample_boundary\r\n"
|
|
@"3\r\n"
|
|
@"--sample_boundary--\r\n"
|
|
@"epilogue, should be ignored";
|
|
|
|
NSInputStream *inputStream = [NSInputStream inputStreamWithData:[response dataUsingEncoding:NSUTF8StringEncoding]];
|
|
RCTMultipartStreamReader *reader = [[RCTMultipartStreamReader alloc] initWithInputStream:inputStream boundary:@"sample_boundary"];
|
|
__block NSInteger count = 0;
|
|
BOOL success = [reader readAllParts:^(__unused NSDictionary *headers, NSData *content, BOOL done) {
|
|
count++;
|
|
XCTAssertEqual(done, count == 3);
|
|
NSString *expectedBody = [NSString stringWithFormat:@"%ld", (long)count];
|
|
NSString *actualBody = [[NSString alloc] initWithData:content encoding:NSUTF8StringEncoding];
|
|
XCTAssertEqualObjects(actualBody, expectedBody);
|
|
}];
|
|
XCTAssertTrue(success);
|
|
XCTAssertEqual(count, 3);
|
|
}
|
|
|
|
- (void)testNoDelimiter {
|
|
NSString *response = @"Yolo";
|
|
|
|
NSInputStream *inputStream = [NSInputStream inputStreamWithData:[response dataUsingEncoding:NSUTF8StringEncoding]];
|
|
RCTMultipartStreamReader *reader = [[RCTMultipartStreamReader alloc] initWithInputStream:inputStream boundary:@"sample_boundary"];
|
|
__block NSInteger count = 0;
|
|
BOOL success = [reader readAllParts:^(__unused NSDictionary *headers, __unused NSData *content, __unused BOOL done) {
|
|
count++;
|
|
}];
|
|
XCTAssertFalse(success);
|
|
XCTAssertEqual(count, 0);
|
|
}
|
|
|
|
- (void)testNoCloseDelimiter {
|
|
NSString *response =
|
|
@"preable, should be ignored\r\n"
|
|
@"--sample_boundary\r\n"
|
|
@"Content-Type: application/json; charset=utf-8\r\n"
|
|
@"Content-Length: 2\r\n\r\n"
|
|
@"{}\r\n"
|
|
@"--sample_boundary\r\n"
|
|
@"incomplete message...";
|
|
|
|
NSInputStream *inputStream = [NSInputStream inputStreamWithData:[response dataUsingEncoding:NSUTF8StringEncoding]];
|
|
RCTMultipartStreamReader *reader = [[RCTMultipartStreamReader alloc] initWithInputStream:inputStream boundary:@"sample_boundary"];
|
|
__block NSInteger count = 0;
|
|
BOOL success = [reader readAllParts:^(__unused NSDictionary *headers, __unused NSData *content, __unused BOOL done) {
|
|
count++;
|
|
}];
|
|
XCTAssertFalse(success);
|
|
XCTAssertEqual(count, 1);
|
|
}
|
|
|
|
@end
|