示例#1
0
    def _is_valid(self,
                  log_file: Optional[Union[Logger, TextIO]] = None) -> bool:
        log = Logger() if log_file is None else log_file if isinstance(
            log_file, Logger) else Logger(log_file)
        nerrors = log.nerrors

        if self._context.TYPE and getattr(self, self._context.TYPE, "") != self._class_name \
                and self._class_name not in self._context.TYPE_EXCEPTIONS:
            if log.log("Type mismatch - Expected: {} Actual: {}".format(
                    self._class_name, getattr(self, self._context.TYPE))):
                return False

        for name in self._members.keys():
            entry = getattr(self, name)
            if not self._is_valid_element(log, name, entry):
                return False

        if self._strict:
            # Test each attribute against the schema
            for k, v in self._strip_nones(self.__dict__).items():
                if k not in self._members and k != self._context.TYPE \
                        and k not in self._context.IGNORE and k != "@context":
                    if not self._is_valid_element(log, k, v):
                        if log.log("Extra element: {}: {}".format(k, v)):
                            return False

        return log.nerrors == nerrors
示例#2
0
 def _is_valid_element(self, log: Logger, name: str,
                       val: Type[JSGValidateable]) -> bool:
     if name not in self._members:
         return any(e._is_valid_element for e in self._reference_types)
     else:
         etype = self._members[name]
         if etype is JSGNull:
             return val is JSGNull or val is None
         if val is None and type(etype) is type(AnyType):
             return False
         if val is not None and val is not Empty and isinstance(
                 val, JSGArray):
             if not val._validate(cast(list, val),
                                  log)[0] and not log.logging:
                 return False
         elif not conforms(val, etype, self._context.NAMESPACE
                           ):  # Note: None and absent are equivalent
             if val is None or val is Empty:
                 if log.log("{}: Missing required field: '{}'".format(
                         self.__class__.__name__, name)):
                     return False
             else:
                 if log.log(
                         "{}: Type mismatch for {}. Expecting: {} Got: {}".
                         format(self.__class__.__name__, name, etype,
                                type(val))):
                     return False
         elif val is not None and not self._test(
                 val, log):  # Make sure that entry conforms to its own type
             return False
     return True
示例#3
0
 def _is_valid(self, log_file: Optional[Union[Logger, TextIO]] = None) -> bool:
     log = Logger() if log_file is None else log_file if isinstance(log_file, Logger) else Logger(log_file)
     nerrors = log.nerrors
     nitems = len(self._strip_nones(self.__dict__))
     if nitems < self._min:
         if log.log(f"Number of elements is {nitems} which is less than the minimum number ({self._min})"):
             return False
     if self._max is not None and nitems > self._max:
         if log.log(f"Number of elements is {nitems} which is greater than the minimum number ({self._max})"):
             return False
     super()._is_valid(log)
     return nerrors == log.nerrors
示例#4
0
 def _is_valid_element(self, log: Logger, name: str,
                       entry: Type[JSGValidateable]) -> bool:
     if self._name_filter is not None:
         if not self._name_filter.matches(name):
             #if log.log(f"Illegal Object Map key: {name}={entry}"):
             if log.log("Illegal Object Map key: " + name + "=" + entry):
                 return False
     return super()._is_valid_element(log, name, entry)
示例#5
0
class JSGReadMeTestCase(unittest.TestCase):

    log = Logger(sys.stdout)

    def eval_for_error(self, fn: str, mod, error: str):
        fn_in_json = json_load(fn)
        expected = fn_in_json._ERROR
        del fn_in_json._ERROR
        with self.assertRaises(ValueError) as context:
            r = load(fn, mod)
        self.assertEqual(expected, str(context.exception))

    def eval_python(self, cwd: str, dirpath: str, fn: str) -> None:
        basefile = fn.rsplit('.', 1)[0]
        outfile = os.path.abspath(os.path.join(cwd, "py", basefile + ".py"))
        self.assertEqual(
            0,
            generate([
                os.path.relpath(os.path.join(dirpath, fn)), "-o", outfile,
                "-nh"
            ]))
        mod = import_module("tests_standalone.test_jsg_readme.py." + basefile)
        num_evaluated = 0
        for dirpath, _, filenames in os.walk(os.path.join(cwd, "json")):
            for filename in filenames:
                if filename.startswith(basefile) and filename.endswith(
                        ".json"):
                    num_evaluated += 1
                    full_fn = os.path.join(dirpath, filename)
                    if "_f" not in os.path.basename(full_fn):
                        r = load(full_fn, mod)
                        self.assertTrue(r._is_valid(log))
                    else:
                        self.eval_for_error(
                            full_fn, mod,
                            "ValueError: Unknown attribute: text=left in 2017")
        # TODO: complete this test
        # self.assertTrue(num_evaluated > 0, f"{fn} has no json equivalents")

    @unittest.skipIf(
        False,
        "This test has to be run alone -- namespace conflicts otherwise ")
    def test_jsg_readme(self):
        cwd = os.path.abspath(os.path.dirname(__file__))
        num_evaluated = 0
        for dirpath, _, filenames in os.walk(os.path.join(cwd, "jsg")):
            for fn in filenames:
                if fn.endswith(".jsg"):
                    num_evaluated += 1
                    self.eval_python(cwd, dirpath, fn)
        self.assertEqual(6, num_evaluated)

    @unittest.skipIf(True, "Outsdanding issue here on get")
    def test_gsg_1(self):
        # TODO: Fix this problem!
        self.assertTrue(False, "Rename ge1_f1.json to get.json")
示例#6
0
 def _jsg_type_for(self, name: str, element: Any,
                   poss_types: Union[type, Tuple[type]]) -> JSGValidateable:
     et = self._map_jsg_type(name, element, poss_types)
     if et is not None:
         return et
     #raise ValueError(f"Wrong type for {name}: {Logger.json_repr(element)} - expected:"
     #                 f" {poss_types} got {type(element).__name__}")
     raise ValueError("Wrong type for " + name + ": " +
                      Logger.json_repr(element) + " - expected: " +
                      poss_types + " got " + type(element.__name__))
示例#7
0
import sys
import os
import unittest

from importlib import import_module

from pyjsg.jsglib.loader import load
from pyjsg.jsglib.logger import Logger
from pyjsg.parser_impl.generate_python import generate
from jsonasobj import load as json_load

log = Logger(sys.stdout)


class JSGReadMeTestCase(unittest.TestCase):

    log = Logger(sys.stdout)

    def eval_for_error(self, fn: str, mod, error: str):
        fn_in_json = json_load(fn)
        expected = fn_in_json._ERROR
        del fn_in_json._ERROR
        with self.assertRaises(ValueError) as context:
            r = load(fn, mod)
        self.assertEqual(expected, str(context.exception))

    def eval_python(self, cwd: str, dirpath: str, fn: str) -> None:
        basefile = fn.rsplit('.', 1)[0]
        outfile = os.path.abspath(os.path.join(cwd, "py", basefile + ".py"))
        self.assertEqual(
            0,