From: <rb...@us...> - 2017-10-07 17:33:01
|
Revision: 14863 http://sourceforge.net/p/htmlunit/code/14863 Author: rbri Date: 2017-10-07 17:32:58 +0000 (Sat, 07 Oct 2017) Log Message: ----------- fix Promise for many then calls on the same async one 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-10-07 14:42:01 UTC (rev 14862) +++ trunk/htmlunit/src/main/java/com/gargoylesoftware/htmlunit/javascript/host/Promise.java 2017-10-07 17:32:58 UTC (rev 14863) @@ -18,6 +18,9 @@ import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.EDGE; import static com.gargoylesoftware.htmlunit.javascript.configuration.SupportedBrowser.FF; +import java.util.ArrayList; +import java.util.List; + import com.gargoylesoftware.htmlunit.javascript.SimpleScriptable; import com.gargoylesoftware.htmlunit.javascript.background.BasicJavaScriptJob; import com.gargoylesoftware.htmlunit.javascript.configuration.JsxClass; @@ -52,7 +55,7 @@ /** To be set only by {@link #all(Context, Scriptable, Object[], Function)}. */ private Promise[] all_; - private BasicJavaScriptJob settledAction_; + private List<BasicJavaScriptJob> settledJobs_; private Promise dependentPromise_; /** @@ -186,9 +189,11 @@ state_ = PromiseState.REJECTED; } - if (settledAction_ != null) { - window.getWebWindow().getJobManager().addJob(settledAction_, window.getDocument().getPage()); - settledAction_ = null; + if (settledJobs_ != null) { + for (BasicJavaScriptJob job : settledJobs_) { + window.getWebWindow().getJobManager().addJob(job, window.getDocument().getPage()); + } + settledJobs_ = null; } if (dependentPromise_ != null) { @@ -248,7 +253,7 @@ final Promise thisPromise = this; - settledAction_ = new BasicJavaScriptJob() { + final BasicJavaScriptJob job = new BasicJavaScriptJob() { @Override public void run() { @@ -300,9 +305,14 @@ }; if (state_ == PromiseState.FULFILLED || state_ == PromiseState.REJECTED) { - window.getWebWindow().getJobManager().addJob(settledAction_, window.getDocument().getPage()); - settledAction_ = null; + window.getWebWindow().getJobManager().addJob(job, window.getDocument().getPage()); } + else { + if (settledJobs_ == null) { + settledJobs_ = new ArrayList<BasicJavaScriptJob>(2); + } + settledJobs_.add(job); + } return returnPromise; } 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-10-07 14:42:01 UTC (rev 14862) +++ trunk/htmlunit/src/test/java/com/gargoylesoftware/htmlunit/javascript/host/PromiseTest.java 2017-10-07 17:32:58 UTC (rev 14863) @@ -518,6 +518,88 @@ * @throws Exception if an error occurs */ @Test + @Alerts(DEFAULT = {"done", "1 yes", "2 yes"}, + IE = {}) + public void thenTwice() throws Exception { + final String html = "<html>\n" + + "<head>\n" + + " <script>\n" + + " function test() {\n" + + " if (window.Promise) {\n" + + " var p = Promise.resolve('yes');\n" + + "\n" + + " p.then(function(value) {\n" + + " log('1 ' + value);\n" + + " })\n" + + " p.then(function(value) {\n" + + " log('2 ' + value);\n" + + " })\n" + + " log('done');\n" + + " }\n" + + " }\n" + + "\n" + + " function log(x) {\n" + + " document.getElementById('log').value += x + '\\n';\n" + + " }\n" + + " </script>\n" + + "</head>\n" + + "<body onload='test()'>\n" + + " <textarea id='log' cols='80' rows='40'></textarea>\n" + + "</body>\n" + + "</html>"; + 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", "1 yes", "2 yes"}, + IE = {}) + public void thenTwiceAsync() throws Exception { + final String html = "<html>\n" + + "<head>\n" + + " <script>\n" + + " function test() {\n" + + " if (window.Promise) {\n" + + " var p = new Promise(function(resolve, reject) {\n" + + " window.setTimeout( function() {\n" + + " resolve('yes');\n" + + " }, 20);\n" + + " })\n" + + "\n" + + " p.then(function(value) {\n" + + " log('1 ' + value);\n" + + " })\n" + + " p.then(function(value) {\n" + + " log('2 ' + value);\n" + + " })\n" + + " log('done');\n" + + " }\n" + + " }\n" + + "\n" + + " function log(x) {\n" + + " document.getElementById('log').value += x + '\\n';\n" + + " }\n" + + " </script>\n" + + "</head>\n" + + "<body onload='test()'>\n" + + " <textarea id='log' cols='80' rows='40'></textarea>\n" + + "</body>\n" + + "</html>"; + 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 = {"Success", "string", "oh, no!", "after catch"}, IE = {}) public void catchTest() throws Exception { |