IDEA-74652 Time tracking features. Basic implementation: per task time spent.

This commit is contained in:
Evgeny Zakrevsky
2012-11-08 23:38:31 +04:00
parent 80a3b8523a
commit bc3f525b2b
15 changed files with 326 additions and 42 deletions
@@ -654,6 +654,10 @@ public class UIUtil {
return isUnderGTKLookAndFeel() ? getTreeTextBackground() : UIManager.getColor("Table.background");
}
public static Color getTableBackground(final boolean isSelected) {
return isSelected ? getTableSelectionBackground() : getTableBackground();
}
public static Color getTableSelectionForeground() {
return UIManager.getColor("Table.selectionForeground");
}
@@ -662,6 +666,10 @@ public class UIUtil {
return UIManager.getColor("Table.foreground");
}
public static Color getTableForeground(final boolean isSelected) {
return isSelected ? getTableSelectionForeground() : getTableForeground();
}
public static Color getTableGridColor() {
return UIManager.getColor("Table.gridColor");
}
@@ -53,4 +53,12 @@ public abstract class LocalTask extends Task {
public boolean isClosedLocally() {
return getChangeLists().isEmpty();
}
public abstract long getTimeSpent();
public abstract void setTimeSpent(long time);
public abstract long getActivated();
public abstract void setActivated(long time);
}
@@ -22,5 +22,11 @@ import java.util.EventListener;
*/
public interface TaskListener extends EventListener {
void taskDeactivated(LocalTask task);
void taskActivated(LocalTask task);
void taskAdded(LocalTask task);
void taskRemoved(LocalTask task);
}
@@ -0,0 +1,23 @@
package com.intellij.tasks;
/**
* User: evgeny.zakrevsky
* Date: 11/8/12
*/
public class TaskListenerAdapter implements TaskListener {
@Override
public void taskDeactivated(final LocalTask task) {
}
@Override
public void taskActivated(final LocalTask task) {
}
@Override
public void taskAdded(final LocalTask task) {
}
@Override
public void taskRemoved(final LocalTask task) {
}
}
@@ -61,9 +61,9 @@ public abstract class TaskManager {
@Nullable
public abstract Task updateIssue(@NotNull String id);
public abstract LocalTask[] getLocalTasks();
public abstract List<LocalTask> getLocalTasks();
public abstract LocalTask[] getLocalTasks(final boolean withClosed);
public abstract List<LocalTask> getLocalTasks(final boolean withClosed);
public abstract LocalTask addTask(Task issue);
@@ -124,6 +124,10 @@
<tasks.repositoryType implementation="com.intellij.tasks.generic.assembla.AssemblaRepositoryType"/>
<checkinHandlerFactory implementation="com.intellij.tasks.impl.TaskCheckinHandlerFactory"/>
<toolWindow id="Tasks" anchor="right" secondary="false" icon="TasksIcons.Other"
factoryClass="com.intellij.tasks.timetracking.TasksToolWindowFactory"
conditionClass="com.intellij.tasks.timetracking.TasksToolWindowFactory"/>
</extensions>
</idea-plugin>
@@ -40,7 +40,6 @@ import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import java.awt.event.ActionEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
@@ -182,8 +181,8 @@ public class SwitchTaskAction extends BaseTaskAction {
final TaskManager manager = TaskManager.getManager(project);
LocalTask activeTask = manager.getActiveTask();
LocalTask[] localTasks = manager.getLocalTasks();
Arrays.sort(localTasks, TaskManagerImpl.TASK_UPDATE_COMPARATOR);
List<LocalTask> localTasks = manager.getLocalTasks();
Collections.sort(localTasks, TaskManagerImpl.TASK_UPDATE_COMPARATOR);
ArrayList<LocalTask> temp = new ArrayList<LocalTask>();
boolean vcsEnabled = manager.isVcsEnabled();
for (final LocalTask task : localTasks) {
@@ -90,7 +90,7 @@ public class LoadContextAction extends BaseTaskAction {
}
});
final TaskManager taskManager = TaskManager.getManager(project);
LocalTask[] tasks = taskManager.getLocalTasks();
List<LocalTask> tasks = taskManager.getLocalTasks();
infos.addAll(ContainerUtil.mapNotNull(tasks, new NullableFunction<LocalTask, ContextHolder>() {
public ContextHolder fun(final LocalTask task) {
if (task.isActive()) {
@@ -58,6 +58,8 @@ public class LocalTaskImpl extends LocalTask {
private boolean myActive;
private List<ChangeListInfo> myChangeLists = new ArrayList<ChangeListInfo>();
private long myTimeSpent = 0;
private long myActivated;
/** for serialization */
@@ -80,6 +82,7 @@ public class LocalTaskImpl extends LocalTask {
if (origin instanceof LocalTaskImpl) {
myChangeLists = ((LocalTaskImpl)origin).getChangeLists();
myActive = ((LocalTaskImpl)origin).isActive();
myTimeSpent = ((LocalTaskImpl)origin).getTimeSpent();
}
}
@@ -258,4 +261,23 @@ public class LocalTaskImpl extends LocalTask {
public String getCustomIcon() {
return myCustomIcon;
}
@Tag("timeSpent")
public long getTimeSpent() {
return myTimeSpent;
}
public void setTimeSpent(final long timeSpent) {
myTimeSpent = timeSpent;
}
@Override
public long getActivated() {
return myActivated;
}
@Override
public void setActivated(final long time) {
myActivated = time;
}
}
@@ -101,10 +101,10 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
private final Map<String, Task> myIssueCache = Collections.synchronizedMap(new LinkedHashMap<String, Task>());
private final Map<String, LocalTaskImpl> myTasks = Collections.synchronizedMap(new LinkedHashMap<String, LocalTaskImpl>() {
private final Map<String, LocalTask> myTasks = Collections.synchronizedMap(new LinkedHashMap<String, LocalTask>() {
@Override
public LocalTaskImpl put(String key, LocalTaskImpl task) {
LocalTaskImpl result = super.put(key, task);
public LocalTask put(String key, LocalTask task) {
LocalTask result = super.put(key, task);
if (size() > myConfig.taskHistoryLength) {
ArrayList<LocalTask> list = new ArrayList<LocalTask>(values());
Collections.sort(list, TASK_UPDATE_COMPARATOR);
@@ -131,6 +131,7 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
private final List<TaskRepository> myRepositories = new ArrayList<TaskRepository>();
private final EventDispatcher<TaskListener> myDispatcher = EventDispatcher.create(TaskListener.class);
private Set<TaskRepository> myBadRepositories = new ConcurrentHashSet<TaskRepository>();
private long myProjectOpenedTime;
public TaskManagerImpl(Project project,
WorkingContextManager contextManager,
@@ -158,6 +159,18 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
}
}
};
addTaskListener(new TaskListenerAdapter() {
@Override
public void taskDeactivated(final LocalTask task) {
task.setTimeSpent(task.getTimeSpent() + System.currentTimeMillis() - task.getActivated());
}
@Override
public void taskActivated(final LocalTask task) {
task.setActivated(System.currentTimeMillis());
}
});
}
@Override
@@ -200,6 +213,7 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
activateTask(myTasks.get(LocalTaskImpl.DEFAULT_TASK_ID), true, false);
}
myTasks.remove(task.getId());
myDispatcher.getMulticaster().taskRemoved(task);
myContextManager.removeContext(task);
}
@@ -277,7 +291,7 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
try {
Task issue = repository.findTask(id);
if (issue != null) {
LocalTaskImpl localTask = myTasks.get(id);
LocalTask localTask = myTasks.get(id);
if (localTask != null) {
localTask.updateFromIssue(issue);
return localTask;
@@ -293,20 +307,19 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
}
@Override
public LocalTaskImpl[] getLocalTasks() {
public List<LocalTask> getLocalTasks() {
return getLocalTasks(true);
}
@Override
public LocalTaskImpl[] getLocalTasks(final boolean withClosed) {
public List<LocalTask> getLocalTasks(final boolean withClosed) {
synchronized (myTasks) {
final List<LocalTaskImpl> filteredTasks = ContainerUtil.filter(myTasks.values(), new Condition<LocalTaskImpl>() {
return ContainerUtil.filter(myTasks.values(), new Condition<LocalTask>() {
@Override
public boolean value(final LocalTaskImpl task) {
public boolean value(final LocalTask task) {
return withClosed || !task.isClosedLocally();
}
});
return filteredTasks.toArray(new LocalTaskImpl[filteredTasks.size()]);
}
}
@@ -362,7 +375,6 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
private void saveActiveTask() {
myContextManager.saveContext(myActiveTask);
myActiveTask.setActive(false);
myActiveTask.setUpdated(new Date());
}
@@ -372,6 +384,7 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
task.setUpdated(new Date());
}
task.setActive(true);
myActiveTask.setActive(false);
addTask(task);
if (task.isIssue()) {
StartupManager.getInstance(myProject).runWhenProjectIsInitialized(new Runnable() {
@@ -385,9 +398,11 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
}
});
}
boolean isChanged = !task.equals(myActiveTask);
LocalTask oldActiveTask = myActiveTask;
boolean isChanged = !task.equals(oldActiveTask);
myActiveTask = task;
if (isChanged) {
myDispatcher.getMulticaster().taskDeactivated(oldActiveTask);
myDispatcher.getMulticaster().taskActivated(task);
}
return task;
@@ -395,6 +410,7 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
private void addTask(LocalTaskImpl task) {
myTasks.put(task.getId(), task);
myDispatcher.getMulticaster().taskAdded(task);
}
@Override
@@ -505,6 +521,7 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
if (activeTask != null) {
myActiveTask = activeTask;
myDispatcher.getMulticaster().taskActivated(activeTask);
}
}
@@ -557,6 +574,8 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
}
myContextManager.pack(200, 50);
myProjectOpenedTime = System.currentTimeMillis();
}
private TaskProjectConfiguration getProjectConfiguration() {
@@ -564,6 +583,7 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
}
public void projectClosed() {
getState().myTotallyTimeSpent += System.currentTimeMillis() - myProjectOpenedTime;
}
@NotNull
@@ -589,7 +609,7 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
});
}
LocalTaskImpl defaultTask = myTasks.get(LocalTaskImpl.DEFAULT_TASK_ID);
LocalTask defaultTask = myTasks.get(LocalTaskImpl.DEFAULT_TASK_ID);
if (defaultTask == null) {
defaultTask = createDefaultTask();
addTask(defaultTask);
@@ -603,7 +623,7 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
}
}
for (LocalTaskImpl localTask : getLocalTasks()) {
for (LocalTask localTask : getLocalTasks()) {
for (Iterator<ChangeListInfo> iterator = localTask.getChangeLists().iterator(); iterator.hasNext(); ) {
final ChangeListInfo changeListInfo = iterator.next();
if (myChangeListManager.getChangeList(changeListInfo.id) == null) {
@@ -612,9 +632,9 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
}
}
doActivate(myActiveTask, false);
myChangeListManager.addChangeListListener(myChangeListListener);
doActivate(myActiveTask, false);
}
private static LocalTaskImpl createDefaultTask() {
@@ -667,7 +687,7 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
}
// update local tasks
synchronized (myTasks) {
for (Map.Entry<String, LocalTaskImpl> entry : myTasks.entrySet()) {
for (Map.Entry<String, LocalTask> entry : myTasks.entrySet()) {
Task issue = myIssueCache.get(entry.getKey());
if (issue != null) {
entry.getValue().updateFromIssue(issue);
@@ -745,7 +765,7 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
@Nullable
@Override
public LocalTask getAssociatedTask(LocalChangeList list) {
for (LocalTaskImpl task : getLocalTasks()) {
for (LocalTask task : getLocalTasks()) {
for (ChangeListInfo changeListInfo : task.getChangeLists()) {
if (changeListInfo.id.equals(list.getId())) {
return task;
@@ -843,6 +863,8 @@ public class TaskManagerImpl extends TaskManager implements ProjectComponent, Pe
public boolean searchClosedTasks = false;
public long myTotallyTimeSpent = 0;
@Tag("servers")
public Element servers = new Element("servers");
}
@@ -0,0 +1,33 @@
package com.intellij.tasks.timetracking;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.Condition;
import com.intellij.openapi.wm.ToolWindow;
import com.intellij.openapi.wm.ToolWindowFactory;
import com.intellij.tasks.LocalTask;
import com.intellij.tasks.TaskManager;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentFactory;
import com.intellij.ui.content.ContentManager;
/**
* User: evgeny.zakrevsky
* Date: 11/8/12
*/
public class TasksToolWindowFactory implements ToolWindowFactory, Condition<Project> {
@Override
public boolean value(final Project project) {
final LocalTask activeTask = TaskManager.getManager(project).getActiveTask();
final boolean isNotUsed = activeTask.isDefault() && Comparing.equal(activeTask.getCreated(), activeTask.getUpdated());
return !isNotUsed;
}
@Override
public void createToolWindowContent(final Project project, final ToolWindow toolWindow) {
final ContentManager contentManager = toolWindow.getContentManager();
final Content content = ContentFactory.SERVICE.getInstance().createContent(new TasksToolWindowPanel(project), null, false);
contentManager.addContent(content);
}
}
@@ -0,0 +1,159 @@
package com.intellij.tasks.timetracking;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.util.Comparing;
import com.intellij.openapi.util.IconLoader;
import com.intellij.tasks.LocalTask;
import com.intellij.tasks.TaskListenerAdapter;
import com.intellij.tasks.TaskManager;
import com.intellij.ui.ScrollPaneFactory;
import com.intellij.ui.SimpleColoredComponent;
import com.intellij.ui.table.JBTable;
import com.intellij.util.text.DateFormatUtil;
import com.intellij.util.ui.ColumnInfo;
import com.intellij.util.ui.ListTableModel;
import com.intellij.util.ui.UIUtil;
import org.jetbrains.annotations.Nullable;
import javax.swing.*;
import javax.swing.table.TableCellRenderer;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Comparator;
/**
* User: evgeny.zakrevsky
* Date: 11/8/12
*/
public class TasksToolWindowPanel extends JPanel implements Disposable {
private Timer myTimer;
public TasksToolWindowPanel(final Project project) {
super(new BorderLayout());
final TaskManager taskManager = TaskManager.getManager(project);
final JTable table = new JBTable(createListModel());
final ListTableModel<LocalTask> model = (ListTableModel<LocalTask>)table.getModel();
model.setItems(taskManager.getLocalTasks());
add(ScrollPaneFactory.createScrollPane(table, true), BorderLayout.CENTER);
taskManager.addTaskListener(new TaskListenerAdapter() {
@Override
public void taskDeactivated(final LocalTask task) {
model.setItems(taskManager.getLocalTasks());
}
@Override
public void taskActivated(final LocalTask task) {
model.setItems(taskManager.getLocalTasks());
}
@Override
public void taskAdded(final LocalTask task) {
model.setItems(taskManager.getLocalTasks());
}
@Override
public void taskRemoved(final LocalTask task) {
model.setItems(taskManager.getLocalTasks());
}
});
myTimer = new Timer(60 * 1000, new ActionListener() {
@Override
public void actionPerformed(final ActionEvent e) {
table.repaint();
}
});
myTimer.start();
}
private static ListTableModel<LocalTask> createListModel() {
final ColumnInfo<LocalTask, String> task = new ColumnInfo<LocalTask, String>("Task") {
@Nullable
@Override
public String valueOf(final LocalTask task) {
return task.getPresentableName();
}
@Nullable
@Override
public TableCellRenderer getRenderer(final LocalTask task) {
return new TableCellRenderer() {
@Override
public Component getTableCellRendererComponent(final JTable table,
final Object value,
final boolean isSelected,
final boolean hasFocus,
final int row,
final int column) {
final SimpleColoredComponent component = new SimpleColoredComponent();
component.setBackground(UIUtil.getTableBackground(isSelected));
final boolean isClosed = task.isClosed() || task.isClosedLocally();
component.setForeground(isClosed ? UIUtil.getLabelDisabledForeground() : UIUtil.getTableForeground(isSelected));
component.setIcon(isClosed ? IconLoader.getTransparentIcon(task.getIcon()) : task.getIcon());
return component;
}
};
}
@Nullable
@Override
public Comparator<LocalTask> getComparator() {
return new Comparator<LocalTask>() {
public int compare(LocalTask o1, LocalTask o2) {
int i = Comparing.compare(o2.getUpdated(), o1.getUpdated());
return i == 0 ? Comparing.compare(o2.getCreated(), o1.getCreated()) : i;
}
};
}
};
final ColumnInfo<LocalTask, String> spentTime = new ColumnInfo<LocalTask, String>("Time Spent") {
@Nullable
@Override
public String valueOf(final LocalTask task) {
long timeSpent = task.getTimeSpent();
if (task.isActive()) {
timeSpent += System.currentTimeMillis() - task.getActivated();
}
return DateFormatUtil.formatDuration(timeSpent);
}
@Nullable
@Override
public Comparator<LocalTask> getComparator() {
return new Comparator<LocalTask>() {
@Override
public int compare(final LocalTask o1, final LocalTask o2) {
return Comparing.compare(o1.getTimeSpent(), o2.getTimeSpent());
}
};
}
};
return new ListTableModel<LocalTask>((new ColumnInfo[]{task, spentTime}));
}
private static String formatDuration(final long milliseconds) {
final int second = 1000;
final int minute = 60 * 1000;
final int hour = 60 * 60 * 1000;
return String.format("%d:%02d:%02d", milliseconds / hour, milliseconds % hour / minute,
milliseconds % minute / second);
}
@Override
public void dispose() {
myTimer.stop();
myTimer = null;
}
}
@@ -24,7 +24,7 @@ public class TaskManagerTest extends TaskManagerTestCase {
public void testAddRemoveListener() throws Exception {
TaskListener listener = new TaskListener() {
TaskListener listener = new TaskListenerAdapter() {
@Override
public void taskActivated(LocalTask task) {
@@ -37,7 +37,7 @@ public class TaskManagerTest extends TaskManagerTestCase {
public void testTaskSwitch() throws Exception {
final Ref<Integer> count = Ref.create(0);
TaskListener listener = new TaskListener() {
TaskListener listener = new TaskListenerAdapter() {
@Override
public void taskActivated(LocalTask task) {
count.set(count.get() + 1);
@@ -1,11 +1,11 @@
package com.intellij.tasks;
import com.intellij.tasks.impl.LocalTaskImpl;
import com.intellij.tasks.impl.TaskManagerImpl;
import com.intellij.testFramework.IdeaTestCase;
import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
import java.util.Collections;
import java.util.List;
/**
* @author Dmitry Avdeev
@@ -38,8 +38,8 @@ public abstract class TaskManagerTestCase extends LightCodeInsightFixtureTestCas
}
private void removeAllTasks() {
LocalTaskImpl[] tasks = myManager.getLocalTasks();
for (LocalTaskImpl task : tasks) {
List<LocalTask> tasks = myManager.getLocalTasks();
for (LocalTask task : tasks) {
myManager.removeTask(task);
}
}
@@ -43,8 +43,8 @@ public class TaskVcsTest extends TaskManagerTestCase {
private ChangeListManager myChangeListManager;
public void testInitialState() {
assertEquals(1, myManager.getLocalTasks().length);
final LocalTaskImpl defaultTask = myManager.getLocalTasks()[0];
assertEquals(1, myManager.getLocalTasks().size());
final LocalTask defaultTask = myManager.getLocalTasks().get(0);
assertEquals(defaultTask, myManager.getActiveTask());
assertTrue(defaultTask.isDefault());
@@ -57,13 +57,13 @@ public class TaskVcsTest extends TaskManagerTestCase {
}
public void testSwitchingTasks() throws Exception {
final LocalTaskImpl defaultTask = myManager.getLocalTasks()[0];
final LocalTask defaultTask = myManager.getLocalTasks().get(0);
Task task = myRepository.findTask("TEST-001");
assertNotNull(task);
myManager.activateTask(task, false, false);
assertEquals(2, myManager.getLocalTasks().length);
assertEquals(2, myManager.getLocalTasks().size());
LocalTask localTask = myManager.getActiveTask();
assertEquals(task, localTask);
@@ -215,7 +215,7 @@ public class TaskVcsTest extends TaskManagerTestCase {
myManager.getState().associateWithCurrentTaskForNewChangelist = false;
addChangeList("New Changelist", "");
assertEquals(2, myManager.getLocalTasks().length);
assertEquals(2, myManager.getLocalTasks().size());
assertEquals(2, myChangeListManager.getChangeLists().size());
LocalChangeList newChangeList = myChangeListManager.findChangeList("New Changelist");
assertNotNull(newChangeList);
@@ -230,7 +230,7 @@ public class TaskVcsTest extends TaskManagerTestCase {
myManager.getState().associateWithTaskForNewChangelist = false;
addChangeList("New Changelist", "");
assertEquals(1, myManager.getLocalTasks().length);
assertEquals(1, myManager.getLocalTasks().size());
assertEquals(2, myChangeListManager.getChangeLists().size());
LocalChangeList newChangeList = myChangeListManager.findChangeList("New Changelist");
assertNotNull(newChangeList);
@@ -253,13 +253,13 @@ public class TaskVcsTest extends TaskManagerTestCase {
public void testSaveContextOnCommitForExistingTask() throws Exception {
myManager.getState().saveContextOnCommit = true;
assertEquals(1, myManager.getLocalTasks().length);
assertEquals(1, myManager.getLocalTasks().size());
Task task = myRepository.findTask("TEST-001");
assertNotNull(task);
myManager.activateTask(task, false, true);
assertEquals(2, myManager.getLocalTasks().length);
assertEquals(2, myManager.getLocalTasks().size());
assertEquals(2, myChangeListManager.getChangeLists().size());
LocalTask localTask = myManager.getActiveTask();
List<ChangeListInfo> changelists = localTask.getChangeLists();
@@ -269,7 +269,7 @@ public class TaskVcsTest extends TaskManagerTestCase {
CommitChangeListDialog.commitChanges(getProject(), Collections.<Change>emptyList(), changeList, null, changeList.getName());
assertEquals(2, myManager.getLocalTasks().length); // no extra task created
assertEquals(2, myManager.getLocalTasks().size()); // no extra task created
assertEquals(2, myChangeListManager.getChangeLists().size());
assertEquals(localTask, myManager.getAssociatedTask(changeList)); // association should survive
@@ -278,24 +278,24 @@ public class TaskVcsTest extends TaskManagerTestCase {
public void testSaveContextOnCommit() throws Exception {
myManager.getState().saveContextOnCommit = true;
assertEquals(1, myManager.getLocalTasks().length);
assertEquals(1, myManager.getLocalTasks().size());
assertEquals(1, myChangeListManager.getChangeLists().size());
myManager.getState().associateWithTaskForNewChangelist = false;
LocalChangeList changeList = addChangeList("New Changelist", "");
myManager.getState().associateWithTaskForNewChangelist = true;
assertEquals(1, myManager.getLocalTasks().length);
assertEquals(1, myManager.getLocalTasks().size());
assertEquals(2, myChangeListManager.getChangeLists().size());
CommitChangeListDialog.commitChanges(getProject(), Collections.<Change>emptyList(), changeList, null, changeList.getName());
assertEquals(2, myManager.getLocalTasks().length); // extra task created
assertEquals(2, myManager.getLocalTasks().size()); // extra task created
assertEquals(2, myChangeListManager.getChangeLists().size());
assertTrue(ContainerUtil.exists(myManager.getLocalTasks(), new Condition<LocalTaskImpl>() {
assertTrue(ContainerUtil.exists(myManager.getLocalTasks(), new Condition<LocalTask>() {
@Override
public boolean value(final LocalTaskImpl task) {
public boolean value(final LocalTask task) {
return task.getSummary().equals("New Changelist");
}
}));