"""Test suite for prance.BaseParser ."""

__author__ = 'Jens Finkhaeuser'
__copyright__ = 'Copyright (c) 2016-2021 Jens Finkhaeuser'
__license__ = 'MIT'
__all__ = ()

import pytest

from prance import BaseParser
from prance import ValidationError
from prance.util.fs import FileNotFoundError

from . import none_of


@pytest.fixture
def petstore_parser():
  return BaseParser('tests/specs/petstore.yaml')


@pytest.fixture
def petstore_parser_from_string():
  yaml = None
  with open('tests/specs/petstore.yaml', 'rb') as f:
    x = f.read()
    yaml = x.decode('utf8')
  return BaseParser(spec_string = yaml)


def test_load_fail():
  from prance.util.url import ResolutionError
  with pytest.raises(ResolutionError):
    BaseParser('tests/specs/missing.yaml')


def test_parse_fail():
  with pytest.raises(ValidationError):
    BaseParser(spec_string = """---
invalid 'a'sda YAML""")


def test_version_fail():
  with pytest.raises(ValidationError):
    BaseParser(spec_string = """---
openapi: 4.0.0""")


def test_filename_or_spec():
  with pytest.raises(AssertionError):
    BaseParser('', '')


@pytest.mark.skipif(none_of('openapi-spec-validator', 'swagger-spec-validator', 'flex'), reason='Backends missing.')
def test_load_and_parse_valid(petstore_parser):
  assert petstore_parser.specification, 'No specs loaded!'


@pytest.mark.skipif(none_of('openapi-spec-validator', 'swagger-spec-validator', 'flex'), reason='Backends missing.')
def test_load_and_parse_lazy():
  parser = BaseParser('tests/specs/petstore.yaml', lazy = True)
  assert parser.specification is None, 'Should not have specs yet!'

  parser.parse()
  assert parser.specification, 'No specs loaded!'


@pytest.mark.skipif(none_of('openapi-spec-validator', 'swagger-spec-validator', 'flex'), reason='Backends missing.')
def test_yaml_valid(petstore_parser):
  assert petstore_parser.yaml(), 'Did not get YAML representation of specs!'


@pytest.mark.skipif(none_of('openapi-spec-validator', 'swagger-spec-validator', 'flex'), reason='Backends missing.')
def test_json_valid(petstore_parser):
  assert petstore_parser.json(), 'Did not get JSON representation of specs!'


@pytest.mark.skipif(none_of('openapi-spec-validator', 'swagger-spec-validator', 'flex'), reason='Backends missing.')
def test_cache_specs_mixin(petstore_parser):
  # In order to test the caching, we need to first use either the YAML or the
  # JSON mixin. Let's use YAML, because it's more swagger-ish
  yaml = petstore_parser.yaml()
  assert yaml, 'Did not get YAML representation of specs!'

  # Caching should mean that if the specifications do not change, then neither
  # does the YAML repersentation.
  assert yaml == petstore_parser.yaml(), 'YAML representation changed!'

  # In fact, the objects shouldn't even change.
  assert id(yaml) == id(petstore_parser.yaml()), 'YAML did not change but '\
      'got regenerated!'

  # However, when the specs change, then so must the YAML representation.
  petstore_parser.specification['foo'] = 'bar'
  assert yaml != petstore_parser.yaml(), 'YAML representation did not change!'


@pytest.mark.skipif(none_of('openapi-spec-validator', 'swagger-spec-validator', 'flex'), reason='Backends missing.')
def test_relative_urls_from_string(petstore_parser_from_string):
  # This must succeed
  assert petstore_parser_from_string.yaml(), 'Did not get YAML representation of specs!'
