2 new revisions:

Revision: 970e12328222
Branch:   default
Author:   Jussi Malinen <jussi.ao.mali...@gmail.com>
Date:     Mon Jun  9 12:54:36 2014 UTC
Log:      Update issue 811...
http://code.google.com/p/robotframework/source/detail?r=970e12328222

Revision: 13e23fb235f7
Branch:   default
Author:   Jussi Malinen <jussi.ao.mali...@gmail.com>
Date:     Mon Jun  9 12:54:44 2014 UTC
Log:      Automated merge with https://code.google.com/p/robotframework/
http://code.google.com/p/robotframework/source/detail?r=13e23fb235f7

==============================================================================
Revision: 970e12328222
Branch:   default
Author:   Jussi Malinen <jussi.ao.mali...@gmail.com>
Date:     Mon Jun  9 12:54:36 2014 UTC
Log:      Update issue 811

Now calling close method from library listener when ending the scope for that library.
http://code.google.com/p/robotframework/source/detail?r=970e12328222

Modified:
 /atest/robot/test_libraries/as_listener.txt
 /atest/robot/test_libraries/as_listener_in_java.txt
 /atest/testdata/test_libraries/as_listener/listenerlibrary.py
 /atest/testresources/testlibs/JavaListenerLibrary.class
 /atest/testresources/testlibs/JavaListenerLibrary.java
 /src/robot/output/librarylisteners.py
 /src/robot/output/listeners.py
 /src/robot/running/namespace.py

=======================================
--- /atest/robot/test_libraries/as_listener.txt Wed May 28 12:28:07 2014 UTC
+++ /atest/robot/test_libraries/as_listener.txt Mon Jun  9 12:54:36 2014 UTC
@@ -1,5 +1,8 @@
 *** Settings ***
-Suite Setup Run Tests ${EMPTY} test_libraries/as_listener/suite_scope.txt test_libraries/as_listener/test_scope.txt
+Suite Setup     Run Tests  ${EMPTY}
+...      test_libraries/as_listener/suite_scope.txt
+...      test_libraries/as_listener/test_scope.txt
+...      test_libraries/as_listener/global_scope.txt
 Force Tags      regression  jybot  pybot
 Resource        atest_resource.txt

@@ -16,3 +19,14 @@
     Check Test Case  ${TESTNAME}
 Listener methods starting with underscore are not keywords
     Check Test Case  ${TESTNAME}
+Global scope library gets events
+    Check Test Case  ${TESTNAME}
+New test gets previous global scope events
+    Check Test Case  ${TESTNAME}
+Check closing
+    Stderr Should Match
+    ...     SEPARATOR=\n
+    ...     *CLOSING TEST SUITE
+    ...     CLOSING TEST CASE
+    ...     CLOSING TEST CASE
+    ...     CLOSING GLOBAL
=======================================
--- /atest/robot/test_libraries/as_listener_in_java.txt Wed May 28 12:28:07 2014 UTC +++ /atest/robot/test_libraries/as_listener_in_java.txt Mon Jun 9 12:54:36 2014 UTC
@@ -12,3 +12,5 @@
     Check Test Case  ${TESTNAME}
 Listener methods starting with underscore are not keywords
     Check Test Case  ${TESTNAME}
+Check closing
+    Stderr Should Match   *CLOSING IN JAVA SUITE LIBRARY LISTENER\n
=======================================
--- /atest/testdata/test_libraries/as_listener/listenerlibrary.py Wed May 28 12:28:07 2014 UTC +++ /atest/testdata/test_libraries/as_listener/listenerlibrary.py Mon Jun 9 12:54:36 2014 UTC
@@ -1,3 +1,5 @@
+import sys
+
 class listenerlibrary(object):

     ROBOT_LISTENER_API_VERSION = 2
@@ -25,6 +27,10 @@
     def _end_keyword(self, name, attrs):
         self.events.append('end kw %s' % name)

+    def _close(self):
+        self.events.append('close %s' % self.ROBOT_LIBRARY_SCOPE)
+        sys.__stderr__.write("CLOSING %s\n" % self.ROBOT_LIBRARY_SCOPE)
+
     def events_should_be(self, *expected):
assert self._format(self.events) == self._format(expected), 'Expected events\n %s\n actual\n %s' % (self._format(expected), self._format(self.events))

=======================================
--- /atest/testresources/testlibs/JavaListenerLibrary.class Wed May 28 11:31:17 2014 UTC +++ /atest/testresources/testlibs/JavaListenerLibrary.class Mon Jun 9 12:54:36 2014 UTC
@@ -13,6 +13,8 @@
    V  W
    V
X Y Z [ ROBOT_LISTENER_API_VERSION Ljava/lang/String; + + a b c d ROBOT_LISTENER_API_VERSION Ljava/lang/String; ConstantValue \ ROBOT_LIBRARY_SCOPE ] events Ljava/util/ArrayList; Signature )Ljava/util/ArrayList<Ljava/lang/String;>; ROBOT_LIBRARY_LISTENER LJavaListenerLibrary; <init> ()V Code LineNumberTable startSuite $(Ljava/lang/String;Ljava/util/Map;)V endSuite startTest endTest _startKeyword @@ -31,6 +33,8 @@ f g java/lang/RuntimeException -Expected events not the same size. Expected:

^ h + + g w Actual:

  - i
@@ -40,6 +44,7 @@
TEST SUITE append -(Ljava/lang/String;)Ljava/lang/StringBuilder; toString ()Ljava/lang/String; add (Ljava/lang/Object;)Z clone ()Ljava/lang/Object; size ()I -(Ljava/lang/Object;)Ljava/lang/StringBuilder; (Ljava/lang/String;)V get (I)Ljava/lang/Object; equals ! ! " # $ % " # & ' ( ) * + , - . / 9 *· *» Y· µ **µ ± 0 1 2 / 8 + 4 5 2 8 *´ » Y· ¶ +¶ ¶ W± 0 @@ -68,16 +73,20 @@ W± 0 % & 8 9 / # + ) * < = 2 # *´ ¶ À ° 0 ) ) : ; < / É ™*´ ¶ +¹ Ÿ *» Y» Y· ¶ +¶ ¶ *´ ¶ ¶ · ¿ =
+¿ =
 +¹    ¢ X+
¹ À *´ + À +*´ + À -š :» Y» Y· ¶ + -¹ À ¶ ¶ *´ -À ¶ ¶ · ¿„ §ÿ¤± 0 +¿„ §ÿ¤± 3 - . 7 / C 0 [ 1 ’ / ˜ 4 ) = > ?
=======================================
--- /atest/testresources/testlibs/JavaListenerLibrary.java Wed May 28 11:31:17 2014 UTC +++ /atest/testresources/testlibs/JavaListenerLibrary.java Mon Jun 9 12:54:36 2014 UTC
@@ -37,6 +37,11 @@
         events.add("end kw "+name);
     }

+    public void close() {
+        System.err.println("CLOSING IN JAVA SUITE LIBRARY LISTENER");
+    }
+
+    @SuppressWarnings("unchecked")
     public List<String> getEvents() {
         return (List<String>)events.clone();
     }
=======================================
--- /src/robot/output/librarylisteners.py       Wed May 28 12:28:07 2014 UTC
+++ /src/robot/output/librarylisteners.py       Mon Jun  9 12:54:36 2014 UTC
@@ -12,7 +12,7 @@
 #  See the License for the specific language governing permissions and
 #  limitations under the License.

-from .listeners import Listeners, _ListenerProxy
+from .listeners import Listeners, ListenerProxy
 from .loggerhelper import AbstractLoggerProxy


@@ -21,28 +21,52 @@
     def __init__(self):
         self._running_test = False
         self._setup_or_teardown_type = None
+        self._global_listeners = {}

     def __nonzero__(self):
         return True

+    def _notify_end_test(self, listener, test):
+        Listeners._notify_end_test(self, listener, test)
+        if listener.library_scope == 'TESTCASE':
+            listener.call_method(listener.close)
+
+    def _notify_end_suite(self, listener, suite):
+        Listeners._notify_end_suite(self, listener, suite)
+        if listener.library_scope == 'TESTSUITE':
+            listener.call_method(listener.close)
+
+    def end_suite(self, suite):
+        for listener in self._listeners:
+            self._notify_end_suite(listener, suite)
+        if not suite.parent:
+            for listener in self._global_listeners.values():
+                listener.call_method(listener.close)
+
     @property
     def _listeners(self):
         from robot.running import EXECUTION_CONTEXTS
         if not EXECUTION_CONTEXTS.current:
             return []
-        return [_LibraryListenerProxy(listener) for listener in
-                EXECUTION_CONTEXTS.current.namespace.library_listeners]
+        listeners = [_LibraryListenerProxy(library) for library in
+                     EXECUTION_CONTEXTS.current.namespace.libraries
+                     if library.has_listener]
+        for listener in listeners:
+            if listener.library_scope == 'GLOBAL':
+                self._global_listeners[listener.logger] = listener
+        return listeners


-class _LibraryListenerProxy(_ListenerProxy):
+class _LibraryListenerProxy(ListenerProxy):

-    def __init__(self, listener):
-        AbstractLoggerProxy.__init__(self, listener)
-        self.name = type(listener).__name__
-        self.version = self._get_version(listener)
-        self.is_java = self._is_java(listener)
+    def __init__(self, library):
+        AbstractLoggerProxy.__init__(self, library.listener)
+        self.name = type(library).__name__
+        self.version = self._get_version(library.listener)
+        self.is_java = self._is_java(library.listener)
+        self.library_scope = library.scope

     def _get_method_names(self, name):
-        names = _ListenerProxy._get_method_names(self, name)
+        names = ListenerProxy._get_method_names(self, name)
         return names + ['_' + name for name in names]

=======================================
--- /src/robot/output/listeners.py      Wed Jun  4 13:08:57 2014 UTC
+++ /src/robot/output/listeners.py      Mon Jun  9 12:54:36 2014 UTC
@@ -69,7 +69,7 @@
         listeners = []
         for name, args in listener_data:
             try:
-                listeners.append(_ListenerProxy(name, args))
+                listeners.append(ListenerProxy(name, args))
             except DataError, err:
                 if args:
                     name += ':' + ':'.join(args)
@@ -78,13 +78,13 @@
         return listeners

     def start_suite(self, suite):
-        for li in self._listeners:
-            if li.version == 1:
-                li.call_method(li.start_suite, suite.name, suite.doc)
+        for listener in self._listeners:
+            if listener.version == 1:
+ listener.call_method(listener.start_suite, suite.name, suite.doc)
             else:
                 attrs = self._get_start_attrs(suite, 'metadata')
                 attrs.update(self._get_suite_attrs(suite))
-                li.call_method(li.start_suite, suite.name, attrs)
+ listener.call_method(listener.start_suite, suite.name, attrs)

     def _get_suite_attrs(self, suite):
         return {
@@ -95,56 +95,62 @@
         }

     def end_suite(self, suite):
-        for li in self._listeners:
-            if li.version == 1:
-                li.call_method(li.end_suite, suite.status,
-                               suite.full_message)
-            else:
-                attrs = self._get_end_attrs(suite, 'metadata')
-                attrs['statistics'] = suite.stat_message
-                attrs.update(self._get_suite_attrs(suite))
-                li.call_method(li.end_suite, suite.name, attrs)
+        for listener in self._listeners:
+            self._notify_end_suite(listener, suite)
+
+    def _notify_end_suite(self, listener, suite):
+        if listener.version == 1:
+            listener.call_method(listener.end_suite, suite.status,
+                           suite.full_message)
+        else:
+            attrs = self._get_end_attrs(suite, 'metadata')
+            attrs['statistics'] = suite.stat_message
+            attrs.update(self._get_suite_attrs(suite))
+            listener.call_method(listener.end_suite, suite.name, attrs)

     def start_test(self, test):
         self._running_test = True
-        for li in self._listeners:
-            if li.version == 1:
-                li.call_method(li.start_test, test.name, test.doc,
-                               list(test.tags))
+        for listener in self._listeners:
+            if listener.version == 1:
+ listener.call_method(listener.start_test, test.name, test.doc,
+                                     list(test.tags))
             else:
                 attrs = self._get_start_attrs(test, 'tags')
                 attrs['critical'] = 'yes' if test.critical else 'no'
                 attrs['template'] = test.template or ''
-                li.call_method(li.start_test, test.name, attrs)
+                listener.call_method(listener.start_test, test.name, attrs)

     def end_test(self, test):
         self._running_test = False
-        for li in self._listeners:
-            if li.version == 1:
-                li.call_method(li.end_test, test.status, test.message)
-            else:
-                attrs = self._get_end_attrs(test, 'tags')
-                attrs['critical'] = 'yes' if test.critical else 'no'
-                attrs['template'] = test.template or ''
-                li.call_method(li.end_test, test.name, attrs)
+        for listener in self._listeners:
+            self._notify_end_test(listener, test)
+
+    def _notify_end_test(self, listener, test):
+        if listener.version == 1:
+ listener.call_method(listener.end_test, test.status, test.message)
+        else:
+            attrs = self._get_end_attrs(test, 'tags')
+            attrs['critical'] = 'yes' if test.critical else 'no'
+            attrs['template'] = test.template or ''
+            listener.call_method(listener.end_test, test.name, attrs)

     def start_keyword(self, kw):
-        for li in self._listeners:
-            if li.version == 1:
-                li.call_method(li.start_keyword, kw.name, kw.args)
+        for listener in self._listeners:
+            if listener.version == 1:
+ listener.call_method(listener.start_keyword, kw.name, kw.args)
             else:
                 attrs = self._get_start_attrs(kw, *self._kw_extra_attrs)
                 attrs['type'] = self._get_keyword_type(kw, start=True)
-                li.call_method(li.start_keyword, kw.name, attrs)
+ listener.call_method(listener.start_keyword, kw.name, attrs)

     def end_keyword(self, kw):
-        for li in self._listeners:
-            if li.version == 1:
-                li.call_method(li.end_keyword, kw.status)
+        for listener in self._listeners:
+            if listener.version == 1:
+                listener.call_method(listener.end_keyword, kw.status)
             else:
                 attrs = self._get_end_attrs(kw, *self._kw_extra_attrs)
                 attrs['type'] = self._get_keyword_type(kw, start=False)
-                li.call_method(li.end_keyword, kw.name, attrs)
+                listener.call_method(listener.end_keyword, kw.name, attrs)

     def _get_keyword_type(self, kw, start=True):
# When running setup or teardown, only the top level keyword has type
@@ -161,26 +167,26 @@
                           kw.type.title())

     def log_message(self, msg):
-        for li in self._listeners:
-            if li.version == 2:
-                li.call_method(li.log_message, self._create_msg_dict(msg))
+        for listener in self._listeners:
+            if listener.version == 2:
+ listener.call_method(listener.log_message, self._create_msg_dict(msg))

     def message(self, msg):
-        for li in self._listeners:
-            if li.version == 2:
-                li.call_method(li.message, self._create_msg_dict(msg))
+        for listener in self._listeners:
+            if listener.version == 2:
+ listener.call_method(listener.message, self._create_msg_dict(msg))

     def _create_msg_dict(self, msg):
         return {'timestamp': msg.timestamp, 'message': msg.message,
                 'level': msg.level, 'html': 'yes' if msg.html else 'no'}

     def output_file(self, name, path):
-        for li in self._listeners:
-            li.call_method(getattr(li, '%s_file' % name.lower()), path)
+        for listener in self._listeners:
+ listener.call_method(getattr(listener, '%s_file' % name.lower()), path)

     def close(self):
-        for li in self._listeners:
-            li.call_method(li.close)
+        for listener in self._listeners:
+            listener.call_method(listener.close)

     def _get_start_attrs(self, item, *extra):
         return self._get_attrs(item, self._start_attrs, extra)
@@ -213,7 +219,7 @@
         return value


-class _ListenerProxy(AbstractLoggerProxy):
+class ListenerProxy(AbstractLoggerProxy):
     _methods = ['start_suite', 'end_suite', 'start_test', 'end_test',
                 'start_keyword', 'end_keyword', 'log_message', 'message',
                 'output_file', 'report_file', 'log_file', 'debug_file',
@@ -256,3 +262,8 @@
         for key, value in dictionary.iteritems():
             map.put(key, value)
         return map
+
+
+# TODO: Remove in 2.9, left here in 2.8.5 for backwards compatibility.
+# Consider also decoupling importing from __init__ to ease extending.
+_ListenerProxy = ListenerProxy
=======================================
--- /src/robot/running/namespace.py     Wed May 28 12:53:02 2014 UTC
+++ /src/robot/running/namespace.py     Mon Jun  9 12:54:36 2014 UTC
@@ -56,10 +56,8 @@
         self._imported_variable_files = ImportCache()

     @property
-    def library_listeners(self):
-        for lib in self._testlibs.itervalues():
-            if lib.has_listener:
-                yield lib.listener
+    def libraries(self):
+        return list(self._testlibs.itervalues())

     def handle_imports(self):
         self._import_default_libraries()

==============================================================================
Revision: 13e23fb235f7
Branch:   default
Author:   Jussi Malinen <jussi.ao.mali...@gmail.com>
Date:     Mon Jun  9 12:54:44 2014 UTC
Log:      Automated merge with https://code.google.com/p/robotframework/
http://code.google.com/p/robotframework/source/detail?r=13e23fb235f7


--

--- You received this message because you are subscribed to the Google Groups "robotframework-commit" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to robotframework-commit+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to