# Path: spanner_orm/decorator.py
# T = TypeVar('T')
# def transactional_read(func: Callable[..., T]) -> Callable[..., T]:
# def transactional_write(func: Callable[..., T]) -> Callable[..., T]:
# def _transactional(spanner_api_method_lambda: Callable[[], Callable[..., T]],
#                    func: Callable[..., T]) -> Callable[..., T]:
#   def wrapper(*args, **kwargs) -> T:
#     def spanner_wrapper(transaction) -> T:


import logging
import unittest
from unittest import mock
from absl.testing import parameterized
from spanner_orm import decorator


class DecoratorTest(parameterized.TestCase):

  @parameterized.parameters(
      (decorator.transactional_read, 'run_read_only'),
      (decorator.transactional_write, 'run_write'),
  )
  @mock.patch('spanner_orm.api.spanner_api')
  def test_transactional_injects_new_transaction(self, decorator_in_test,
                                                 method_name_to_mock,
                                                 mock_spanner_api):
    mock_tx = mock.Mock()
    mock_api_method = getattr(mock_spanner_api.return_value,
                              method_name_to_mock)
    mock_api_method.side_effect = mock_spanner_method(mock_tx)

    @decorator_in_test
    def get_book(book_id, method=None, transaction=None):
      self.assertEqual(mock_tx, transaction)
      self.assertEqual(123, book_id)
      self.assertEqual('library', method)

      return 200

    result = get_book(123, method='library')
    self.assertEqual(200, result)
    mock_api_method.assert_called_once()

  @parameterized.parameters(decorator.transactional_read,

# Path: spanner_orm/decorator.py
# T = TypeVar('T')
# def transactional_read(func: Callable[..., T]) -> Callable[..., T]:
# def transactional_write(func: Callable[..., T]) -> Callable[..., T]:
# def _transactional(spanner_api_method_lambda: Callable[[], Callable[..., T]],
#                    func: Callable[..., T]) -> Callable[..., T]:
#   def wrapper(*args, **kwargs) -> T:
#     def spanner_wrapper(transaction) -> T:


# Path: spanner_orm/tests/decorator_test.py
import logging
import unittest
from unittest import mock
from absl.testing import parameterized
from spanner_orm import decorator



class DecoratorTest(parameterized.TestCase):

  @parameterized.parameters(
      (decorator.transactional_read, 'run_read_only'),
      (decorator.transactional_write, 'run_write'),
  )
  @mock.patch('spanner_orm.api.spanner_api')
  def test_transactional_injects_new_transaction(self, decorator_in_test,
                                                 method_name_to_mock,
                                                 mock_spanner_api):
    mock_tx = mock.Mock()
    mock_api_method = getattr(mock_spanner_api.return_value,
                              method_name_to_mock)
    mock_api_method.side_effect = mock_spanner_method(mock_tx)

    @decorator_in_test
    def get_book(book_id, method=None, transaction=None):
      self.assertEqual(mock_tx, transaction)
      self.assertEqual(123, book_id)
      self.assertEqual('library', method)

      return 200

    result = get_book(123, method='library')
    self.assertEqual(200, result)
    mock_api_method.assert_called_once()

  @parameterized.parameters(decorator.transactional_read,

                            decorator.transactional_write)