text: # -*- coding: UTF-8 -*-
  #
  # Copyright 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved.
  #
  # Licensed under the Apache License, Version 2.0 (the "License"). You
  # may not use this file except in compliance with the License. A copy of
  # the License is located at
  #
  # http://aws.amazon.com/apache2.0/
  #
  # or in the "license" file accompanying this file. This file is
  # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
  # ANY KIND, either express or implied. See the License for the specific
  # language governing permissions and limitations under the License.
  import sys
  
  import mock
  import unittest
  
  from ebcli.core import io
  
  
  class TestIo(unittest.TestCase):
      @mock.patch('ebcli.core.io.prompt')
      def test_prompt_for_environment_name(self, mock_prompt):
          invalid_cases = [
              'Inv@lid',
              'sml',
              'this-name-is-definitely-too-long-like-seriously-who-does-this',
              'bad:char',
              'bad_char',
              'bad+char',
              'bad=char',
              'bad?char',
              'bad>char',
              'bad\\char',
              'bad/char',
              'bad#char',
              'bad?char',
              '-startswithhyphen',
              'endswithhyphen-',
              '-bothsideshyphen-',
              'spaces are bad',
              # end in valid case for loop completion
              'standard-name',
          ]
  
          valid_cases = [
              'ALL-UPPER',
              'MiXeD-CaSe',
              'normal-env-name',
              '1starts-with-num',
              'ends-with-num1',
              'has0-nums1-23422',
              'this-name-is-just-right',
              'this-name-is-now-fine-99',
              '1234567890123456789012345678901234567890',
              'four']
  
          mock_prompt.side_effect = invalid_cases
  
          result = io.prompt_for_environment_name()
          self.assertEqual(result, 'standard-name')
          self.assertEqual(mock_prompt.call_count, len(invalid_cases))
  
          mock_prompt.side_effect = valid_cases
          for case in valid_cases:
              value = io.prompt_for_environment_name()
              self.assertEqual(value, case)
  
      @mock.patch('ebcli.core.io.get_input')
      def test_get_boolean_response(self, get_input_mock):
          get_input_mock.return_value = 'y'
          result = io.get_boolean_response()
          get_input_mock.assert_called_once_with('(Y/n)', default='y')
          self.assertTrue(result)
  
      @mock.patch('ebcli.core.io.get_input')
      def test_get_boolean_response__text_sans_default(self, get_input_mock):
          get_input_mock.return_value = 'y'
          result = io.get_boolean_response(text='This is the prompt text.')
          get_input_mock.assert_called_once_with(
              'This is the prompt text. (Y/n)',
              default='y')
          self.assertTrue(result)
  
      @mock.patch('ebcli.core.io.get_input')
      def test_get_boolean_response__text_default_false(self, get_input_mock):
          get_input_mock.return_value = 'y'
          result = io.get_boolean_response(
              text='This is the prompt text.',
              default=False)
          get_input_mock.assert_called_once_with(
              'This is the prompt text. (y/N)',
              default='n')
          self.assertTrue(result)
  
      @mock.patch('ebcli.core.io.get_input')
      def test_get_boolean_response__bad_input(self, get_input_mock):
          response_list = ['a', '1', 'Ys', 'x', '', 'nah', '?', 'y']
          get_input_mock.side_effect = response_list
          result = io.get_boolean_response()
  
          self.assertTrue(result)
          self.assertEqual(get_input_mock.call_count, len(response_list))
  
      @mock.patch('ebcli.core.io.get_input')
      def test_get_boolean_response_true(self, get_input_mock):
          get_input_mock.side_effect = ['y', 'Y', 'YES', 'yes', 'Yes']
  
          result1 = io.get_boolean_response()
          result2 = io.get_boolean_response()
          result3 = io.get_boolean_response()
          result4 = io.get_boolean_response()
          result5 = io.get_boolean_response()
          self.assertTrue(result1)
          self.assertTrue(result2)
          self.assertTrue(result3)
          self.assertTrue(result4)
          self.assertTrue(result5)
  
      @mock.patch('ebcli.core.io.get_input')
      def test_get_boolean_response_false(self, get_input_mock):
          get_input_mock.side_effect = ['n', 'N', 'NO', 'no', 'No']
          result1 = io.get_boolean_response()
          result2 = io.get_boolean_response()
          result3 = io.get_boolean_response()
          result4 = io.get_boolean_response()
          result5 = io.get_boolean_response()
          self.assertFalse(result1)
          self.assertFalse(result2)
          self.assertFalse(result3)
          self.assertFalse(result4)
          self.assertFalse(result5)
  
      @mock.patch('ebcli.core.io.sys')
      def test_event_streamer(self, mock_sys):
          mock_sys.stdout.isatty.return_value = True
          with mock.patch('ebcli.core.io.echo') as echo_mocked:
              streamer = io.get_event_streamer()
              streamer.stream_event("msg1")
              streamer.stream_event("msg2")
              echo_mocked.assert_called_with(streamer.prompt, end='')
              streamer.end_stream()
          self.assertEqual(streamer.eventcount, 2, "Expected event count to be 2 but was: {0}".format(streamer.eventcount))
  
      @mock.patch('ebcli.core.io.sys')
      def test_event_streamer_with_unsafe_exit(self, mock_sys):
          mock_sys.stdout.isatty.return_value = True
          with mock.patch('ebcli.core.io.echo') as echo_mocked:
              streamer = io.get_event_streamer()
              streamer.stream_event("msg1", safe_to_quit=False)
              echo_mocked.assert_called_with(streamer.unsafe_prompt, end='')
              streamer.end_stream()
          self.assertEqual(streamer.eventcount, 1, "Expected event count to be 1 but was: {0}".format(streamer.eventcount))
  
      @mock.patch('ebcli.core.io.sys')
      def test_pipe_streamer(self, mock_sys):
          mock_sys.stdout.isatty.return_value = False
          message = "msg1"
          with mock.patch('ebcli.core.io.echo') as echo_mocked:
              streamer = io.get_event_streamer()
              streamer.stream_event(message)
              echo_mocked.assert_called_with(message)
              streamer.end_stream()
          self.assertEqual(streamer.eventcount, 0, "Expected event count to be 0 but was: {0}".format(streamer.eventcount))
  
      @mock.patch('sys.stdout.isatty')
      def test_term_is_colorable(self, isatty_mock):
          isatty_mock.return_value = True
  
          self.assertTrue(io.term_is_colorable())
  
      @mock.patch('sys.stdout.isatty')
      def test_term_is_colorable(self, isatty_mock):
          isatty_mock.return_value = False
  
          self.assertFalse(io.term_is_colorable())
  
      def test_convert_to_string(self):
          class DummyObj:
              def __str__(self):
                  return 'dummy_object'
  
          self.assertEqual('asasdad', io._convert_to_string('asasdad'))
  
          self.assertEqual('ßßßßß', io._convert_to_string(u'ßßßßß'))
          self.assertEqual('ßßßßß', io._convert_to_string(u'ßßßßß'.encode('utf-8')))
  
          self.assertEqual('10', io._convert_to_string(int(10)))
          self.assertEqual('10.09876', io._convert_to_string(10.09876))
          if sys.version_info < (3, 0):
              self.assertEqual('10', io._convert_to_string(long(10)))
  
          self.assertEqual('dummy_object', io._convert_to_string(DummyObj()))
  
      @mock.patch('ebcli.core.io.colorama.init')
      @mock.patch('ebcli.core.io.term_is_colorable')
      def test_bold(
              self,
              term_is_colorable_mock,
              init_mock
      ):
          term_is_colorable_mock.return_value = True
          self.assertEqual('\x1b[1mßßßßß\x1b[22m', io.bold(u'ßßßßß'))
          init_mock.assert_called_once()
  
      @mock.patch('ebcli.core.io.colorama.init')
      @mock.patch('ebcli.core.io.term_is_colorable')
      def test_bold__term_is_not_colorable(
              self,
              term_is_colorable_mock,
              init_mock
      ):
          term_is_colorable_mock.return_value = False
          self.assertEqual('ßßßßß', io.bold(u'ßßßßß'))
          init_mock.assert_not_called()
  
      def test_remap_color(self):
          self.assertEqual('YELLOW', io._remap_color('ORANGE'))
          self.assertEqual('WHITE', io._remap_color('GRAY'))
          self.assertEqual('WHITE', io._remap_color('GREY'))
          self.assertEqual('SOmE OtHEr cOLoR', io._remap_color('SOmE OtHEr cOLoR'))
  
      @mock.patch('ebcli.core.io.colorama.init')
      @mock.patch('ebcli.core.io.term_is_colorable')
      def test_color(
              self,
              term_is_colorable_mock,
              init_mock
      ):
          term_is_colorable_mock.return_value = True
          self.assertEqual('\x1b[33mßßßßß\x1b[39m', io.color('ORANGE', u'ßßßßß'))
  
          init_mock.assert_called_once()
  
      @mock.patch('ebcli.core.io.colorama.init')
      @mock.patch('ebcli.core.io.term_is_colorable')
      def test_color__term_is_not_colorable(
              self,
              term_is_colorable_mock,
              init_mock
      ):
          term_is_colorable_mock.return_value = False
          self.assertEqual('ßßßßß', io.color('ORANGE', u'ßßßßß'))
  
          init_mock.assert_not_called()
  
      @mock.patch('ebcli.core.io.colorama.init')
      @mock.patch('ebcli.core.io.term_is_colorable')
      def test_on_color(
              self,
              term_is_colorable_mock,
              init_mock
      ):
          term_is_colorable_mock.return_value = True
          self.assertEqual('\x1b[43mßßßßß\x1b[49m', io.on_color('ORANGE', u'ßßßßß'))
  
          init_mock.assert_called_once()
  
      @mock.patch('ebcli.core.io.colorama.init')
      @mock.patch('ebcli.core.io.term_is_colorable')
      def test_on_color__term_is_not_colorable(
              self,
              term_is_colorable_mock,
              init_mock
      ):
          term_is_colorable_mock.return_value = False
          self.assertEqual('ßßßßß', io.on_color('ORANGE', u'ßßßßß'))
  
          init_mock.assert_not_called()
  
      @mock.patch('ebcli.core.io.print_')
      def test_echo_and_justify(self, print_mock):
          io.echo_and_justify(4, 'how ', 'now ', 'brown ', 'cow ')
  
          print_mock.assert_called_once_with('how now brown cow')
  
      @mock.patch('ebcli.core.io.print_')
      def test_echo(self, print_mock):
          io.echo(
              'how ', 'now ', 'brown ', 'cow ',
              sep=','
          )
  
          print_mock.assert_called_once_with('how ', 'now ', 'brown ', 'cow ', sep=',')
  
      @mock.patch('ebcli.core.io.echo')
      def test_log_alert(self, echo_mock):
          io.log_alert('hello, world!')
  
          echo_mock.assert_called_once_with('Alert:', 'hello, world!')
  
      @mock.patch('ebcli.core.io.ebglobals')
      @mock.patch('ebcli.core.io.echo')
      def test_log_info(
              self,
              echo_mock,
              ebglobals_mock
      ):
          io.log_info('hello, world!')
          echo_mock.assert_not_called()
  
      @mock.patch('ebcli.core.io.ebglobals', spec={})
      @mock.patch('ebcli.core.io.echo')
      def test_log_info__cement_application_not_defined_yet(
              self,
              echo_mock,
              ebglobals_mock
      ):
          io.log_info('hello, world!')
          echo_mock.assert_called_once_with('INFO: hello, world!')
  
      @mock.patch('ebcli.core.io.ebglobals')
      @mock.patch('ebcli.core.io.echo')
      def test_log_warning(
              self,
              echo_mock,
              ebglobals_mock
      ):
          io.log_warning('hello, world!')
          echo_mock.assert_not_called()
  
      @mock.patch('ebcli.core.io.ebglobals', spec={})
      @mock.patch('ebcli.core.io.echo')
      def test_log_warning__cement_application_not_defined_yet(
              self,
              echo_mock,
              ebglobals_mock
      ):
          io.log_warning('hello, world!')
          echo_mock.assert_called_once_with('WARN: hello, world!')
  
      @mock.patch('ebcli.core.io.ebglobals')
      def test_log_error__debug_mode(
              self,
              ebglobals_mock
      ):
          ebglobals_mock.app.pargs.debug = True
          io.log_error('hello, world!')
          ebglobals_mock.app.log.error.asswert_called_once_with()
  
      @mock.patch('ebcli.core.io.ebglobals')
      @mock.patch('ebcli.core.io.echo')
      def test_log_error(
              self,
              echo_mock,
              ebglobals_mock
      ):
          ebglobals_mock.app.pargs.debug = False
  
          io.log_error('hello, world!')
  
          ebglobals_mock.app.log.error.assert_not_called()
          echo_mock.assert_called_once_with('ERROR: hello, world!')
  
      @mock.patch('ebcli.core.io.ebglobals', spec={})
      @mock.patch('ebcli.core.io.echo')
      def test_log_error__cement_app_not_initialized_yet(
              self,
              echo_mock,
              ebglobals_mock
      ):
          io.log_error('hello, world!')
  
          echo_mock.assert_called_once_with('ERROR: hello, world!')
  
      @mock.patch('ebcli.core.io._get_input')
      def test_get_input(self, _get_input_mock):
          _get_input_mock.return_value = 'customer input'
          self.assertEqual(
              'customer input',
              io.get_input('some prompt')
          )
  
          _get_input_mock.assert_called_once_with('some prompt')
  
      @mock.patch('ebcli.core.io._get_input')
      def test_get_input__use_default(self, _get_input_mock):
          _get_input_mock.return_value = ''
          self.assertEqual(
              'default customer input',
              io.get_input('some prompt', default='default customer input')
          )
  
          _get_input_mock.assert_called_once_with('some prompt')
  
      @mock.patch('ebcli.core.io.pydoc.pager')
      def test_echo_with_pager(self, pager_mock):
          io.echo_with_pager('some text')
          pager_mock.assert_called_once_with('some text')
  
      @mock.patch('ebcli.core.io.get_input')
      def test_prompt(self, get_input_mock):
          get_input_mock.return_value = '10'
  
          io.prompt('some text', default='22')
  
          get_input_mock.assert_called_once_with('(some text)', '22')
  
      def test_prompt_for_unique_name__default_is_the_list(self):
          with self.assertRaises(AssertionError) as context_manager:
              io.prompt_for_unique_name('default', ['default', 'default_2'])
          self.assertEqual('Default name is not unique', str(context_manager.exception))
  
      @mock.patch('ebcli.core.io.prompt')
      @mock.patch('ebcli.core.io.echo')
      def test_prompt_for_unique_name__default_is_the_list(
              self,
              echo_mock,
              prompt_mock
      ):
          prompt_mock.side_effect = [
              'name_1',
              'name_2',
              'name_3',
          ]
          self.assertEqual(
              'name_3',
              io.prompt_for_unique_name('default', ['name_1', 'name_2'])
          )
  
          echo_mock.assert_has_calls(
              [
                  mock.call('Sorry that name already exists, try another.'),
                  mock.call('Sorry that name already exists, try another.')
              ]
          )
  
      @mock.patch('ebcli.core.io.getpass.getpass')
      def test_get_pass__gets_right_first_time(
              self,
              get_pass_mock
      ):
          get_pass_mock.side_effect = [
              'password',
              'password',
          ]
  
          self.assertEqual(
              'password',
              io.get_pass('')
          )
  
      @mock.patch('ebcli.core.io.getpass.getpass')
      def test_get_pass__gets_right_second_time(
              self,
              get_pass_mock
      ):
          get_pass_mock.side_effect = [
              'password',
              'passwor∂',
              'password',
              'password',
          ]
  
          self.assertEqual(
              'password',
              io.get_pass('')
          )
  
          self.assertEqual(4, get_pass_mock.call_count)
  
      @mock.patch('ebcli.core.io.get_input')
      def test_validate_action__mismatch(
              self,
              get_input_mock
      ):
          get_input_mock.return_value = 'unexpected_input'
  
          with self.assertRaises(io.ValidationError) as context_manager:
              io.validate_action('customer prompt', 'expected_input')
  
          self.assertEqual('Names do not match. Exiting.', str(context_manager.exception))
  
      @mock.patch('ebcli.core.io.get_input')
      def test_validate_action(
              self,
              get_input_mock
      ):
          get_input_mock.return_value = 'expected_input'
  
          io.validate_action('customer prompt', 'expected_input')
  
      @mock.patch('ebcli.core.io.sys.stdout.write')
      def test_update_upload_progress__progress_is_between_zero_and_one(
              self,
              write_mock
      ):
          io.update_upload_progress(0.50)
  
          write_mock.assert_called_once_with(
              '\rUploading: [#########################-------------------------] 50% '
          )
  
      @mock.patch('ebcli.core.io.sys.stdout.write')
      def test_update_upload_progress__progress_is_negative(
              self,
              write_mock
      ):
          io.update_upload_progress(-1)
  
          write_mock.assert_called_once_with(
              '\rUploading: [--------------------------------------------------] 0% Halt...\r\n'
          )
  
      @mock.patch('ebcli.core.io.sys.stdout.write')
      def test_update_upload_progress__progress_is_zero(
              self,
              write_mock
      ):
          io.update_upload_progress(0)
  
          write_mock.assert_called_once_with(
              '\rUploading: [--------------------------------------------------] 0% '
          )
  
      @mock.patch('ebcli.core.io.sys.stdout.write')
      def test_update_upload_progress__progress_is_non_numerical(
              self,
              write_mock
      ):
          io.update_upload_progress('a')
  
          write_mock.assert_called_once_with(
              '\rUploading: [--------------------------------------------------] 0% error: progress var must be float\r\n'
          )
  
      @mock.patch('ebcli.core.io.sys.stdout.write')
      def test_update_upload_progress__progress_is_complete(
              self,
              write_mock
      ):
          io.update_upload_progress(1)
  
          write_mock.assert_called_once_with(
              '\rUploading: [##################################################] 100% Done...\r\n'
          )
  