package vandy.mooc.tests; import android.test.AndroidTestCase; import junit.framework.Assert; import vandy.mooc.model.aidl.WeatherData; import vandy.mooc.model.aidl.WeatherDataJsonParser; import java.io.ByteArrayInputStream; import java.io.InputStream; import java.util.List; /** * Test case for testing the WeatherDataJsonParser class methods. * The data member validation is only performed on the subset of * data members that the skeleton application actually uses. For * clarity, all data members required by the skeleton are marked * with a "required" comment. * <p/> * These tests have broken the data into strings that could be * used to test each of the individual methods in the parser. * However, student implementations may vary in terms of the * state of the JsonReader that is passed to each of these * functions which will likely make function specific testing * fail. For example, some students may decide to call * reader.beginArray() and reader.endArray() outside * the scope of an array parsing function, while others may * call these functions inside the function. * <p/> * NOTE: If any student implementation uses more than this the * minimum number of data members required by the skeleton, these * values will not be tested by this test case. */ public class TestWeatherDataJsonParser extends AndroidTestCase { /** * Sys data */ public static final String mSysData = "\"sys\": {" + "\"message\": 0.0138," + "\"country\": \"United States of America\"," /* required */ + "\"sunrise\": 1431427373," /* required */ + "\"sunset\": 1431477841" /* required */ + "}"; /** * Weathers data (only 1 list entry). */ public static final String mWeathersData = "\"weather\": [{" + "\"id\": 802," /* required */ + "\"main\": \"Clouds\"," /* parcelized but not used */ + "\"description\": \"scattered clouds\"," /* required */ + "\"icon\": \"03d\"" /* parcelized but not used */ + "}]"; /** * Main data. */ public static final String mMainData = "\"main\": {" + "\"temp\": 289.847," /* required */ + "\"temp_min\": 289.847," + "\"temp_max\": 289.847," + "\"pressure\": 1010.71," /* parcelized but not used */ + "\"sea_level\": 1035.76," + "\"grnd_level\": 1010.71," + "\"humidity\": 76" + "}"; /* required */ /** * Wind data. */ public static final String mWindData = "\"wind\": {" + "\"speed\": 2.42," /* required */ + "\"deg\": 310.002" /* required */ + "}"; /* * Weather Data (with string replacement stubs for subclasses). */ public static final String mData = "{" + "\"coord\": { \"lon\": -86.78, \"lat\": 36.17 }," + "_SYS_DATA" + "," + "_WEATHER_DATA" + "," + "\"base\": \"stations\"," + "_MAIN_DATA" + "," + "_WIND_DATA" + "," + "\"clouds\": {" + "\"all\": 36" + "}," + "\"dt\": 1431435983," /* parcelized but not used */ + "\"id\": 4644585," + "\"name\": \"Nashville\"," /* required */ + "\"cod\": 200" /* parcelized but not used */ + "}"; /* * Weather Data error response. */ public static final String mErrorData = "{" + "\"cod\": 404," /* required */ + "\"message\": \"Error: Not found city\"" /* required */ + "}"; /** * Test case runner for testing the * WeatherDataJsonParser class methods. * * @throws Throwable */ public void testParseJSONStream() throws Throwable { // Build the input string to mock the JSON output // from openweathermap.org. String data = buildJSONData(); // Convert JSON string to an InputStream. InputStream inputStream = new ByteArrayInputStream(data.getBytes()); // Test the WeatherDataJsonParser main entry point. WeatherDataJsonParser parser = new WeatherDataJsonParser(); try { // Test the parser. List<WeatherData> weatherDataList = parser.parseJsonStream(inputStream); // Now verify the results from the parser. validateWeatherDataList(weatherDataList); } catch (Exception e) { fail("Unable to parse weather data: " + e); } } public void testParseJsonErrorStream() throws Throwable { // Build the input string to mock the Json output // from openweathermap.org. String data = buildJsonErrorData(); // Convert Json string to an InputStream. InputStream inputStream = new ByteArrayInputStream(data.getBytes()); // Test the WeatherDataJsonParser main entry point. WeatherDataJsonParser parser = new WeatherDataJsonParser(); try { // Test the parser. List<WeatherData> weatherDataList = parser.parseJsonStream(inputStream); // Now verify the results from the parser. validateErrorData(weatherDataList); } catch (Exception e) { fail("Unable to parse weather data: " + e); } } public void validateWeatherDataList(List<WeatherData> weatherDataList) throws Throwable { Assert.assertNotNull(weatherDataList != null); Assert.assertNotNull(weatherDataList.size() == 1); WeatherData weatherData = weatherDataList.get(0); Assert.assertNotNull(weatherData); // Probably not necessary. // Validate weatherData members. validateData(weatherData); // Validate sys data values. validateSys(weatherData); // Validate weathers data values. validateWeathers(weatherData); // Validate main data values. validateMain(weatherData); // Validate wind data values. validateWind(weatherData); } public void validateErrorData(List<WeatherData> weatherDataList) { Assert.assertNotNull(weatherDataList != null); Assert.assertNotNull(weatherDataList.size() == 1); WeatherData weatherData = weatherDataList.get(0); Assert.assertNotNull(weatherData); Assert.assertEquals("getCod() is invalid", weatherData.getCod(), 404); Assert.assertEquals("getMessage() is invalid", weatherData.getMessage(), "Error: Not found city"); } public void validateData(WeatherData weatherData) { Assert.assertNotNull(weatherData); Assert.assertEquals("getName() is invalid", weatherData.getName(), "Nashville"); } public void validateWeathers(WeatherData weatherData) { Assert.assertNotNull(weatherData.getWeathers()); Assert.assertEquals("Expected 1 weathers array object", 1, weatherData.getWeathers().size()); Assert.assertEquals("getWeathers().get(0).getDescription() value is invalid", weatherData.getWeathers().get(0).getDescription(), "scattered clouds"); Assert.assertEquals("getWeathers().get(0).getId() value is invalid", weatherData.getWeathers().get(0).getId(), 802); } public void validateSys(WeatherData weatherData) { Assert.assertNotNull(weatherData.getSys()); Assert.assertEquals("getSys().getCountry() is invalid", weatherData.getSys().getCountry(), "United States of America"); Assert.assertEquals("getSys().getSunrise() is invalid", weatherData.getSys().getSunrise(), 1431427373); Assert.assertEquals("getSys().getSunset() is invalid", weatherData.getSys().getSunset(), 1431477841); } public void validateMain(WeatherData weatherData) { Assert.assertNotNull(weatherData.getMain()); Assert.assertEquals("getSys().getHumidity() is invalid", weatherData.getMain().getHumidity(), 76); Assert.assertEquals("getSys().getTemp() is invalid", weatherData.getMain().getTemp(), 289.847); } public void validateWind(WeatherData weatherData) { Assert.assertNotNull(weatherData.getWind()); Assert.assertEquals("getWind().getDeg() is invalid", weatherData.getWind().getDeg(), 310.002); Assert.assertEquals("getWind().getSpeed() is invalid", weatherData.getWind().getSpeed(), 2.42); } private String buildJSONData() { String data = new String(mData); data = data.replace("_SYS_DATA", mSysData); data = data.replace("_MAIN_DATA", mMainData); data = data.replace("_WEATHER_DATA", mWeathersData); data = data.replace("_WIND_DATA", mWindData); return data; } private String buildJsonErrorData() { return mErrorData; } }