text: from subprocess import PIPE
  from pathlib import PosixPath, Path
  from mock import patch, Mock
  from oops import main, conf, types
  from tests.utils import Rule, Command
  
  
  def test_load_rule():
      match = object()
      get_new_command = object()
      with patch('oops.main.load_source',
                 return_value=Mock(
                     match=match,
                     get_new_command=get_new_command,
                     enabled_by_default=True)) as load_source:
          assert main.load_rule(Path('/rules/bash.py')) \
                 == Rule('bash', match, get_new_command)
          load_source.assert_called_once_with('bash', '/rules/bash.py')
  
  
  def test_get_rules():
      with patch('oops.main.Path.glob') as glob, \
              patch('oops.main.load_source',
                    lambda x, _: Mock(match=x, get_new_command=x,
                                      enabled_by_default=True)):
          glob.return_value = [PosixPath('bash.py'), PosixPath('lisp.py')]
          assert list(main.get_rules(
              Path('~'),
              Mock(rules=conf.DEFAULT_RULES))) \
                 == [Rule('bash', 'bash', 'bash'),
                     Rule('lisp', 'lisp', 'lisp'),
                     Rule('bash', 'bash', 'bash'),
                     Rule('lisp', 'lisp', 'lisp')]
          assert list(main.get_rules(
              Path('~'),
              Mock(rules=types.RulesNamesList(['bash'])))) \
                 == [Rule('bash', 'bash', 'bash'),
                     Rule('bash', 'bash', 'bash')]
  
  
  def test_get_command():
      with patch('oops.main.Popen') as Popen, \
              patch('oops.main.os.environ',
                    new_callable=lambda: {}), \
              patch('oops.main.wait_output',
                    return_value=True):
          Popen.return_value.stdout.read.return_value = b'stdout'
          Popen.return_value.stderr.read.return_value = b'stderr'
          assert main.get_command(Mock(), ['oops', 'apt-get',
                                           'search', 'vim']) \
                 == Command('apt-get search vim', 'stdout', 'stderr')
          Popen.assert_called_once_with('apt-get search vim',
                                        shell=True,
                                        stdout=PIPE,
                                        stderr=PIPE,
                                        env={'LANG': 'C'})
          assert main.get_command(Mock(), ['']) is None
  
  
  def test_get_matched_rule(capsys):
      rules = [Rule('', lambda x, _: x.script == 'cd ..'),
               Rule('', lambda *_: False),
               Rule('rule', Mock(side_effect=OSError('Denied')))]
      assert main.get_matched_rule(Command('ls'),
                                   rules, Mock(no_colors=True)) is None
      assert main.get_matched_rule(Command('cd ..'),
                                   rules, Mock(no_colors=True)) == rules[0]
      assert capsys.readouterr()[1].split('\n')[0] \
             == '[WARN] Rule rule:'
  
  
  def test_run_rule(capsys):
      with patch('oops.main.confirm', return_value=True):
          main.run_rule(Rule(get_new_command=lambda *_: 'new-command'),
                        None, None)
          assert capsys.readouterr() == ('new-command\n', '')
      with patch('oops.main.confirm', return_value=False):
          main.run_rule(Rule(get_new_command=lambda *_: 'new-command'),
                        None, None)
          assert capsys.readouterr() == ('', '')
  
  
  def test_confirm(capsys):
      # When confirmation not required:
      assert main.confirm('command', Mock(require_confirmation=False))
      assert capsys.readouterr() == ('', 'command\n')
      # When confirmation required and confirmed:
      with patch('oops.main.sys.stdin.read', return_value='\n'):
          assert main.confirm('command', Mock(require_confirmation=True,
                                              no_colors=True))
          assert capsys.readouterr() == ('', 'command [enter/ctrl+c]')
      # When confirmation required and ctrl+c:
      with patch('oops.main.sys.stdin.read', side_effect=KeyboardInterrupt):
          assert not main.confirm('command', Mock(require_confirmation=True,
                                                  no_colors=True))
          assert capsys.readouterr() == ('', 'command [enter/ctrl+c]Aborted\n')
  