blob: a0f6458d91b94fd81e14f8d75cc200e2e1cba928 [file] [log] [blame]
package org.eclipse.emf.parsley.tests
import java.io.ByteArrayOutputStream
import java.io.PrintStream
import org.eclipse.emf.common.command.AbstractCommand
import org.eclipse.emf.common.command.Command
import org.eclipse.emf.ecore.resource.Resource
import org.eclipse.emf.ecore.resource.impl.ResourceImpl
import org.eclipse.emf.edit.domain.EditingDomain
import org.eclipse.emf.parsley.junit4.AbstractEmfParsleyControlBasedTest
import org.eclipse.emf.parsley.listeners.AsyncCommandStackListenerHelper
import org.eclipse.emf.parsley.tests.AsyncCommandStackListenerTest.TestableCommand
import org.eclipse.emf.parsley.tests.util.EmfParsleyFixturesAndUtilitiesTestRule
import org.eclipse.emf.parsley.tests.util.TestableCommandStackListenerClient
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import static extension org.junit.Assert.*
class AsyncCommandStackListenerTest extends AbstractEmfParsleyControlBasedTest {
@Rule public extension EmfParsleyFixturesAndUtilitiesTestRule fixtures = new EmfParsleyFixturesAndUtilitiesTestRule()
var EditingDomain editingDomain = null
var TestableCommandStackListenerClient client
var AsyncCommandStackListenerHelper helper
var Resource resource
static class TestableCommand extends AbstractCommand {
val affectedObjects = newArrayList()
override getAffectedObjects() {
return affectedObjects
}
override canExecute() {
true
}
override execute() {
}
override redo() {
}
}
@Before
def void initialize() {
val injector = getOrCreateInjector
editingDomain = injector.getProvider(EditingDomain).get()
client = new TestableCommandStackListenerClient
helper = injector.getInstance(AsyncCommandStackListenerHelper)
resource = new ResourceImpl
}
@Test def void testCommandAffectingNoObject() {
setupListener(resource)
executeCommand(new TestableCommand)
0.assertEquals(client.commandsAffectingResources.size)
1.assertEquals(client.commands.size)
}
@Test def void testCommandAffectingNoEObject() {
setupListener(resource)
executeCommand(new TestableCommand => [affectedObjects += "a string"])
0.assertEquals(client.commandsAffectingResources.size)
1.assertEquals(client.commands.size)
}
@Test def void testCommandAffectingObjectOfDifferentResource() {
setupListener(resource)
val resource2 = new ResourceImpl
val object = createClassWithName("")
resource2.contents += object
executeCommand(new TestableCommand => [affectedObjects += object])
0.assertEquals(client.commandsAffectingResources.size)
1.assertEquals(client.commands.size)
}
@Test def void testCommandAffectingObjectOfDifferentResourceWithoutResourceToObserve() {
setupListener()
val resource2 = new ResourceImpl
val object = createClassWithName("")
resource2.contents += object
executeCommand(new TestableCommand => [affectedObjects += object])
1.assertEquals(client.commandsAffectingResources.size)
1.assertEquals(client.commands.size)
}
@Test def void testCommandAffectingResource() {
setupListener(resource)
val object = createClassWithName("")
resource.contents += object
executeCommand(new TestableCommand => [affectedObjects += object])
1.assertEquals(client.commandsAffectingResources.size)
1.assertEquals(client.commands.size)
}
@Test def void testCommandThrowingNPE() {
// check that EMF internally detects the NPE
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=479491
setupListener(resource)
val err = new ByteArrayOutputStream()
val backup = System.err
System.setErr(new PrintStream(err))
try {
executeCommand(new TestableCommand() {
override execute() {
throw new NullPointerException
}
})
// since the command throws a NPE, the most recent command will be null
// so we won't get any notification
0.assertEquals(client.commandsAffectingResources.size)
0.assertEquals(client.commands.size)
// check that EMF internally caught the exception
assertTrue("not found the expected string in:\n" + err.toString,
err.toString.contains("An exception was ignored during command execution")
)
} finally {
System.setErr(backup)
}
}
def private executeCommand(Command command) {
editingDomain.commandStack.execute(command)
// the listener executes in the UI thread with async
// so we must flush all the pending events
flushPendingEvents
}
def private setupListener() {
helper.addCommandStackListener(editingDomain, shell, client)
}
def private setupListener(Resource resource) {
helper.addCommandStackListener(editingDomain, shell, client, resource)
}
}