forked from facebook/react
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[scheduler] 2/n Adding 'schedule' fixture (facebook#12884)
* Adding 'schedule' fixture **what is the change?:** We need to test the `schedule` module against real live browser APIs. As a quick solution we're writing a fixture for using in manual testing. Later we plan on adding automated browser testing, using this or a similar fixture as the test page. **why make this change?:** To further solidify test coverage for `schedule` before making further improvements/refactors to the module. **test plan:** `open fixtures/schedule/index.html` and inspect the results. It should be clear that things pass. We also temporarily broke the scheduler and verified that this fixture demonstrates the problems. **issue:** Internal task T29442940 * Made fixture tests display red or green border depending on pass/fail **what is the change?:** Added red/green solid/dashed border for test results when using the schedule fixture. We also tweaked the timing of the last test because it was on the line in terms of whether it passed or failed. **why make this change?:** To make it faster to use the fixture - it takes more time to read through the results line by line and check that they match what is expected. **test plan:** Looked at the fixture, and also tried modifying a test to show what it looks like when something fails.
- Loading branch information
Showing
2 changed files
with
293 additions
and
10 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,293 @@ | ||
<!DOCTYPE html> | ||
<html style="width: 100%; height: 100%;"> | ||
<head> | ||
<meta charset="utf-8"> | ||
<title>Schedule Test Page</title> | ||
<style> | ||
.correct { | ||
border: solid green 2px; | ||
} | ||
.incorrect { | ||
border: dashed red 2px; | ||
} | ||
</style> | ||
</head> | ||
<body> | ||
<h1>Schedule Fixture</h1> | ||
<p> | ||
This fixture is for manual testing purposes, and the patterns used in | ||
implementing it should not be used as a model. This is mainly for anyone | ||
working on making changes to the `schedule` module. | ||
</p> | ||
<h2>Tests:</h2> | ||
<ol> | ||
<li> | ||
<button onClick="runTestOne()">Run Test 1</button> | ||
<p>Calls the callback with the frame when not blocked:</p> | ||
<div><b>Expected:</b></div> | ||
<div id="test-1-expected"> | ||
</div> | ||
<div> -------------------------------------------------</div> | ||
<div> If you see the same above and below it's correct. | ||
<div> -------------------------------------------------</div> | ||
<div><b>Actual:</b></div> | ||
<div id="test-1"></div> | ||
</li> | ||
<li> | ||
<p>Accepts multiple callbacks and calls within frame when not blocked</p> | ||
<button onClick="runTestTwo()">Run Test 2</button> | ||
<div><b>Expected:</b></div> | ||
<div id="test-2-expected"> | ||
</div> | ||
<div> -------------------------------------------------</div> | ||
<div> If you see the same above and below it's correct. | ||
<div> -------------------------------------------------</div> | ||
<div><b>Actual:</b></div> | ||
<div id="test-2"></div> | ||
</li> | ||
<li> | ||
<p>Schedules callbacks in correct order when they use scheduleWork to schedule themselves</p> | ||
<button onClick="runTestThree()">Run Test 3</button> | ||
<div><b>Expected:</b></div> | ||
<div id="test-3-expected"> | ||
</div> | ||
<div> -------------------------------------------------</div> | ||
<div> If you see the same above and below it's correct. | ||
<div> -------------------------------------------------</div> | ||
<div><b>Actual:</b></div> | ||
<div id="test-3"></div> | ||
</li> | ||
<li> | ||
<p>Calls timed out callbacks and then any more pending callbacks, defers others if time runs out</p> | ||
<button onClick="runTestFour()">Run Test 4</button> | ||
<div><b>Expected:</b></div> | ||
<div id="test-4-expected"> | ||
</div> | ||
<div> -------------------------------------------------</div> | ||
<div> If you see the same above and below it's correct. | ||
<div> -------------------------------------------------</div> | ||
<div><b>Actual:</b></div> | ||
<div id="test-4"></div> | ||
</li> | ||
</ol> | ||
<script src="../../build/dist/react-scheduler.development.js"></script> | ||
<script src="https://unpkg.com/babel-standalone@6/babel.js"></script> | ||
<script type="text/babel"> | ||
const {scheduleWork, cancelWork, now} = ReactScheduler; | ||
function displayTestResult(testNumber) { | ||
const expectationNode = document.getElementById('test-' + testNumber + '-expected'); | ||
const resultNode = document.getElementById('test-' + testNumber); | ||
resultNode.innerHTML = latestResults[testNumber - 1].join('<br />'); | ||
expectationNode.innerHTML = expectedResults[testNumber - 1].join('<br />'); | ||
} | ||
function clearTestResult(testNumber) { | ||
const resultNode = document.getElementById('test-' + testNumber); | ||
resultNode.innerHTML = ''; | ||
latestResults[testNumber - 1] = []; | ||
} | ||
function updateTestResult(testNumber, textToAddToResult) { | ||
latestResults[testNumber - 1].push(textToAddToResult); | ||
}; | ||
function checkTestResult(testNumber) { | ||
|
||
let correct = true; | ||
const expected = expectedResults[testNumber - 1]; // zero indexing | ||
const result = latestResults[testNumber - 1]; // zero indexing | ||
if (expected.length !== result.length) { | ||
correct = false; | ||
} else { | ||
for (let i = 0, len = expected.length; i < len; i++) { | ||
if (expected[i] !== result[i]) { | ||
correct = false; | ||
break; | ||
} | ||
} | ||
} | ||
const currentClass = correct ? 'correct' : 'incorrect'; | ||
const previousClass = correct ? 'incorrect' : 'correct'; | ||
document.getElementById('test-' + testNumber).classList.remove(previousClass); | ||
document.getElementById('test-' + testNumber).classList.add(currentClass); | ||
} | ||
function logWhenFramesStart(testNumber, cb) { | ||
requestAnimationFrame(() => { | ||
updateTestResult(testNumber, 'frame 1 started'); | ||
requestAnimationFrame(() => { | ||
updateTestResult(testNumber, 'frame 2 started'); | ||
requestAnimationFrame(() => { | ||
updateTestResult(testNumber, 'frame 3 started... we stop counting now.'); | ||
cb(); | ||
}); | ||
}); | ||
}); | ||
} | ||
// push in results when we run the test | ||
const latestResults = [ | ||
// test 1 | ||
[ | ||
], | ||
// test 2 | ||
[ | ||
], | ||
// test 3 | ||
[ | ||
], | ||
// test 4 | ||
[ | ||
], | ||
]; | ||
|
||
const expectedResults = [ | ||
// test 1 | ||
[ | ||
'scheduled Cb1', | ||
'frame 1 started', | ||
'cb1 called with argument of {"didTimeout":false}', | ||
'frame 2 started', | ||
'frame 3 started... we stop counting now.', | ||
], | ||
// test 2 | ||
[ | ||
'scheduled CbA', | ||
'scheduled CbB', | ||
'frame 1 started', | ||
'cbA called with argument of {"didTimeout":false}', | ||
'cbB called with argument of {"didTimeout":false}', | ||
'frame 2 started', | ||
'frame 3 started... we stop counting now.', | ||
], | ||
// test 3 | ||
[ | ||
'scheduled CbA', | ||
'scheduled CbB', | ||
'frame 1 started', | ||
'scheduled CbA again', | ||
'cbA0 called with argument of {"didTimeout":false}', | ||
'cbB called with argument of {"didTimeout":false}', | ||
'cbA1 called with argument of {"didTimeout":false}', | ||
'frame 2 started', | ||
'frame 3 started... we stop counting now.', | ||
], | ||
// test 4 | ||
[ | ||
'scheduled cbA', | ||
'scheduled cbB', | ||
'scheduled cbC', | ||
'scheduled cbD', | ||
'frame 1 started', | ||
'cbC called with argument of {"didTimeout":true}', | ||
'cbA called with argument of {"didTimeout":false}', | ||
'cbA running and taking some time', | ||
'frame 2 started', | ||
'cbB called with argument of {"didTimeout":false}', | ||
'cbD called with argument of {"didTimeout":false}', | ||
'frame 3 started... we stop counting now.', | ||
], | ||
]; | ||
function runTestOne() { | ||
// Test 1 | ||
// Calls the callback with the frame when not blocked | ||
clearTestResult(1); | ||
const test1Log = []; | ||
const cb1Arguments = []; | ||
const cb1 = (x) => { | ||
updateTestResult(1, 'cb1 called with argument of ' + JSON.stringify(x)); | ||
} | ||
scheduleWork(cb1); | ||
updateTestResult(1, 'scheduled Cb1'); | ||
logWhenFramesStart(1, () => { | ||
displayTestResult(1); | ||
checkTestResult(1); | ||
}); | ||
}; | ||
|
||
function runTestTwo() { | ||
// Test 2 | ||
// accepts multiple callbacks and calls within frame when not blocked | ||
clearTestResult(2); | ||
const cbA = (x) => { | ||
updateTestResult(2, 'cbA called with argument of ' + JSON.stringify(x)); | ||
} | ||
const cbB = (x) => { | ||
updateTestResult(2, 'cbB called with argument of ' + JSON.stringify(x)); | ||
} | ||
scheduleWork(cbA); | ||
updateTestResult(2, 'scheduled CbA'); | ||
scheduleWork(cbB); | ||
updateTestResult(2, 'scheduled CbB'); | ||
logWhenFramesStart(2, () => { | ||
displayTestResult(2); | ||
checkTestResult(2); | ||
}); | ||
} | ||
|
||
function runTestThree() { | ||
// Test 3 | ||
// Schedules callbacks in correct order when they use scheduleWork to schedule themselves | ||
clearTestResult(3); | ||
let callbackAIterations = 0; | ||
const cbA = (x) => { | ||
if (callbackAIterations < 1) { | ||
scheduleWork(cbA); | ||
updateTestResult(3, 'scheduled CbA again'); | ||
} | ||
updateTestResult(3, 'cbA' + callbackAIterations + ' called with argument of ' + JSON.stringify(x)); | ||
callbackAIterations++; | ||
} | ||
const cbB = (x) => { | ||
updateTestResult(3, 'cbB called with argument of ' + JSON.stringify(x)); | ||
} | ||
scheduleWork(cbA); | ||
updateTestResult(3, 'scheduled CbA'); | ||
scheduleWork(cbB); | ||
updateTestResult(3, 'scheduled CbB'); | ||
logWhenFramesStart(3, () => { | ||
displayTestResult(3); | ||
checkTestResult(3); | ||
}); | ||
} | ||
|
||
function waitForTimeToPass(timeInMs) { | ||
const startTime = Date.now(); | ||
const endTime = startTime + timeInMs; | ||
while (Date.now() < endTime) { | ||
// wait... | ||
} | ||
} | ||
|
||
function runTestFour() { | ||
// Test 4 | ||
// Calls timed out callbacks and then any more pending callbacks, defers others if time runs out | ||
clearTestResult(4); | ||
const cbA = (x) => { | ||
updateTestResult(4, 'cbA called with argument of ' + JSON.stringify(x)); | ||
updateTestResult(4, 'cbA running and taking some time'); | ||
waitForTimeToPass(35); | ||
} | ||
const cbB = (x) => { | ||
updateTestResult(4, 'cbB called with argument of ' + JSON.stringify(x)); | ||
} | ||
const cbC = (x) => { | ||
updateTestResult(4, 'cbC called with argument of ' + JSON.stringify(x)); | ||
} | ||
const cbD = (x) => { | ||
updateTestResult(4, 'cbD called with argument of ' + JSON.stringify(x)); | ||
} | ||
scheduleWork(cbA); // won't time out | ||
updateTestResult(4, 'scheduled cbA'); | ||
scheduleWork(cbB, {timeout: 100}); // times out later | ||
updateTestResult(4, 'scheduled cbB'); | ||
scheduleWork(cbC, {timeout: 2}); // will time out fast | ||
updateTestResult(4, 'scheduled cbC'); | ||
scheduleWork(cbD); // won't time out | ||
updateTestResult(4, 'scheduled cbD'); | ||
|
||
// should have run in order of C, A, B, D | ||
|
||
logWhenFramesStart(4, () => { | ||
displayTestResult(4); | ||
checkTestResult(4); | ||
}); | ||
} | ||
</script type="text/babel"> | ||
</body> | ||
</html> |
This file was deleted.
Oops, something went wrong.