From: <rb...@us...> - 2017-11-03 16:23:11
|
Revision: 14900 http://sourceforge.net/p/htmlunit/code/14900 Author: rbri Date: 2017-11-03 16:23:08 +0000 (Fri, 03 Nov 2017) Log Message: ----------- more Promise fixes Modified Paths: -------------- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Promise.java trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/PromiseTest.java Modified: trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Promise.java =================================================================== --- trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Promise.java 2017-11-03 15:04:41 UTC (rev 14899) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Promise.java 2017-11-03 16:23:08 UTC (rev 14900) @@ -58,7 +58,7 @@ private Promise[] all_; private List<BasicJavaScriptJob> settledJobs_; - private Promise dependentPromise_; + private List<Promise> dependentPromises_; /** * Default constructor. @@ -207,9 +207,11 @@ settledJobs_ = null; } - if (dependentPromise_ != null) { - dependentPromise_.settle(fulfilled, newValue, window); - dependentPromise_ = null; + if (dependentPromises_ != null) { + for (Promise promise : dependentPromises_) { + promise.settle(fulfilled, newValue, window); + } + dependentPromises_ = null; } } @@ -292,7 +294,10 @@ final Object o = array.get(i); if (o instanceof Promise) { returnPromise.all_[i] = (Promise) o; - returnPromise.all_[i].dependentPromise_ = returnPromise; + if (returnPromise.all_[i].dependentPromises_ == null) { + returnPromise.all_[i].dependentPromises_ = new ArrayList<Promise>(2); + } + returnPromise.all_[i].dependentPromises_.add(returnPromise); } else { returnPromise.all_[i] = create(thisObj, new Object[] {o}, PromiseState.FULFILLED); @@ -349,7 +354,10 @@ returnPromise.settle(false, resultPromise.value_, window); } else { - resultPromise.dependentPromise_ = returnPromise; + if (resultPromise.dependentPromises_ == null) { + resultPromise.dependentPromises_ = new ArrayList<Promise>(2); + } + resultPromise.dependentPromises_.add(returnPromise); } } else { Modified: trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/PromiseTest.java =================================================================== --- trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/PromiseTest.java 2017-11-03 15:04:41 UTC (rev 14899) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/PromiseTest.java 2017-11-03 16:23:08 UTC (rev 14900) @@ -160,10 +160,12 @@ + " var p = new Promise();\n" + " log('done');\n" + " } catch(e) { log(e instanceof TypeError); }\n" + + " try{\n" + " var p = new Promise([1, 2, 4]);\n" + " log('done');\n" + " } catch(e) { log(e instanceof TypeError); }\n" + + " try{\n" + " var original = Promise.resolve(42);\n" + " var p = new Promise(original);\n" @@ -901,6 +903,51 @@ * @throws Exception if an error occurs */ @Test + @Alerts(DEFAULT = {"done", "first 3,1337,Success", "second 3,Success"}, + IE = {}) + public void allAsync2() throws Exception { + final String html = "<html>\n" + + "<head>\n" + + " <script>\n" + + " function test() {\n" + + " if (window.Promise) {\n" + + " var p1 = Promise.resolve(3);\n" + + " var p2 = 1337;\n" + + " var p3 = new Promise(function(resolve, reject) {\n" + + " window.setTimeout( function() {\n" + + " resolve('Success');\n" + + " }, 20);\n" + + " });\n" + + "\n" + + " Promise.all([p1, p2, p3]).then(function(values) {\n" + + " log('first ' + values);\n" + + " });\n" + + " Promise.all([p1, p3]).then(function(values) {\n" + + " log('second ' + values);\n" + + " });\n" + + " log('done');\n" + + " }\n" + + " }\n" + + "\n" + + " function log(x) {\n" + + " document.getElementById('log').value += x + '\\n';\n" + + " }\n" + + "</script></head>\n" + + "<body onload='test()'>\n" + + " <textarea id='log' cols='80' rows='40'></textarea>\n" + + "</body>\n" + + "</html>\n"; + + final WebDriver driver = loadPage2(html); + Thread.sleep(200); + final String text = driver.findElement(By.id("log")).getAttribute("value").trim().replaceAll("\r", ""); + assertEquals(String.join("\n", getExpectedAlerts()), text); + } + + /** + * @throws Exception if an error occurs + */ + @Test @Alerts(DEFAULT = {"done", "string", "Failed"}, IE = {}) public void allRejectAsync() throws Exception { @@ -946,6 +993,55 @@ * @throws Exception if an error occurs */ @Test + @Alerts(DEFAULT = {"done", "first Failed", "second Failed"}, + IE = {}) + public void allRejectAsync2() throws Exception { + final String html = "<html>\n" + + "<head>\n" + + " <script>\n" + + " function test() {\n" + + " if (window.Promise) {\n" + + " var p1 = Promise.resolve(3);\n" + + " var p2 = 1337;\n" + + " var p3 = new Promise(function(resolve, reject) {\n" + + " window.setTimeout( function() {\n" + + " reject('Failed');\n" + + " }, 20);\n" + + " });\n" + + "\n" + + " Promise.all([p1, p2, p3]).then(function(value) {\n" + + " log('failure');\n" + + " }, function(value) {\n" + + " log('first ' + value);\n" + + " });\n" + + " Promise.all([p1, p3]).then(function(value) {\n" + + " log('failure');\n" + + " }, function(value) {\n" + + " log('second ' + value);\n" + + " });\n" + + " log('done');\n" + + " }\n" + + " }\n" + + "\n" + + " function log(x) {\n" + + " document.getElementById('log').value += x + '\\n';\n" + + " }\n" + + "</script></head>\n" + + "<body onload='test()'>\n" + + " <textarea id='log' cols='80' rows='40'></textarea>\n" + + "</body>\n" + + "</html>\n"; + + final WebDriver driver = loadPage2(html); + Thread.sleep(200); + final String text = driver.findElement(By.id("log")).getAttribute("value").trim().replaceAll("\r", ""); + assertEquals(String.join("\n", getExpectedAlerts()), text); + } + + /** + * @throws Exception if an error occurs + */ + @Test @Alerts(DEFAULT = {"done", "Success 2"}, IE = {}) public void raceAsync() throws Exception { @@ -993,6 +1089,58 @@ * @throws Exception if an error occurs */ @Test + @Alerts(DEFAULT = {"done", "first Success 2", "second Success 2"}, + IE = {}) + public void raceAsync2() throws Exception { + final String html = "<html>\n" + + "<head>\n" + + " <script>\n" + + " function test() {\n" + + " if (window.Promise) {\n" + + " var p1 = new Promise(function(resolve, reject) {\n" + + " window.setTimeout( function() {\n" + + " resolve('Success');\n" + + " }, 40);\n" + + " });\n" + + " var p2 = new Promise(function(resolve, reject) {\n" + + " window.setTimeout( function() {\n" + + " resolve('Success 2');\n" + + " }, 20);\n" + + " });\n" + + "\n" + + " Promise.race([p1, p2]).then(function(value) {\n" + + " log('first ' + value);\n" + + " }, function(value) {\n" + + " log('failure');\n" + + " });\n" + + " Promise.race([p1, p2]).then(function(value) {\n" + + " log('second ' + value);\n" + + " }, function(value) {\n" + + " log('failure');\n" + + " });\n" + + " log('done');\n" + + " }\n" + + " }\n" + + "\n" + + " function log(x) {\n" + + " document.getElementById('log').value += x + '\\n';\n" + + " }\n" + + "</script></head>\n" + + "<body onload='test()'>\n" + + " <textarea id='log' cols='80' rows='40'></textarea>\n" + + "</body>\n" + + "</html>\n"; + + final WebDriver driver = loadPage2(html); + Thread.sleep(200); + final String text = driver.findElement(By.id("log")).getAttribute("value").trim().replaceAll("\r", ""); + assertEquals(String.join("\n", getExpectedAlerts()), text); + } + + /** + * @throws Exception if an error occurs + */ + @Test @Alerts(DEFAULT = {"done", "Failed"}, IE = {}) public void raceRejectAsync() throws Exception { @@ -1035,4 +1183,56 @@ final String text = driver.findElement(By.id("log")).getAttribute("value").trim().replaceAll("\r", ""); assertEquals(String.join("\n", getExpectedAlerts()), text); } + + /** + * @throws Exception if an error occurs + */ + @Test + @Alerts(DEFAULT = {"done", "first Failed", "second Failed"}, + IE = {}) + public void raceRejectAsync2() throws Exception { + final String html = "<html>\n" + + "<head>\n" + + " <script>\n" + + " function test() {\n" + + " if (window.Promise) {\n" + + " var p1 = new Promise(function(resolve, reject) {\n" + + " window.setTimeout( function() {\n" + + " resolve('Success');\n" + + " }, 40);\n" + + " });\n" + + " var p2 = new Promise(function(resolve, reject) {\n" + + " window.setTimeout( function() {\n" + + " reject('Failed');\n" + + " }, 20);\n" + + " });\n" + + "\n" + + " Promise.race([p1, p2]).then(function(value) {\n" + + " log('failure');\n" + + " }, function(value) {\n" + + " log('first ' + value);\n" + + " });\n" + + " Promise.race([p1, p2]).then(function(value) {\n" + + " log('failure');\n" + + " }, function(value) {\n" + + " log('second ' + value);\n" + + " });\n" + + " log('done');\n" + + " }\n" + + " }\n" + + "\n" + + " function log(x) {\n" + + " document.getElementById('log').value += x + '\\n';\n" + + " }\n" + + "</script></head>\n" + + "<body onload='test()'>\n" + + " <textarea id='log' cols='80' rows='40'></textarea>\n" + + "</body>\n" + + "</html>\n"; + + final WebDriver driver = loadPage2(html); + Thread.sleep(200); + final String text = driver.findElement(By.id("log")).getAttribute("value").trim().replaceAll("\r", ""); + assertEquals(String.join("\n", getExpectedAlerts()), text); + } } |