Commit 0eef5a9e authored by Evan W. Patton's avatar Evan W. Patton Committed by Jeffrey Schiller

Initialize polygons loaded at runtime

Change-Id: I708b6f4f2d602ed227a1a6343461ee60273b40f8
parent 0d3364ee
...@@ -233,6 +233,7 @@ ...@@ -233,6 +233,7 @@
<path id="libsForAndroidRuntimeTests.path"> <path id="libsForAndroidRuntimeTests.path">
<pathelement location="${public.build.dir}/AndroidRuntime.jar" /> <pathelement location="${public.build.dir}/AndroidRuntime.jar" />
<pathelement location="${build.dir}/common/CommonTestUtils.jar" />
<path refid="AndroidRuntime.path" /> <path refid="AndroidRuntime.path" />
<pathelement location="${lib.dir}/junit/junit-4.8.2.jar" /> <pathelement location="${lib.dir}/junit/junit-4.8.2.jar" />
<pathelement location="${lib.dir}/junit4/tl4j-junit4-1.1.3.jar" /> <pathelement location="${lib.dir}/junit4/tl4j-junit4-1.1.3.jar" />
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
package com.google.appinventor.components.runtime; package com.google.appinventor.components.runtime;
import android.support.annotation.VisibleForTesting;
import android.text.TextUtils; import android.text.TextUtils;
import android.util.Log; import android.util.Log;
import com.google.appinventor.components.annotations.DesignerComponent; import com.google.appinventor.components.annotations.DesignerComponent;
...@@ -299,4 +300,9 @@ public class Polygon extends PolygonBase implements MapPolygon { ...@@ -299,4 +300,9 @@ public class Polygon extends PolygonBase implements MapPolygon {
this.holePoints.addAll(points); this.holePoints.addAll(points);
clearGeometry(); clearGeometry();
} }
@VisibleForTesting
boolean isInitialized() {
return initialized;
}
} }
...@@ -249,8 +249,8 @@ public final class GeoJSONUtil { ...@@ -249,8 +249,8 @@ public final class GeoJSONUtil {
} }
} }
public static Object processGeoJSONFeature(final String logTag, final MapFactory.MapFeatureContainer container, public static MapFactory.MapFeature processGeoJSONFeature(final String logTag,
final YailList descriptions) { final MapFactory.MapFeatureContainer container, final YailList descriptions) {
String type = null; String type = null;
YailList geometry = null; YailList geometry = null;
YailList properties = null; YailList properties = null;
...@@ -347,6 +347,7 @@ public final class GeoJSONUtil { ...@@ -347,6 +347,7 @@ public final class GeoJSONUtil {
if (i.hasNext()) { if (i.hasNext()) {
polygon.HolePoints(YailList.makeList(swapNestedCoordinates((LList) ((Pair)coordinates.getCdr()).getCdr()))); polygon.HolePoints(YailList.makeList(swapNestedCoordinates((LList) ((Pair)coordinates.getCdr()).getCdr())));
} }
polygon.Initialize();
return polygon; return polygon;
} }
...@@ -364,6 +365,7 @@ public final class GeoJSONUtil { ...@@ -364,6 +365,7 @@ public final class GeoJSONUtil {
} }
polygon.Points(YailList.makeList(points)); polygon.Points(YailList.makeList(points));
polygon.HolePoints(YailList.makeList(holePoints)); polygon.HolePoints(YailList.makeList(holePoints));
polygon.Initialize();
return polygon; return polygon;
} }
......
{"type":"FeatureCollection","features":[
{"type":"Feature","id":"USA-CT","properties":{"fips":"09","name":"Connecticut","Title":"Connecticut","Description":"this is a state"},"geometry":{"type":"Polygon","coordinates":[[[-73.053528,42.039048],[-71.799309,42.022617],[-71.799309,42.006186],[-71.799309,41.414677],[-71.859555,41.321569],[-71.947186,41.338],[-72.385341,41.261322],[-72.905651,41.28323],[-73.130205,41.146307],[-73.371191,41.102491],[-73.655992,40.987475],[-73.727192,41.102491],[-73.48073,41.21203],[-73.55193,41.294184],[-73.486206,42.050002],[-73.053528,42.039048]]]}}
,{"type":"Feature","id":"USA-MA","properties":{"fips":"25","name":"Massachusetts","Title":"Massachusetts"},"geometry":{"type":"Polygon","coordinates":[[[-70.917521,42.887974],[-70.818936,42.871543],[-70.780598,42.696281],[-70.824413,42.55388],[-70.983245,42.422434],[-70.988722,42.269079],[-70.769644,42.247172],[-70.638197,42.08834],[-70.660105,41.962371],[-70.550566,41.929509],[-70.539613,41.814493],[-70.260289,41.715908],[-69.937149,41.809016],[-70.008349,41.672093],[-70.484843,41.5516],[-70.660105,41.546123],[-70.764167,41.639231],[-70.928475,41.611847],[-70.933952,41.540646],[-71.120168,41.496831],[-71.196845,41.67757],[-71.22423,41.710431],[-71.328292,41.781632],[-71.383061,42.01714],[-71.530939,42.01714],[-71.799309,42.006186],[-71.799309,42.022617],[-73.053528,42.039048],[-73.486206,42.050002],[-73.508114,42.08834],[-73.267129,42.745573],[-72.456542,42.729142],[-71.29543,42.696281],[-71.185891,42.789389],[-70.917521,42.887974]]]}}
,{"type":"Feature","id":"USA-NH","properties":{"fips":"33","name":"New Hampshire","Title":"New Hampshire"},"geometry":{"type":"Polygon","coordinates":[[[-71.08183,45.303304],[-71.032537,44.657025],[-70.966814,43.34256],[-70.807983,43.227544],[-70.824413,43.128959],[-70.703921,43.057759],[-70.818936,42.871543],[-70.917521,42.887974],[-71.185891,42.789389],[-71.29543,42.696281],[-72.456542,42.729142],[-72.544173,42.80582],[-72.533219,42.953697],[-72.445588,43.008466],[-72.456542,43.150867],[-72.379864,43.572591],[-72.204602,43.769761],[-72.116971,43.994316],[-72.02934,44.07647],[-72.034817,44.322932],[-71.700724,44.41604],[-71.536416,44.585825],[-71.629524,44.750133],[-71.4926,44.914442],[-71.503554,45.013027],[-71.361154,45.270443],[-71.131122,45.243058],[-71.08183,45.303304]]]}}
,{"type":"Feature","id":"USA-RI","properties":{"fips":"44","name":"Rhode Island","Title":"Rhode Island"},"geometry":{"type":"MultiPolygon","coordinates":[[[[-71.196845,41.67757],[-71.120168,41.496831],[-71.317338,41.474923],[-71.196845,41.67757]]],[[[-71.530939,42.01714],[-71.383061,42.01714],[-71.328292,41.781632],[-71.22423,41.710431],[-71.344723,41.726862],[-71.448785,41.578985],[-71.481646,41.370861],[-71.859555,41.321569],[-71.799309,41.414677],[-71.799309,42.006186],[-71.530939,42.01714]]]]}}
,{"type":"Feature","id":"USA-VT","properties":{"fips":"50","name":"Vermont","Title":"Vermont"},"geometry":{"type":"Polygon","coordinates":[[[-71.503554,45.013027],[-71.4926,44.914442],[-71.629524,44.750133],[-71.536416,44.585825],[-71.700724,44.41604],[-72.034817,44.322932],[-72.02934,44.07647],[-72.116971,43.994316],[-72.204602,43.769761],[-72.379864,43.572591],[-72.456542,43.150867],[-72.445588,43.008466],[-72.533219,42.953697],[-72.544173,42.80582],[-72.456542,42.729142],[-73.267129,42.745573],[-73.278083,42.833204],[-73.245221,43.523299],[-73.404052,43.687607],[-73.349283,43.769761],[-73.436914,44.043608],[-73.321898,44.246255],[-73.294514,44.437948],[-73.387622,44.618687],[-73.332852,44.804903],[-73.343806,45.013027],[-72.308664,45.002073],[-71.503554,45.013027]]]}}
,{"type":"Feature","id":"USA-ME","properties":{"fips":"23","name":"Maine","Title":"Maine"},"geometry":{"type":"Polygon","coordinates":[[[-70.703921,43.057759],[-70.824413,43.128959],[-70.807983,43.227544],[-70.966814,43.34256],[-71.032537,44.657025],[-71.08183,45.303304],[-70.649151,45.440228],[-70.720352,45.511428],[-70.556043,45.664782],[-70.386258,45.735983],[-70.41912,45.796229],[-70.260289,45.889337],[-70.309581,46.064599],[-70.210996,46.327492],[-70.057642,46.415123],[-69.997395,46.694447],[-69.225147,47.461219],[-69.044408,47.428357],[-69.033454,47.242141],[-68.902007,47.176418],[-68.578868,47.285957],[-68.376221,47.285957],[-68.233821,47.357157],[-67.954497,47.198326],[-67.790188,47.066879],[-67.779235,45.944106],[-67.801142,45.675736],[-67.456095,45.604536],[-67.505388,45.48952],[-67.417757,45.379982],[-67.488957,45.281397],[-67.346556,45.128042],[-67.16034,45.160904],[-66.979601,44.804903],[-67.187725,44.646072],[-67.308218,44.706318],[-67.406803,44.596779],[-67.549203,44.624164],[-67.565634,44.531056],[-67.75185,44.54201],[-68.047605,44.328409],[-68.118805,44.476286],[-68.222867,44.48724],[-68.173574,44.328409],[-68.403606,44.251732],[-68.458375,44.377701],[-68.567914,44.311978],[-68.82533,44.311978],[-68.830807,44.459856],[-68.984161,44.426994],[-68.956777,44.322932],[-69.099177,44.103854],[-69.071793,44.043608],[-69.258008,43.923115],[-69.444224,43.966931],[-69.553763,43.840961],[-69.707118,43.82453],[-69.833087,43.720469],[-69.986442,43.742376],[-70.030257,43.851915],[-70.254812,43.676653],[-70.194565,43.567114],[-70.358873,43.528776],[-70.369827,43.435668],[-70.556043,43.320652],[-70.703921,43.057759]]]}}
]}
\ No newline at end of file
...@@ -9,6 +9,7 @@ import android.content.Context; ...@@ -9,6 +9,7 @@ import android.content.Context;
import android.hardware.Sensor; import android.hardware.Sensor;
import android.view.View; import android.view.View;
import android.widget.RelativeLayout; import android.widget.RelativeLayout;
import com.google.appinventor.common.testutils.TestUtils;
import com.google.appinventor.components.runtime.shadows.ShadowAsynchUtil; import com.google.appinventor.components.runtime.shadows.ShadowAsynchUtil;
import com.google.appinventor.components.runtime.shadows.ShadowEventDispatcher; import com.google.appinventor.components.runtime.shadows.ShadowEventDispatcher;
import com.google.appinventor.components.runtime.util.ErrorMessages; import com.google.appinventor.components.runtime.util.ErrorMessages;
...@@ -20,11 +21,15 @@ import org.junit.Test; ...@@ -20,11 +21,15 @@ import org.junit.Test;
import org.osmdroid.util.GeoPoint; import org.osmdroid.util.GeoPoint;
import org.osmdroid.views.MapView; import org.osmdroid.views.MapView;
import org.robolectric.RuntimeEnvironment; import org.robolectric.RuntimeEnvironment;
import org.robolectric.annotation.Config;
import org.robolectric.shadow.api.Shadow; import org.robolectric.shadow.api.Shadow;
import org.robolectric.shadows.ShadowSensorManager; import org.robolectric.shadows.ShadowSensorManager;
import org.robolectric.shadows.ShadowView; import org.robolectric.shadows.ShadowView;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.Collections; import java.util.Collections;
import static com.google.appinventor.components.runtime.shadows.ShadowEventDispatcher.assertErrorOccurred; import static com.google.appinventor.components.runtime.shadows.ShadowEventDispatcher.assertErrorOccurred;
...@@ -43,6 +48,7 @@ import static org.junit.Assert.assertTrue; ...@@ -43,6 +48,7 @@ import static org.junit.Assert.assertTrue;
* *
* @author ewpatton@mit.edu (Evan W. Patton) * @author ewpatton@mit.edu (Evan W. Patton)
*/ */
@Config(shadows = ShadowAsynchUtil.class)
public class MapTest extends MapTestBase { public class MapTest extends MapTestBase {
private Map map; private Map map;
...@@ -391,6 +397,22 @@ public class MapTest extends MapTestBase { ...@@ -391,6 +397,22 @@ public class MapTest extends MapTestBase {
assertEquals(defaultFeatureListSize, map.getController().getOverlayCount()); assertEquals(defaultFeatureListSize, map.getController().getOverlayCount());
} }
@Test
public void testLoadFromURL() throws MalformedURLException {
ShadowEventDispatcher.doNotHandleEvent(map, "GotFeatures");
String target = TestUtils.APP_INVENTOR_ROOT_DIR + "/components/tests/assets/com.google.appinventor.components.runtime.test/usa-new-england.geojson".replace('/', File.separatorChar);
map.LoadFromURL(new File(target).toURI().toURL().toString());
ShadowAsynchUtil.runAllPendingRunnables();
runAllEvents();
assertEventFiredAny(map, "GotFeatures");
assertEquals(6, map.Features().size());
// Test that the Polygons have been initialized, otherwise they won't draw.
for (int i = 0; i < map.Features().size(); i++) {
assertTrue(((Polygon)map.Features().getObject(i)).isInitialized());
}
}
private MapView getMapView() { private MapView getMapView() {
RelativeLayout layout = (RelativeLayout) map.getView(); RelativeLayout layout = (RelativeLayout) map.getView();
return (MapView) layout.getChildAt(0); return (MapView) layout.getChildAt(0);
......
...@@ -34,8 +34,26 @@ public class ShadowEventDispatcher { ...@@ -34,8 +34,26 @@ public class ShadowEventDispatcher {
private static Map<Component, Set<EventWithArgs>> firedEvents = new HashMap<>(); private static Map<Component, Set<EventWithArgs>> firedEvents = new HashMap<>();
private static Map<Component, Set<String>> unhandledEvents = new HashMap<>();
public static void clearEvents() { public static void clearEvents() {
firedEvents.clear(); firedEvents.clear();
unhandledEvents.clear();
}
/**
* Registers a (component, eventName) pair that the EventDispatcher should report as not having
* an event handler defined. This can be used to test default handling behavior for those events
* that may do alternative handling if the developer has not provided blocks to handle the
* event.
* @param component the component to watch
* @param eventName the event to report as not handled
*/
public static void doNotHandleEvent(Component component, String eventName) {
if (!unhandledEvents.containsKey(component)) {
unhandledEvents.put(component, new HashSet<String>());
}
unhandledEvents.get(component).add(eventName);
} }
@Implementation @Implementation
...@@ -44,7 +62,7 @@ public class ShadowEventDispatcher { ...@@ -44,7 +62,7 @@ public class ShadowEventDispatcher {
firedEvents.put(component, new HashSet<EventWithArgs>()); firedEvents.put(component, new HashSet<EventWithArgs>());
} }
firedEvents.get(component).add(new EventWithArgs(eventName, args)); firedEvents.get(component).add(new EventWithArgs(eventName, args));
return true; return !unhandledEvents.containsKey(component) || !unhandledEvents.get(component).contains(eventName);
} }
public static void assertEventFired(Component component, String eventName, Object... args) { public static void assertEventFired(Component component, String eventName, Object... args) {
...@@ -130,4 +148,25 @@ public class ShadowEventDispatcher { ...@@ -130,4 +148,25 @@ public class ShadowEventDispatcher {
} }
throw new AssertionError(String.format("Form did not receive PermissionDenied event for permission %s.", permission)); throw new AssertionError(String.format("Form did not receive PermissionDenied event for permission %s.", permission));
} }
/**
* Retrieves the arguments passed when an event was dispatched. This can be used to perform
* further assertions on the event data.
*
* @param component The component that raised the event
* @param eventName The name of the event raised
* @return An array of arguments passed for the event.
* @throws AssertionError if the specified event has not occurred for the given component
*/
public static Object[] getArgumentsForEventFired(Component component, String eventName) {
Set<EventWithArgs> events = firedEvents.get(component);
if (events != null) {
for (EventWithArgs e : events) {
if (e.eventName.equals(eventName)) {
return e.args;
}
}
}
throw new AssertionError(String.format("Component %s did not receive event %s.", component, eventName));
}
} }
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment