6 new revisions:

Revision: 51a7b0202736
Author:   Pekka Klärck
Date:     Mon Jun 13 03:27:37 2011
Log: Pass setup/teardown type to all start/end_keyword listener methods exe...
http://code.google.com/p/robotframework/source/detail?r=51a7b0202736

Revision: 61f5f29f8af6
Author:   Pekka Klärck
Date:     Mon Jun 13 03:43:55 2011
Log:      (whitespace) cleanup
http://code.google.com/p/robotframework/source/detail?r=61f5f29f8af6

Revision: c7682275527e
Author:   Pekka Klärck
Date:     Mon Jun 13 03:54:35 2011
Log:      bump
http://code.google.com/p/robotframework/source/detail?r=c7682275527e

Revision: 36dc4f55cc18
Author:   Pekka Klärck
Date:     Mon Jun 13 03:55:56 2011
Log: Documented new type attribute of start/end_keyword listener methods...
http://code.google.com/p/robotframework/source/detail?r=36dc4f55cc18

Revision: addacfa6082a
Author:   Pekka Klärck
Date:     Mon Jun 13 03:56:00 2011
Log:      regen
http://code.google.com/p/robotframework/source/detail?r=addacfa6082a

Revision: d2749a2e0a63
Author:   Pekka Klärck
Date:     Mon Jun 13 03:56:11 2011
Log:      Automated merge with https://robotframework.googlecode.com/hg/
http://code.google.com/p/robotframework/source/detail?r=d2749a2e0a63

==============================================================================
Revision: 51a7b0202736
Author:   Pekka Klärck
Date:     Mon Jun 13 03:27:37 2011
Log: Pass setup/teardown type to all start/end_keyword listener methods executed as a part of setup/teardown. Also changed the type to title case (e.g. 'test setup' -> 'Test Setup').

Update issue 859
I thought about this a bit myself and come to conclusion that it's better if all keywords executd as a part of setup/teardown got a correct type.
http://code.google.com/p/robotframework/source/detail?r=51a7b0202736

Modified:
 /atest/testdata/misc/setups_and_teardowns.txt
 /atest/testresources/listeners/listeners.py
 /src/robot/output/listeners.py

=======================================
--- /atest/testdata/misc/setups_and_teardowns.txt       Sat Jun 11 15:59:22 2011
+++ /atest/testdata/misc/setups_and_teardowns.txt       Mon Jun 13 03:27:37 2011
@@ -1,11 +1,29 @@
 ***Settings***
Documentation This suite was initially created for testing keyword types with
 ...             listeners but can be used for other purposes too.
-Suite Setup     Log  Suite Setup
-Suite Teardown  Log  Suite Teardown
-Test Setup      Log  Test Setup
-Test Teardown   Log  Test Teardown
+Suite Setup     Suite Setup
+Suite Teardown  Suite Teardown
+Test Setup      Test Setup
+Test Teardown   Test Teardown

 ***Test Cases***
+
 Test with setup and teardown
+    Keyword
+
+***Keywords***
+
+Suite Setup
+    Log  Suite Setup
+
+Suite Teardown
+    Log  Suite Teardown
+
+Test Setup
+    Log  Test Setup
+
+Test Teardown
+    Log  Test Teardown
+
+Keyword
     Log  Keyword
=======================================
--- /atest/testresources/listeners/listeners.py Sat Jun 11 15:59:22 2011
+++ /atest/testresources/listeners/listeners.py Mon Jun 13 03:27:37 2011
@@ -66,9 +66,10 @@
     ROBOT_LISTENER_API_VERSION = '2'

     def start_keyword(self, name, attrs):
-        if attrs['type'] != attrs['args'][0].lower():
+        expected =  attrs['args'][0] if name == 'BuiltIn.Log' else name
+        if attrs['type'] != expected:
             raise RuntimeError("Wrong keyword type '%s', expected '%s'."
-                               % (attrs['type'], attrs['args'][0].lower()))
+                               % (attrs['type'], expected))

     end_keyword = start_keyword

=======================================
--- /src/robot/output/listeners.py      Sat Jun 11 15:59:22 2011
+++ /src/robot/output/listeners.py      Mon Jun 13 03:27:37 2011
@@ -30,8 +30,9 @@
_end_attrs = _start_attrs + ['endtime', 'elapsedtime', 'status', 'message']

     def __init__(self, listeners):
-        self._running_test = False
         self._listeners = self._import_listeners(listeners)
+        self._running_test = False
+        self._setup_or_teardown_type = None

     def __nonzero__(self):
         return bool(self._listeners)
@@ -95,23 +96,32 @@
                 li.call_method(li.start_keyword, kw.name, kw.args)
             else:
                 attrs = self._get_start_attrs(kw, 'args', '-longname')
-                attrs['type'] = self._get_keyword_type(kw)
+                attrs['type'] = self._get_keyword_type(kw, start=True)
                 li.call_method(li.start_keyword, kw.name, attrs)

-    def _get_keyword_type(self, kw):
-        if kw.type == 'kw':
-            return 'keyword'
- return '%s %s' % (('test' if self._running_test else 'suite'), kw.type)
-
     def end_keyword(self, kw):
         for li in self._listeners:
             if li.version == 1:
                 li.call_method(li.end_keyword, kw.status)
             else:
attrs = self._get_end_attrs(kw, 'args', '-longname', '-message')
-                attrs['type'] = self._get_keyword_type(kw)
+                attrs['type'] = self._get_keyword_type(kw, start=False)
                 li.call_method(li.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
+        # set to setup/teardown but we want to pass that type also to all
+        # start/end_keyword listener methods called below that keyword.
+        if kw.type == 'kw':
+            return self._setup_or_teardown_type or 'Keyword'
+        kw_type = self._get_setup_or_teardown_type(kw)
+        self._setup_or_teardown_type = kw_type if start else None
+        return kw_type
+
+    def _get_setup_or_teardown_type(self, kw):
+        return '%s %s' % (('Test' if self._running_test else 'Suite'),
+                          kw.type.title())
+
     def log_message(self, msg):
         for li in self._listeners:
             if li.version == 2:

==============================================================================
Revision: 61f5f29f8af6
Author:   Pekka Klärck
Date:     Mon Jun 13 03:43:55 2011
Log:      (whitespace) cleanup
http://code.google.com/p/robotframework/source/detail?r=61f5f29f8af6

Modified:
 /doc/userguide/src/ExtendingRobotFramework/ListenerInterface.txt

=======================================
--- /doc/userguide/src/ExtendingRobotFramework/ListenerInterface.txt Thu Sep 16 12:37:09 2010 +++ /doc/userguide/src/ExtendingRobotFramework/ListenerInterface.txt Mon Jun 13 03:43:55 2011
@@ -2,16 +2,15 @@
 ------------------------

 Robot Framework has a listener interface that can be used to receive
-notifications about test execution. Listeners are classes with certain special -methods, and they can be implemented both with Python and Java. Starting from -version 2.0.2, it is also possible to implement listeners as Python modules. -Example uses of the listener interface include external test monitors, sending
-a mail message when a test fails, and communicating with other systems.
-
-.. contents::
+notifications about test execution. Listeners are classes or modules
+with certain special methods, and they can be implemented both with
+Python and Java. Example uses of the listener interface include
+external test monitors, sending a mail message when a test fails, and
+communicating with other systems.
+
+.. contents::
    :depth: 2
-   :local:
-
+   :local:

 Taking listeners into use
 ~~~~~~~~~~~~~~~~~~~~~~~~~
@@ -22,14 +21,14 @@
 listener interface, similarly as `test library names`_ are got from classes
implementing them. The specified listeners must be in the same `module search
 path`_ where test libraries are searched from when they are imported. Other
-option is to give an absolute or a relative path to the listener file
-`similarly as with test libraries`__. It is possible to take multiple listeners
+option is to give an absolute or a relative path to the listener file
+`similarly as with test libraries`__. It is possible to take multiple listeners
 into use by using this option several times.

Starting from version 2.0.2, it is also possible to give arguments to listener -classes from the command line. Arguments are specified after the listener name
-(or path) using a colon as a separator. This approach provides only string
-type arguments and arguments obviously cannot contain colons. However, it
+classes from the command line. Arguments are specified after the listener name
+(or path) using a colon as a separator. This approach provides only string
+type arguments and arguments obviously cannot contain colons. However, it
 should be pretty easy to listeners to go around these limitations.

 __ `Using physical path to library`_
@@ -43,7 +42,6 @@
    pybot --listener ListenerWithArgs:arg1:arg2
    pybot --listener path/to/MyListener.java:argument tests.html

-
 Available listener interface methods
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

@@ -55,7 +53,6 @@
 implement any official interface, and it only needs to have the methods it
 actually needs.

-
 Listener interface versions
 '''''''''''''''''''''''''''

@@ -65,14 +62,13 @@
will continue to work, but they will be deprecated in some future version, so all new listeners should be implemented with signatures described in the table below. The most recent detailed description of the old listener interface can
-be found in User Guide of Robot Framework 2.0.4.
-
-.. note:: A listener must have attribute :code:`ROBOT_LISTENER_API_VERSION`
+be found in User Guide of Robot Framework 2.0.4.
+
+.. note:: A listener must have attribute :code:`ROBOT_LISTENER_API_VERSION`
   defined in order to be recognized as a new style listener. Value of the
:code:`ROBOT_LISTENER_API_VERSION` attribute must be 2, either as a string or
   as an integer. The examples below are implemented as new style listeners.

-
 Listener interface method signatures
 ''''''''''''''''''''''''''''''''''''

@@ -82,8 +78,8 @@
following table lists all the available methods in the listener interface and the contents of the :code:`attributes` dictionary, where applicable. Keys of the dictionary are strings. All of these methods have also `camelCase` aliases.
-Thus, for example, :code:`startSuite` is a synonym to :code:`start_suite`.
-
+Thus, for example, :code:`startSuite` is a synonym to :code:`start_suite`.
+
 .. table:: Available methods in the listener interface
    :class: tabular

@@ -104,7 +100,7 @@
| | | * totaltests: total number of tests in this suite| | | | and all its sub-suites as an integer | | | | | - | | | The last four were added in Robot Framework 2.5 | + | | | The last four were added in Robot Framework 2.5. | +---------------+------------------+--------------------------------------------------+ | end_suite | name, attributes | Keys in the attributes dictionary: | | | | |
@@ -228,7 +224,6 @@
        void debugFile(String path);
        void close();
    }
-

 Listener examples
 ~~~~~~~~~~~~~~~~~
@@ -242,7 +237,7 @@

    def start_test(name, attrs):
        print 'Executing test %s' % name
-
+
    def start_keyword(name, attrs):
print 'Executing keyword %s with arguments %s' % (name, attrs['args'])

@@ -252,7 +247,6 @@
    def close():
        print 'All tests executed'

-
The second example, which still uses Python, is slightly more complicated. It writes all the information it gets into a text file in a temporary directory without much formatting. The filename may be given from the command line, but
@@ -269,31 +263,30 @@
    class PythonListener:

        ROBOT_LISTENER_API_VERSION = 2
-
+
        def __init__(self, filename='listen.txt'):
            outpath = os.path.join(tempfile.gettempdir(), filename)
            self.outfile = open(outpath, 'w')
-
+
        def start_suite(self, name, attrs):
            self.outfile.write("%s '%s'\n" % (name, attrs['doc']))
-
+
        def start_test(self, name, attrs):
            tags = ' '.join(attrs['tags'])
self.outfile.write("- %s '%s' [ %s ] :: " % (name, attrs['doc'], tags))
-
+
        def end_test(self, name, attrs):
            if attrs['status'] == 'PASS':
                self.outfile.write('PASS\n')
            else:
                self.outfile.write('FAIL: %s\n' % attrs['message'])
-
+
         def end_suite(self, name, attrs):
self.outfile.write('%s\n%s\n' % (attrs['status'], attrs['message']))
-
+
         def close(self):
             self.outfile.close()

-
The third example implements the same functionality as the previous one, but uses Java instead of Python.

 .. sourcecode:: java
@@ -304,7 +297,7 @@


    public class JavaListener {
-
+
        public static final int ROBOT_LISTENER_API_VERSION = 2;
        public static final String DEFAULT_FILENAME = "listen_java.txt";
        private BufferedWriter outfile = null;
@@ -312,14 +305,14 @@
        public JavaListener() throws IOException {
            this(DEFAULT_FILENAME);
        }
-
+
        public JavaListener(String filename) throws IOException {
            String tmpdir = System.getProperty("java.io.tmpdir");
            String sep = System.getProperty("file.separator");
-           String outpath = tmpdir + sep + filename;
+           String outpath = tmpdir + sep + filename;
            outfile = new BufferedWriter(new FileWriter(outpath));
        }
-
+
        public void startSuite(String name, Map attrs) throws IOException {
            outfile.write(name + " '" + attrs.get("doc") + "'\n");
        }
@@ -332,7 +325,7 @@
            }
            outfile.write(" ] :: ");
        }
-
+
        public void endTest(String name, Map attrs) throws IOException {
            String status = attrs.get("status").toString();
            if (status.equals("PASS")) {
@@ -342,11 +335,11 @@
                outfile.write("FAIL: " + attrs.get("message") + "\n");
            }
        }
-
+
        public void endSuite(String name, Map attrs) throws IOException {
outfile.write(attrs.get("status") + "\n" + attrs.get("message") + "\n");
        }
-
+
        public void close() throws IOException {
            outfile.close();
        }

==============================================================================
Revision: c7682275527e
Author:   Pekka Klärck
Date:     Mon Jun 13 03:54:35 2011
Log:      bump
http://code.google.com/p/robotframework/source/detail?r=c7682275527e

Modified:
 /src/robot/version.py

=======================================
--- /src/robot/version.py       Fri May 27 12:00:12 2011
+++ /src/robot/version.py       Mon Jun 13 03:54:35 2011
@@ -3,8 +3,8 @@
 import sys

 VERSION = 'trunk'
-RELEASE = '20110527'
-TIMESTAMP = '20110527-215819'
+RELEASE = '20110613'
+TIMESTAMP = '20110613-134844'

 def get_version(sep=' '):
     if RELEASE == 'final':

==============================================================================
Revision: 36dc4f55cc18
Author:   Pekka Klärck
Date:     Mon Jun 13 03:55:56 2011
Log: Documented new type attribute of start/end_keyword listener methods

Update issue 859
Status: Done
Now this is also documented in the user guide. I consider this done but comments are still appreciated.
http://code.google.com/p/robotframework/source/detail?r=36dc4f55cc18

Modified:
 /doc/userguide/src/ExtendingRobotFramework/ListenerInterface.txt

=======================================
--- /doc/userguide/src/ExtendingRobotFramework/ListenerInterface.txt Mon Jun 13 03:43:55 2011 +++ /doc/userguide/src/ExtendingRobotFramework/ListenerInterface.txt Mon Jun 13 03:55:56 2011
@@ -140,7 +140,12 @@
| | | | | | | * doc: keyword documentation | | | | * starttime: execution start time | - | | | * args: keyword arguments as a list of strings | + | | | * args: keyword's arguments as a list of strings | + | | | * type: string :code:`Keyword` for normal | + | | | keywords and :code:`Test Setup`, :code:`Test | + | | | Teardown`, :code:`Suite Setup` or :code:`Suite | + | | | Teardown` for keywords used in suite/test | + | | | setup/teardown. New in Robot Framework 2.6. | +---------------+------------------+--------------------------------------------------+ | end_keyword | name, attributes | Keys in the attributes dictionary: | | | | |
@@ -151,6 +156,7 @@
| | | as an integer | | | | * args: keyword's arguments as a list of strings | | | | * status: either :code:`PASS` or :code:`FAIL` | + | | | * type: Same as with :code:`start_keyword` | +---------------+------------------+--------------------------------------------------+ | log_message | message | Called when an executed keyword writes a log | | | | message. :code:`message` is a dictionary with |

==============================================================================
Revision: addacfa6082a
Author:   Pekka Klärck
Date:     Mon Jun 13 03:56:00 2011
Log:      regen
http://code.google.com/p/robotframework/source/detail?r=addacfa6082a

Modified:
 /doc/userguide/RobotFrameworkUserGuide.html

=======================================
--- /doc/userguide/RobotFrameworkUserGuide.html Fri May 27 12:02:05 2011
+++ /doc/userguide/RobotFrameworkUserGuide.html Mon Jun 13 03:56:00 2011
@@ -488,7 +488,7 @@
 <body>
 <div class="document" id="robot-framework-user-guide">
 <h1 class="title">Robot Framework User Guide</h1>
-<h2 class="subtitle" id="version-version">Version trunk 20110527</h2>
+<h2 class="subtitle" id="version-version">Version trunk 20110613</h2>

 <!-- This data file has been placed in the public domain. -->
 <!-- Derived from the Unicode character mappings available from
@@ -12680,11 +12680,11 @@
 <div class="section" id="using-listener-interface">
<h2><a class="toc-backref" href="#id519">4.3&nbsp;&nbsp;&nbsp;Using listener interface</a></h2>
 <p>Robot Framework has a listener interface that can be used to receive
-notifications about test execution. Listeners are classes with certain special -methods, and they can be implemented both with Python and Java. Starting from -version 2.0.2, it is also possible to implement listeners as Python modules. -Example uses of the listener interface include external test monitors, sending
-a mail message when a test fails, and communicating with other systems.</p>
+notifications about test execution. Listeners are classes or modules
+with certain special methods, and they can be implemented both with
+Python and Java. Example uses of the listener interface include
+external test monitors, sending a mail message when a test fails, and
+communicating with other systems.</p>
 <div class="contents local topic" id="id206">
 <ul class="auto-toc simple">
<li><a class="reference internal" href="#taking-listeners-into-use" id="id578">4.3.1&nbsp;&nbsp;&nbsp;Taking listeners into use</a></li>
@@ -12787,7 +12787,7 @@
 <li>totaltests: total number of tests in this suite
 and all its sub-suites as an integer</li>
 </ul>
-<p class="last">The last four were added in Robot Framework 2.5</p>
+<p class="last">The last four were added in Robot Framework 2.5.</p>
 </td>
 </tr>
 <tr><td>end_suite</td>
@@ -12842,7 +12842,12 @@
 <ul class="last simple">
 <li>doc: keyword documentation</li>
 <li>starttime: execution start time</li>
-<li>args: keyword arguments as a list of strings</li>
+<li>args: keyword's arguments as a list of strings</li>
+<li>type: string <span class="code">Keyword</span> for normal
+keywords and <span class="code">Test Setup</span>, <span class="code">Test
+Teardown</span>, <span class="code">Suite Setup</span> or <span class="code">Suite
+Teardown</span> for keywords used in suite/test
+setup/teardown. New in Robot Framework 2.6.</li>
 </ul>
 </td>
 </tr>
@@ -12857,6 +12862,7 @@
 as an integer</li>
 <li>args: keyword's arguments as a list of strings</li>
<li>status: either <span class="code">PASS</span> or <span class="code">FAIL</span></li>
+<li>type: Same as with <span class="code">start_keyword</span></li>
 </ul>
 </td>
 </tr>
@@ -14098,7 +14104,7 @@
 <div class="footer">
 <hr class="footer" />
<p>Generated by <a class="reference external" href="http://docutils.sourceforge.net/rst.html";>reStructuredText</a>. Syntax highlighting by <a class="reference external" href="http://pygments.org/";>Pygments</a>.</p>
-<p>Generated on: 2011-05-27 19:01 UTC.
+<p>Generated on: 2011-06-13 10:54 UTC.
 </p>

 </div>

==============================================================================
Revision: d2749a2e0a63
Author:   Pekka Klärck
Date:     Mon Jun 13 03:56:11 2011
Log:      Automated merge with https://robotframework.googlecode.com/hg/
http://code.google.com/p/robotframework/source/detail?r=d2749a2e0a63


Reply via email to