1# This Source Code Form is subject to the terms of the Mozilla Public
2# License, v. 2.0. If a copy of the MPL was not distributed with this file,
3# You can obtain one at http://mozilla.org/MPL/2.0/.
4
5from __future__ import absolute_import, with_statement
6
7from contextlib import closing
8from StringIO import StringIO
9
10try:
11    from abc import abstractmethod
12except ImportError:
13    # abc is python 2.6+
14    # from https://github.com/mozilla/mozbase/blob/master/mozdevice/mozdevice/devicemanager.py
15    def abstractmethod(method):
16        line = method.func_code.co_firstlineno
17        filename = method.func_code.co_filename
18
19        def not_implemented(*args, **kwargs):
20            raise NotImplementedError('Abstract method %s at File "%s", '
21                                      'line %s  should be implemented by a concrete class' %
22                                      (repr(method), filename, line))
23        return not_implemented
24
25
26class Output(object):
27    """ Abstract base class for outputting test results """
28
29    @abstractmethod
30    def serialize(self, results_collection, file_obj):
31        """ Writes the string representation of the results collection
32        to the given file object"""
33
34    def dump_string(self, results_collection):
35        """ Returns the string representation of the results collection """
36        with closing(StringIO()) as s:
37            self.serialize(results_collection, s)
38            return s.getvalue()
39
40
41# helper functions
42def count(iterable):
43    """ Return the count of an iterable. Useful for generators. """
44    c = 0
45    for i in iterable:
46        c += 1
47    return c
48
49
50def long_name(test):
51    if test.test_class:
52        return '%s.%s' % (test.test_class, test.name)
53    return test.name
54