/* * Copyright 2014 Google Inc. All rights reserved. * * 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. */ package com.google.samples.apps.iosched.ui.debug.actions; import android.content.Context; import android.os.AsyncTask; import com.google.samples.apps.iosched.model.ScheduleItem; import com.google.samples.apps.iosched.model.ScheduleItemHelper; import com.google.samples.apps.iosched.ui.debug.DebugAction; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Locale; /** * A DebugAction that tests a few cases of schedule conflicts. */ public class TestScheduleHelperAction implements DebugAction { StringBuilder out = new StringBuilder(); @Override public void run(final Context context, final Callback callback) { new AsyncTask<Context, Void, Boolean>() { @Override protected Boolean doInBackground(Context... contexts) { return startTest(); } @Override protected void onPostExecute(Boolean success) { callback.done(success, out.toString()); } }.execute(context); } @Override public String getLabel() { return "Test scheduler conflict handling"; } public Boolean startTest() { boolean success = true; ArrayList<ScheduleItem> mut = new ArrayList<ScheduleItem>(); ArrayList<ScheduleItem> immut = new ArrayList<ScheduleItem>(); mut.add(item("14:00", "14:30", "m1")); immut.add(item("14:25", "14:50", "i1")); success &= check("no intersection - within range", ScheduleItemHelper.processItems(mut, immut), new ScheduleItem[]{item("14:00", "14:30", "m1"), item("14:25", "14:50", "i1")}); mut.clear(); immut.clear(); mut.add(item("14:00", "16:00", "m1")); immut.add(item("15:00", "16:00", "i1")); success &= check("Simple intersection1", ScheduleItemHelper.processItems(mut, immut), new ScheduleItem[]{item("14:00", "15:00", "m1"), item("15:00", "16:00", "i1")}); mut.clear(); immut.clear(); mut.add(item("14:00", "16:00", "m1")); immut.add(item("13:00", "15:00", "i1")); success &= check("Simple intersection2", ScheduleItemHelper.processItems(mut, immut), new ScheduleItem[]{item("13:00", "15:00", "i1"), item("15:00", "16:00", "m1")}); mut.clear(); immut.clear(); mut.add(item("14:00", "16:00", "m1")); immut.add(item("14:00", "16:00", "i1")); success &= check("same time", ScheduleItemHelper.processItems(mut, immut), new ScheduleItem[]{item("14:00", "16:00", "i1")}); mut.clear(); immut.clear(); mut.add(item("14:00", "16:09", "m1")); immut.add(item("14:05", "16:00", "i1")); success &= check("no split, remaining not big enough", ScheduleItemHelper.processItems(mut, immut), new ScheduleItem[]{item("14:05", "16:00", "i1")}); mut.clear(); immut.clear(); mut.add(item("14:00", "16:10", "m1")); immut.add(item("14:00", "16:00", "i1")); success &= check("split", ScheduleItemHelper.processItems(mut, immut), new ScheduleItem[]{item("14:00", "16:00", "i1"), item("16:00", "16:10", "m1")}); mut.clear(); immut.clear(); mut.add(item("14:00", "17:00", "m1")); immut.add(item("14:30", "15:00", "i1")); immut.add(item("15:30", "16:00", "i2")); success &= check("2 splits", ScheduleItemHelper.processItems(mut, immut), new ScheduleItem[]{ item("14:00", "14:30", "m1"), item("14:30", "15:00", "i1"), item("15:00", "15:30", "m1"), item("15:30", "16:00", "i2"), item("16:00", "17:00", "m1"), }); mut.clear(); immut.clear(); mut.add(item("14:00", "17:00", "m1")); immut.add(item("14:30", "15:00", "i1")); immut.add(item("16:30", "16:51", "i2")); success &= check("2 splits with no remaining", ScheduleItemHelper.processItems(mut, immut), new ScheduleItem[]{ item("14:00", "14:30", "m1"), item("14:30", "15:00", "i1"), item("15:00", "16:30", "m1"), item("16:30", "16:51", "i2"), }); mut.clear(); immut.clear(); mut.add(item("12:00", "15:00", "m1")); mut.add(item("15:00", "17:00", "m2")); mut.add(item("17:00", "17:40", "m3")); immut.add(item("14:30", "15:00", "i1")); immut.add(item("16:30", "16:51", "i2")); success &= check("2 splits, 3 free blocks, no remaining", ScheduleItemHelper.processItems(mut, immut), new ScheduleItem[]{ item("12:00", "14:30", "m1"), item("14:30", "15:00", "i1"), item("15:00", "16:30", "m2"), item("16:30", "16:51", "i2"), item("17:00", "17:40", "m3"), }); mut.clear(); immut.clear(); mut.add(item("12:00", "15:00", "m1")); mut.add(item("15:00", "17:00", "m2")); mut.add(item("17:00", "17:40", "m3")); immut.add(item("14:30", "15:00", "i1")); immut.add(item("16:30", "16:51", "i2")); immut.add(item("16:30", "16:40", "i3")); success &= check("conflicting sessions, 2 splits, 3 free blocks, no remaining", ScheduleItemHelper.processItems(mut, immut), new ScheduleItem[]{ item("12:00", "14:30", "m1"), item("14:30", "15:00", "i1"), item("15:00", "16:30", "m2"), item("16:30", "16:51", "i2"), item("16:30", "16:40", "i3", true), item("17:00", "17:40", "m3"), }); mut.clear(); immut.clear(); mut.add(item("12:00", "15:00", "m1")); mut.add(item("15:00", "17:00", "m2")); mut.add(item("17:00", "17:40", "m3")); immut.add(item("14:30", "15:00", "i1")); immut.add(item("16:30", "16:51", "i2")); immut.add(item("16:50", "17:00", "i3")); success &= check("borderline conflicting sessions, 2 splits, 3 free blocks, no remaining", ScheduleItemHelper.processItems(mut, immut), new ScheduleItem[]{ item("12:00", "14:30", "m1"), item("14:30", "15:00", "i1"), item("15:00", "16:30", "m2"), item("16:30", "16:51", "i2"), item("16:50", "17:00", "i3"), item("17:00", "17:40", "m3"), }); mut.clear(); immut.clear(); immut.add(item("14:30", "15:00", "i1")); immut.add(item("16:30", "19:00", "i2")); immut.add(item("16:30", "17:00", "i3")); immut.add(item("18:00", "18:30", "i4")); success &= check("conflicting sessions", ScheduleItemHelper.processItems(mut, immut), new ScheduleItem[]{ item("14:30", "15:00", "i1"), item("16:30", "19:00", "i2"), item("16:30", "17:00", "i3", true), item("18:00", "18:30", "i4", true), }); return success; } private boolean check(String testDescription, ArrayList<ScheduleItem> actual, ScheduleItem[] expected) { out.append("testing " + testDescription + "..."); boolean equal = true; if (actual.size() != expected.length ) { equal = false; } else { int i=0; for (ScheduleItem item: actual) { if (!item.title.equals(expected[i].title) || item.startTime != expected[i].startTime || item.endTime != expected[i].endTime || ( item.flags&ScheduleItem.FLAG_CONFLICTS_WITH_PREVIOUS) != (expected[i].flags&ScheduleItem.FLAG_CONFLICTS_WITH_PREVIOUS)) { equal = false; break; } i++; } } if (!equal) { out.append("ERROR!:\n"); out.append(" expected\n"); for (ScheduleItem item: expected) { out.append(" " + format(item) + "\n"); } out.append(" actual\n"); for (ScheduleItem item: actual) { out.append(" " + format(item) + "\n"); } } else { out.append("OK\n"); } return equal; } private SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US); private String format(ScheduleItem item) { return item.title + " " + timeStr(item.startTime) + "-" + timeStr(item.endTime) + ((item.flags&ScheduleItem.FLAG_CONFLICTS_WITH_PREVIOUS ) > 0 ? " conflict":""); } private String timeStr(long time) { Date d = new Date(time); return d.getHours()+":"+d.getMinutes(); } private long date(String hourMinute) { try { return sdf.parse("2014-06-25 " + hourMinute + ":00").getTime(); } catch (ParseException ex) { throw new RuntimeException(ex); } } private ScheduleItem item(String start, String end, String id) { return item(start, end, id, false); } private ScheduleItem item(String start, String end, String id, int type) { return item(start, end, id, false, type); } private ScheduleItem item(String start, String end, String id, boolean conflict) { return item(start, end, id, conflict, ScheduleItem.SESSION); } private ScheduleItem item(String start, String end, String id, boolean conflict, int type) { ScheduleItem i = new ScheduleItem(); i.title = id; i.startTime = date(start); i.endTime = date(end); i.type = type; if (conflict) i.flags = ScheduleItem.FLAG_CONFLICTS_WITH_PREVIOUS; return i; } }