# Path: libcloud_rest/api/providers.py
# class DriverMethod(object):
#     _type_name_pattern = r'.\{([_0-9a-zA-Z]+)\}'
# 
#     def __init__(self, driver_obj, method_name):
#         if inspect.isclass(driver_obj):
#             self.driver_cls = driver_obj
#         else:
#             self.driver_cls = driver_obj.__class__
#         self.driver_obj = driver_obj
#         self.method_name = method_name
#         self.method = getattr(self.driver_obj, method_name, None)
#         if not inspect.ismethod(self.method):
#             raise NoSuchOperationError()
#         method_doc = get_method_docstring(self.driver_cls, method_name)
#         if not method_doc:
#             raise MethodParsingException('Empty docstring')
#         argspec_arg = parse_args(self.method)
#         docstring_parse_result = parse_docstring(method_doc, self.driver_cls)
#         self.description = docstring_parse_result['description']
#         docstring_args = docstring_parse_result['arguments']
#         #check vargs
#         self.vargs_entries = []
#         for name, arg_info in argspec_arg.iteritems():
#             if name in docstring_args:
#                 docstring_arg = docstring_args[name]
#                 entry_kwargs = {
#                     'name': name,
#                     'description': docstring_arg['description'],
#                     'type_name': docstring_arg['type_name'],
#                     'required': (docstring_arg['required'] or
#                                  arg_info['required']),
#                 }
#                 if not entry_kwargs['required'] and 'default' in arg_info:
#                     entry_kwargs['default'] = arg_info['default']
#                 self.vargs_entries.append(Entry(**entry_kwargs))
#             else:
#                 raise MethodParsingException(
#                     '%s %s not described in docstring' % (method_name, name))
#             #update kwargs
#         kwargs = set(docstring_args).difference(argspec_arg)
#         self.kwargs_entries = [Entry(arg_name, **docstring_args[arg_name])
#                                for arg_name in kwargs]
#         method_return = docstring_parse_result['return']
#         self.result_entry = Entry('', method_return['type_name'],
#                                   method_return['description'], True)
# 
#     @classmethod
#     def _remove_type_name_brackets(cls, type_name):
#         return re.sub(cls._type_name_pattern, r'\1', type_name)
# 
#     def get_description(self):
#         result_arguments = []
#         for entry in self.vargs_entries:
#             result_arguments.extend(entry.get_arguments())
#         for entry in self.kwargs_entries:
#             result_arguments.extend(entry.get_arguments())
#         result = {'name': self.method_name,
#                   'description': self.description,
#                   'arguments': result_arguments,
#                   'return': {
#                       'type': self._remove_type_name_brackets(
#                           self.result_entry.type_name),
#                       'description': self.result_entry.description}
#                   }
#         return result
# 
#     def invoke_result_to_json(self, value):
#         return self.result_entry.to_json(value)
# 
#     def invoke(self, data):
#         vargs = [e.from_json(data, self.driver_obj)
#                  for e in self.vargs_entries]
#         kwargs = {}
#         for kw_entry in self.kwargs_entries:
#             try:
#                 kwargs[kw_entry.name] = kw_entry.from_json(data,
#                                                            self.driver_obj)
#             except MissingArguments:
#                 if kw_entry.required:
#                     raise
#         if self.method_name == '__init__':
#             return self.driver_cls(*vargs, **kwargs)
#         return self.method(*vargs, **kwargs)


import unittest2
from libcloud_rest.api.providers import DriverMethod
from libcloud_rest.errors import NoSuchOperationError, MethodParsingException
    def setUp(self):
        self.driver_method = DriverMethod(FakeDriver, 'ex_create_fake')

    def test_get_description(self):
        data = self.driver_method.get_description()
        self.assertEqual('ex_create_fake', data['name'])
        self.assertEqual('teachess volume to node.',  data['description'])
        arguments = data['arguments']
        node = {'required': True, 'type': 'str', 'name': 'node_id',
                'description': 'ID of the node which should be used'}
        volume = {'required': True, 'type': 'str', 'name': 'volume',
                  'description': 'Volume to attach'}
        device = {'required': True, 'type': 'str', 'name': 'device',
                  'description': "Where the device is exposed, "
                                 "e.g. '/dev/sdb (required)"}
        extra_dict = {'required': False, 'type': 'dict', 'name': 'extra',
                      'description': 'Extra attributes (driver specific).'}
        extra_str = {'required': False, 'type': 'str', 'name': 'extra',
                     'description': 'Extra attributes (driver specific).'}
        varg = {'default': 'value', 'required': False, 'type': 'str',
                'name': 'varg', 'description': 'with default value'}
        kwarg = {'required': False, 'type': 'str',
                 'name': 'kwarg', 'description': 'Keyword argument'}
        test_args = [node, volume, device, extra_dict, extra_str, varg, kwarg]
        self.assertEqual(arguments, test_args)


class DriverMethodTests(unittest2.TestCase):
    def test_method(self):
        self.assertTrue(DriverMethod(FakeDriver, 'ex_create_fake'))

# Path: libcloud_rest/api/providers.py
# class DriverMethod(object):
#     _type_name_pattern = r'.\{([_0-9a-zA-Z]+)\}'
# 
#     def __init__(self, driver_obj, method_name):
#         if inspect.isclass(driver_obj):
#             self.driver_cls = driver_obj
#         else:
#             self.driver_cls = driver_obj.__class__
#         self.driver_obj = driver_obj
#         self.method_name = method_name
#         self.method = getattr(self.driver_obj, method_name, None)
#         if not inspect.ismethod(self.method):
#             raise NoSuchOperationError()
#         method_doc = get_method_docstring(self.driver_cls, method_name)
#         if not method_doc:
#             raise MethodParsingException('Empty docstring')
#         argspec_arg = parse_args(self.method)
#         docstring_parse_result = parse_docstring(method_doc, self.driver_cls)
#         self.description = docstring_parse_result['description']
#         docstring_args = docstring_parse_result['arguments']
#         #check vargs
#         self.vargs_entries = []
#         for name, arg_info in argspec_arg.iteritems():
#             if name in docstring_args:
#                 docstring_arg = docstring_args[name]
#                 entry_kwargs = {
#                     'name': name,
#                     'description': docstring_arg['description'],
#                     'type_name': docstring_arg['type_name'],
#                     'required': (docstring_arg['required'] or
#                                  arg_info['required']),
#                 }
#                 if not entry_kwargs['required'] and 'default' in arg_info:
#                     entry_kwargs['default'] = arg_info['default']
#                 self.vargs_entries.append(Entry(**entry_kwargs))
#             else:
#                 raise MethodParsingException(
#                     '%s %s not described in docstring' % (method_name, name))
#             #update kwargs
#         kwargs = set(docstring_args).difference(argspec_arg)
#         self.kwargs_entries = [Entry(arg_name, **docstring_args[arg_name])
#                                for arg_name in kwargs]
#         method_return = docstring_parse_result['return']
#         self.result_entry = Entry('', method_return['type_name'],
#                                   method_return['description'], True)
# 
#     @classmethod
#     def _remove_type_name_brackets(cls, type_name):
#         return re.sub(cls._type_name_pattern, r'\1', type_name)
# 
#     def get_description(self):
#         result_arguments = []
#         for entry in self.vargs_entries:
#             result_arguments.extend(entry.get_arguments())
#         for entry in self.kwargs_entries:
#             result_arguments.extend(entry.get_arguments())
#         result = {'name': self.method_name,
#                   'description': self.description,
#                   'arguments': result_arguments,
#                   'return': {
#                       'type': self._remove_type_name_brackets(
#                           self.result_entry.type_name),
#                       'description': self.result_entry.description}
#                   }
#         return result
# 
#     def invoke_result_to_json(self, value):
#         return self.result_entry.to_json(value)
# 
#     def invoke(self, data):
#         vargs = [e.from_json(data, self.driver_obj)
#                  for e in self.vargs_entries]
#         kwargs = {}
#         for kw_entry in self.kwargs_entries:
#             try:
#                 kwargs[kw_entry.name] = kw_entry.from_json(data,
#                                                            self.driver_obj)
#             except MissingArguments:
#                 if kw_entry.required:
#                     raise
#         if self.method_name == '__init__':
#             return self.driver_cls(*vargs, **kwargs)
#         return self.method(*vargs, **kwargs)


# Path: tests/test_providers.py
import unittest2
from libcloud_rest.api.providers import DriverMethod
from libcloud_rest.errors import NoSuchOperationError, MethodParsingException

    def setUp(self):
        self.driver_method = DriverMethod(FakeDriver, 'ex_create_fake')

    def test_get_description(self):
        data = self.driver_method.get_description()
        self.assertEqual('ex_create_fake', data['name'])
        self.assertEqual('teachess volume to node.',  data['description'])
        arguments = data['arguments']
        node = {'required': True, 'type': 'str', 'name': 'node_id',
                'description': 'ID of the node which should be used'}
        volume = {'required': True, 'type': 'str', 'name': 'volume',
                  'description': 'Volume to attach'}
        device = {'required': True, 'type': 'str', 'name': 'device',
                  'description': "Where the device is exposed, "
                                 "e.g. '/dev/sdb (required)"}
        extra_dict = {'required': False, 'type': 'dict', 'name': 'extra',
                      'description': 'Extra attributes (driver specific).'}
        extra_str = {'required': False, 'type': 'str', 'name': 'extra',
                     'description': 'Extra attributes (driver specific).'}
        varg = {'default': 'value', 'required': False, 'type': 'str',
                'name': 'varg', 'description': 'with default value'}
        kwarg = {'required': False, 'type': 'str',
                 'name': 'kwarg', 'description': 'Keyword argument'}
        test_args = [node, volume, device, extra_dict, extra_str, varg, kwarg]
        self.assertEqual(arguments, test_args)


class DriverMethodTests(unittest2.TestCase):
    def test_method(self):
        self.assertTrue(DriverMethod(FakeDriver, 'ex_create_fake'))

        self.assertRaises(NoSuchOperationError, DriverMethod, FakeDriver,