mock_utils.py 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. # Copyright (C) 2017 YouCompleteMe contributors
  2. #
  3. # This file is part of YouCompleteMe.
  4. #
  5. # YouCompleteMe is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # YouCompleteMe is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with YouCompleteMe. If not, see <http://www.gnu.org/licenses/>.
  17. from __future__ import unicode_literals
  18. from __future__ import print_function
  19. from __future__ import division
  20. from __future__ import absolute_import
  21. # Not installing aliases from python-future; it's unreliable and slow.
  22. from builtins import * # noqa
  23. import mock
  24. import requests
  25. class FakeResponse( object ):
  26. """A fake version of a requests response object, just about suitable for
  27. mocking a server response. Not usually used directly. See
  28. MockServerResponse* methods"""
  29. def __init__( self, response, exception ):
  30. self._json = response
  31. self._exception = exception
  32. self.status_code = requests.codes.ok
  33. self.text = not exception
  34. def json( self ):
  35. if self._exception:
  36. return None
  37. return self._json
  38. def raise_for_status( self ):
  39. if self._exception:
  40. raise self._exception
  41. class FakeFuture( object ):
  42. """A fake version of a future response object, just about suitable for
  43. mocking a server response as generated by PostDataToHandlerAsync.
  44. Not usually used directly. See MockAsyncServerResponse* methods"""
  45. def __init__( self, done, response = None, exception = None ):
  46. self._done = done
  47. if not done:
  48. self._result = None
  49. else:
  50. self._result = FakeResponse( response, exception )
  51. def done( self ):
  52. return self._done
  53. def result( self ):
  54. return self._result
  55. def MockAsyncServerResponseDone( response ):
  56. """Return a fake future object that is complete with the supplied response
  57. message. Suitable for mocking a response future within a client request. For
  58. example:
  59. server_message = {
  60. 'message': 'this message came from the server'
  61. }
  62. with patch.object( ycm._message_poll_request,
  63. '_response_future',
  64. new = MockAsyncServerResponseDone( [] ) ) as mock_future:
  65. ycm.OnPeriodicTick() # Uses ycm._message_poll_request ...
  66. """
  67. return mock.MagicMock( wraps = FakeFuture( True, response ) )
  68. def MockAsyncServerResponseInProgress():
  69. """Return a fake future object that is incomplete. Suitable for mocking a
  70. response future within a client request. For example:
  71. with patch.object( ycm._message_poll_request,
  72. '_response_future',
  73. new = MockAsyncServerResponseInProgress() ):
  74. ycm.OnPeriodicTick() # Uses ycm._message_poll_request ...
  75. """
  76. return mock.MagicMock( wraps = FakeFuture( False ) )
  77. def MockAsyncServerResponseException( exception ):
  78. """Return a fake future object that is complete, but raises an exception.
  79. Suitable for mocking a response future within a client request. For example:
  80. exception = RuntimeError( 'Check client handles exception' )
  81. with patch.object( ycm._message_poll_request,
  82. '_response_future',
  83. new = MockAsyncServerResponseException( exception ) ):
  84. ycm.OnPeriodicTick() # Uses ycm._message_poll_request ...
  85. """
  86. return mock.MagicMock( wraps = FakeFuture( True, None, exception ) )
  87. # TODO: In future, implement MockServerResponse and MockServerResponseException
  88. # for synchronous cases when such test cases are needed.