blob: d7f09cc5c44b987fcadf2b6b832fc3f89935f0f5 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 groovy.beans
import groovy.test.GroovyTestCase
/**
* Unit test for ListenerList.
*/
class ListenerListTransformTest extends GroovyTestCase {
void testDefaultFireAndName() {
GroovyShell shell = new GroovyShell()
def tc = shell.evaluate("""
import groovy.beans.*
class TestClass {
@ListenerList
List<TestListener> listeners
}
new TestClass()
""")
assert tc.listeners == []
int count = 0
String source = "TestSource"
String message = "TestMessage"
def evt
assert tc.testListeners.size() == 0
tc.addTestListener([eventOccurred: { e -> count++; evt = e }] as TestListener)
assert tc.testListeners.size() == 1
tc.fireEventOccurred(new TestEvent(source, message))
tc.removeTestListener(tc.testListeners[0])
assert tc.testListeners.size() == 0
assert count == 1
assert evt.source.is(source)
assert evt.message.is(message)
}
void testCustomFireAndName() {
GroovyShell shell = new GroovyShell()
def tc = shell.evaluate("""
package b
import groovy.beans.*
class TestClass {
@ListenerList(name = "someOtherTestListener")
List<TestListener> listeners
}
new TestClass ()
""")
assert tc.listeners == []
int count = 0
String source = "TestSource"
String message = "TestMessage"
def evt
assert !tc.class.methods.name.contains('addTestListener')
assert !tc.class.methods.name.contains('removeTestListener')
assert !tc.class.methods.name.contains('getTestListeners')
assert tc.class.methods.name.contains('fireEventOccurred')
assert tc.someOtherTestListeners.size() == 0
tc.addSomeOtherTestListener([eventOccurred: { e -> count++; evt = e }] as TestListener)
assert tc.someOtherTestListeners.size() == 1
tc.fireEventOccurred(new TestEvent(source, message))
tc.removeSomeOtherTestListener(tc.someOtherTestListeners[0])
assert tc.someOtherTestListeners.size() == 0
assert count == 1
assert evt.source.is(source)
assert evt.message.is(message)
}
void testMultipleMethodListener() {
GroovyShell shell = new GroovyShell()
def tc = shell.evaluate("""
package b
import groovy.beans.*
class TestClass {
@ListenerList
List<TestTwoMethodListener> listeners
}
new TestClass ()
""")
assert tc.listeners == []
int count1 = 0
int count2 = 0
String source1 = 'TestSource'
String source2 = 'TestSource'
String message1 = 'TestMessage'
String message2 = 'TestMessage'
def evt1
def evt2
tc.addTestTwoMethodListener([eventOccurred1: { e -> count1++; evt1 = e }, eventOccurred2: { e -> count2++; evt2 = e }] as TestTwoMethodListener)
tc.fireEventOccurred1(new TestEvent(source1, message1))
assert count1 == 1
assert count2 == 0
assert evt1.source.is(source1)
assert evt1.message.is(message1)
tc.fireEventOccurred2(new TestEvent(source2, message2))
assert count1 == 1
assert count2 == 1
assert evt2.source.is(source2)
assert evt2.message.is(message2)
}
void testMultipleListenersConflictsDetected() {
def message = shouldFail {
new GroovyShell().evaluate("""
package b
import groovy.beans.*
class TestClass {
@ListenerList
Set<TestListener> listeners
@ListenerList(name = "someOtherTestListener")
Vector<TestListener> listeners2
}
""")
}
assert message.contains('Class b.TestClass already has method fireEventOccurred')
}
void testMultipleMethodListeners() {
GroovyShell shell = new GroovyShell()
def tc = shell.evaluate("""
package b
import groovy.beans.*
class TestClass {
@ListenerList
List<TestTwoMethodListener> listeners
}
new TestClass ()
""")
assert tc.listeners == []
int count1 = 0
int count2 = 0
String source1 = 'TestSource'
String source2 = 'TestSource'
String message1 = 'TestMessage'
String message2 = 'TestMessage'
def evt1
def evt2
tc.addTestTwoMethodListener([eventOccurred1: { e -> count1++; evt1 = e }, eventOccurred2: { e -> count2++; evt2 = e }] as TestTwoMethodListener)
tc.fireEventOccurred1(new TestEvent(source1, message1))
assert count1 == 1
assert count2 == 0
assert evt1.source.is(source1)
assert evt1.message.is(message1)
tc.fireEventOccurred2(new TestEvent(source2, message2))
assert count1 == 1
assert count2 == 1
assert evt2.source.is(source2)
assert evt2.message.is(message2)
}
void testMapEvent() {
GroovyShell shell = new GroovyShell()
def tc = shell.evaluate("""
package b
import groovy.beans.*
class TestClass {
@ListenerList
List<TestMapListener> listeners
}
new TestClass () """)
assert tc.listeners == []
int count = 0
String source = 'TestSource'
String message = 'TestMessage'
def evt
tc.addTestMapListener([eventOccurred: { e -> count++; evt = e }] as TestMapListener)
tc.fireEventOccurred([source: source, message: message])
assert count == 1
assert evt.source.is(source)
assert evt.message.is(message)
}
void testError_AnnotationNotOnCollection() {
def message = shouldFail {
new GroovyShell().evaluate("""
import groovy.beans.*
class TestClass {
@ListenerList
def listeners
}
""")
}
assert message.contains('@groovy.beans.ListenerList can only annotate collection properties')
}
void testError_AnnotationWithoutGeneric() {
def message = shouldFail {
new GroovyShell().evaluate("""
import groovy.beans.*
class TestClass {
@ListenerList
List listeners
}
""")
}
assert message.contains('@groovy.beans.ListenerList fields must have a generic type')
}
void testError_AnnotationWithWildcard() {
def message = shouldFail {
new GroovyShell().evaluate("""
import groovy.beans.*
class TestClass {
@ListenerList
List<? super Object> listeners
}
""")
}
assert message.contains('@groovy.beans.ListenerList fields with generic wildcards not yet supported')
}
void testListEvent() {
GroovyShell shell = new GroovyShell()
def tc = shell.evaluate("""
package b
import groovy.beans.*
class TestClass {
@ListenerList
List<TestListListener> listeners
}
new TestClass ()
""")
assert tc.listeners == []
int count = 0
String source = 'TestSource'
String message = 'TestMessage'
def evt
tc.addTestListListener([eventOccurred: { e -> count++; evt = e }] as TestListListener)
tc.fireEventOccurred([source, message])
assert count == 1
assert evt[0].is(source)
assert evt[1].is(message)
}
void testObjectEvent() {
GroovyShell shell = new GroovyShell()
def tc = shell.evaluate("""
package b
import groovy.beans.*
class TestClass {
@ListenerList
List<TestObjectListener> listeners
}
new TestClass ()
""")
assert tc.listeners == []
int count = 0
def evt
tc.addTestObjectListener([eventOccurred: { e -> count++; evt = e }] as TestObjectListener)
def obj = new Object()
tc.fireEventOccurred(obj)
assert count == 1
assert evt.is(obj)
}
void testDefaultForGenericList() {
GroovyShell shell = new GroovyShell()
def tc = shell.evaluate("""
package b
import groovy.beans.*
class TestClass {
@ListenerList
List<TestObjectListener> listeners
}
new TestClass ()
""")
assert tc.listeners == []
int count = 0
String source = 'TestSource'
def evt
assert tc.testObjectListeners.size() == 0
tc.addTestObjectListener([eventOccurred: { e -> count++; evt = e }] as TestObjectListener)
assert tc.testObjectListeners.size() == 1
tc.fireEventOccurred(source)
tc.removeTestObjectListener(tc.testObjectListeners[0])
assert tc.testObjectListeners.size() == 0
assert count == 1
assert evt.is(source)
}
void testDefaultForGenericListUsingFirstAbstractMethodsParameter() {
GroovyShell shell = new GroovyShell()
def tc = shell.evaluate("""
package b
import groovy.beans.*
class TestClass {
@ListenerList
List<TestListener> listeners
}
new TestClass ()
""")
assert tc.listeners == []
int count = 0
String source = 'TestSource'
String message = 'TestMessage'
def evt
assert tc.testListeners.size() == 0
tc.addTestListener([eventOccurred: { e -> count++; evt = e }] as TestListener)
assert tc.testListeners.size() == 1
tc.fireEventOccurred(new TestEvent(source, message))
tc.removeTestListener(tc.testListeners[0])
assert tc.testListeners.size() == 0
assert count == 1
assert evt.source.is(source)
assert evt.message.is(message)
}
// GROOVY-4795
void testSynchronized() {
GroovyShell shell = new GroovyShell()
shell.evaluate("""
import groovy.beans.ListenerList
import java.lang.reflect.Modifier
class C1 {
@ListenerList(synchronize=true) List<EventListener> listeners
}
class C2 {
@ListenerList(synchronize=false) List<EventListener> listeners
}
class C3 {
@ListenerList List<EventListener> listeners
}
assert Modifier.isSynchronized(C1.class.getMethod('getEventListeners').modifiers)
assert !Modifier.isSynchronized(C2.class.getMethod('getEventListeners').modifiers)
assert !Modifier.isSynchronized(C3.class.getMethod('getEventListeners').modifiers)
""")
}
// GROOVY-4797
void testPrimitiveTypes() {
GroovyShell shell = new GroovyShell()
shell.evaluate("""
import groovy.beans.ListenerList
import java.lang.reflect.Modifier
class C {
@ListenerList List<Object> listeners // wait(long timeout) has primitive arg
}
assert C.class.getMethod('getObjects')
""")
}
// GROOVY-8156
void testListenerListWithEventClassInSameCompilationUnit() {
assertScript '''
class Event {}
class EventListener {
Event event
void doSomething(Event e) {
event = e
}
}
class EventHandler {
@groovy.beans.ListenerList
List<EventListener> listeners
}
def listener = new EventListener()
def eh = new EventHandler()
eh.addEventListener(listener)
def testEvent = new Event()
eh.fireDoSomething(testEvent)
assert listener.event.is(testEvent)
'''
}
}