2012年3月25日日曜日

JavaFX + JUnit で javascriptのunit testできるようにしてやるんで、これからハマっていってやんよ - 3

ども。

あいかわらず、ハマっています。

現状のコード


かなりひどいことになっています。

package org.mikeneck.jfx.jsjunit.client;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.concurrent.Worker;
import javafx.scene.web.WebEngine;
import javafx.stage.Stage;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
/**
* Copyright mike_neck (mike@mikeneck.org) 2012 -
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class Browser extends Application {
private static Map<String, Browser> browsers = new HashMap<String, Browser>();
private String url;
private String identifier;
private WebEngine engine;
@Override
public void start(Stage stage) throws Exception {
this.engine = new WebEngine();
saveInstance();
startBrowser();
}
private void saveInstance() {
Parameters parameters = getParameters();
List<String> raw = parameters.getRaw();
browsers.put(raw.get(0), this);
this.identifier = raw.get(0);
this.url = raw.get(1);
}
public static Browser getInstance(String identifier) {
return browsers.get(identifier);
}
public static boolean shouldWait(String identifier) {
return browsers.containsKey(identifier) == false;
}
private void startBrowser() throws InterruptedException {
final BlockingQueue<Worker.State> queue = new LinkedBlockingQueue<Worker.State>();
final BlockingQueue<Class<Void>> voids = new LinkedBlockingQueue<Class<Void>>();
Platform.runLater(
new Runnable() {
@Override
public void run() {
engine.load(url);
try {
voids.put(Void.TYPE);
} catch (InterruptedException e) {
}
}
}
);
voids.take();
Platform.runLater(
new Runnable() {
@Override
public void run() {
try {
queue.put(loadedText());
} catch (InterruptedException e) {
}
}
private Worker.State loadedText() {
Worker<Void> worker = engine.getLoadWorker();
Worker.State state = worker.getState();
while (state.equals(Worker.State.SUCCEEDED) == false) {
worker = engine.getLoadWorker();
state = worker.getState();
System.out.println(state);
}
return state;
}
}
);
queue.take();
}
public void prepareTest () throws InterruptedException {
final BlockingQueue<Worker.State> queue = new LinkedBlockingQueue<Worker.State>();
final BlockingQueue<Class<Void>> voids = new LinkedBlockingQueue<Class<Void>>();
Platform.runLater(
new Runnable() {
@Override
public void run() {
engine.load(url);
try {
voids.put(Void.TYPE);
} catch (InterruptedException e) {
}
}
}
);
voids.take();
Platform.runLater(
new Runnable() {
@Override
public void run() {
try {
queue.put(loadedText());
} catch (InterruptedException e) {
}
}
private Worker.State loadedText() {
Worker<Void> worker = engine.getLoadWorker();
Worker.State state = worker.getState();
while (state.equals(Worker.State.SUCCEEDED) == false) {
worker = engine.getLoadWorker();
state = worker.getState();
System.out.println(state);
}
return state;
}
}
);
Worker.State state = queue.take();
System.out.println("Browser loaded in state : " + state.name());
}
public <T> T runScript(String script, Class<T> expectedClass) throws InterruptedException {
final BlockingQueue<String> queue = new LinkedBlockingQueue<String>();
queue.put(script);
final BlockingQueue<Object> result = new LinkedBlockingQueue<Object>();
Platform.runLater(
new Runnable() {
@Override
public void run() {
try {
String runScript = queue.take();
System.out.println(runScript);
Object object = engine.executeScript(runScript);
result.put(object);
} catch (InterruptedException e) {
}
}
}
);
Object object = result.take();
return expectedClass.cast(object);
}
public void shutDown () {
Platform.runLater(
new Runnable() {
@Override
public void run() {
Platform.exit();
browsers.remove(identifier);
}
}
);
}
}
view raw Browser.java hosted with ❤ by GitHub


package org.mikeneck.jfx.jsjunit;
import javafx.application.Application;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.mikeneck.jfx.jsjunit.client.Browser;
import org.mikeneck.jfx.jsjunit.server.WebServer;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;
/**
* Copyright mike_neck (mike@mikeneck.org) 2012 -
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
public class JsUnitTest {
private static final String TEST_NAME = "JsUnitTest";
static WebServer server;
static Browser browser;
private static ExecutorService service;
@BeforeClass
public static void serverStart() throws Exception {
server = new WebServer();
server.start();
service = Executors.newFixedThreadPool(1);
service.submit(
new Runnable() {
@Override
public void run() {
Application.launch(Browser.class, TEST_NAME, "http://localhost:3080");
}
}
);
while (Browser.shouldWait(TEST_NAME)) {
try {
System.out.println(Browser.shouldWait(TEST_NAME));
Thread.sleep(100);
} catch (InterruptedException e) {
}
}
}
@Before
public void setUp () throws InterruptedException {
browser = Browser.getInstance(TEST_NAME);
System.out.println("setUp");
browser.prepareTest();
System.out.println("setUp end");
}
@Test
public void doNumberTest() throws InterruptedException {
assertThat(browser.runScript("numberTest(1)", Integer.class), is(2));
}
@AfterClass
public static void shutdownServer () throws Exception {
browser.shutDown();
server.stop();
server.destroy();
}
}
view raw JsUnitTest.java hosted with ❤ by GitHub


とにかく、ページをロードした時の同期を図るのがかなりしんどいです。

JUnit / JavaFX / WebView 3つのスレッドを管理しないといけないので、

これがかなりきつい。

ExecutorServiceを使うといいのでは?

と、java-ja温泉でよしおりさんに教えてもらったので、

改善していこうと思います。


0 件のコメント:

コメントを投稿