Esempio n. 1
0
def run_suite():
    global passed
    global failed
    global num_skipped
    global expectations

    passed = 0
    failed = 0
    num_skipped = 0
    expectations = 0

    start_time = time.time()
    walk(join(REPO_DIR, 'clox', 'test', 'lox'), run_script)
    time_passed = time.time() - start_time

    term.print_line()
    
    print()

    if failed == 0:
        print('All {} tests passed ({} expectations) in {:.2f} seconds.'.format(
            term.green(passed), str(expectations), time_passed))
    else:
        print('{} tests passed and {} tests failed in {:.2f} seconds.'.format(
            term.green(passed), term.red(failed), time_passed))

    return failed == 0
Esempio n. 2
0
def run_suite(name):
    global interpreter
    global passed
    global failed
    global num_skipped
    global expectations

    interpreter = INTERPRETERS[name]

    passed = 0
    failed = 0
    num_skipped = 0
    expectations = 0

    walk(join(REPO_DIR, 'test'), run_script)
    term.print_line()

    if failed == 0:
        print('All {} tests passed ({} expectations).'.format(
            term.green(passed), str(expectations)))
    else:
        print('{} tests passed. {} tests failed.'.format(
            term.green(passed), term.red(failed)))

    return failed == 0
Esempio n. 3
0
    def _get_attrib(self, attr, convert_to_str=False):
        """
        Given an attribute name, looks it up on the entry. Names that
        start with ``tags.`` are looked up in the ``tags`` dictionary.

        :param attr: Name of attribute to look up.
        :type attr: ``str``
        :param convert_to_str: Convert result to a string.
        :type convert_to_str: ``bool``

        :rtype: ``object``
        """
        if attr.startswith('tags.'):
            tag = attr[len('tags.'):]
            if tag in self.tags and self.tags[tag] != '':
                return self.tags[tag]
            elif convert_to_str is True:
                return '<not set>'
            else:
                return self.tags.get(tag)
        elif not hasattr(self, attr):
            raise AttributeError('Invalid attribute: {0}. Perhaps you meant '
                                 '{1}?'.format(red(attr),
                                               green('tags.' + attr)))
        else:
            result = getattr(self, attr)
            if convert_to_str is True and not result:
                return '<none>'
            elif convert_to_str is True and isinstance(result, list):
                return ', '.join(result)
            elif convert_to_str is True:
                return str(result)
            else:
                return result
Esempio n. 4
0
 def render(self) -> str:
     guess = self.guess if self.is_filled() else ' '
     assert guess is not None
     if self.status is Status.PENCILLED_IN:
         guess = term.dim(guess)
     elif self.status is Status.MARKED_WRONG:
         guess = term.red(guess)
     elif self.status is Status.MARKED_RIGHT:
         guess = term.green(guess)
     elif self.status is Status.REVEALED:
         guess = term.blue(guess)
     return f' {guess} '
Esempio n. 5
0
def run_script(path):
  if "benchmark" in path: return

  global passed
  global failed
  global num_skipped

  if (splitext(path)[1] != '.lox'):
    return

  # Check if we are just running a subset of the tests.
  if filter_path:
    this_test = relpath(path, join(REPO_DIR, 'test'))
    if not this_test.startswith(filter_path):
      return

  # Make a nice short path relative to the working directory.

  # Normalize it to use "/" since, among other things, the interpreters expect
  # the argument to use that.
  path = relpath(path).replace("\\", "/")

  # Update the status line.
  term.print_line('Passed: {} Failed: {} Skipped: {} {}'.format(
      term.green(passed),
      term.red(failed),
      term.yellow(num_skipped),
      term.gray('({})'.format(path))))

  # Read the test and parse out the expectations.
  test = Test(path)

  if not test.parse():
    # It's a skipped or non-test file.
    return

  test.run()

  # Display the results.
  if len(test.failures) == 0:
    passed += 1
  else:
    failed += 1
    term.print_line(term.red('FAIL') + ': ' + path)
    print('')
    for failure in test.failures:
      print('      ' + term.pink(failure))
    print('')
Esempio n. 6
0
    def render_entries(cls, entries, additional_columns=None,
                       only_show=None, numbers=False):
        """
        Pretty-prints a list of entries. If the window is wide enough to
        support printing as a table, runs the `print_table.render_table`
        function on the table. Otherwise, constructs a line-by-line
        representation..

        :param entries: A list of entries.
        :type entries: [:py:class:`HostEntry`]
        :param additional_columns: Columns to show in addition to defaults.
        :type additional_columns: ``list`` of ``str``
        :param only_show: A specific list of columns to show.
        :type only_show: ``NoneType`` or ``list`` of ``str``
        :param numbers: Whether to include a number column.
        :type numbers: ``bool``

        :return: A pretty-printed string.
        :rtype: ``str``
        """
        additional_columns = additional_columns or []
        if only_show is not None:
            columns = _uniquify(only_show)
        else:
            columns = _uniquify(cls.DEFAULT_COLUMNS + additional_columns)
        top_row = map(cls.prettyname, columns)
        table = [top_row] if numbers is False else [[''] + top_row]
        for i, entry in enumerate(entries):
            row = [entry._get_attrib(c, convert_to_str=True) for c in columns]
            table.append(row if numbers is False else [i] + row)
        cur_width = get_current_terminal_width()
        colors = [get_color_hash(c, 100, 150) for c in columns]
        if cur_width >= get_table_width(table):
            return render_table(table,
                                column_colors=colors if numbers is False
                                              else [green] + colors)
        else:
            result = []
            first_index = 1 if numbers is True else 0
            for row in table[1:]:
                rep = [green('%s:' % row[0] if numbers is True else '-----')]
                for i, val in enumerate(row[first_index:]):
                    color = colors[i-1 if numbers is True else i]
                    name = columns[i]
                    rep.append('  %s: %s' % (name, color(val)))
                result.append('\n'.join(rep))
            return '\n'.join(result)
Esempio n. 7
0
File: build.py Progetto: zyeri/clox
def build_sass(skip_up_to_date):
    '''Process each SASS file.'''
    imports_mod = None
    for source in glob.iglob("asset/sass/*.scss"):
        import_mod = os.path.getmtime(source)
        if not imports_mod: imports_mod = import_mod
        imports_mod = max(imports_mod, import_mod)

    for source in glob.iglob("asset/*.scss"):
        dest = "site/" + os.path.basename(source).split(".")[0] + ".css"

        if skip_up_to_date:
            source_mod = max(os.path.getmtime(source), imports_mod)
            dest_mod = os.path.getmtime(dest)
            if source_mod < dest_mod:
                continue

        subprocess.call(['sass', source, dest])
        print("{} {}".format(term.green("•"), source))
  for snippet_name in snippets:
    snippet = source_code.snippet_tags[chapter][snippet_name]
    split_chapters.split_chapter(chapter, snippet)

    build_name = "{}-{:02}-{}".format(chapter_dir, snippet.index, snippet_name)
    snippet_dir = "{:02}-{}".format(snippet.index, snippet_name)
    source_dir = os.path.join("gen", "snippets", chapter_dir, snippet_dir)

    args = [
      "make",
      "-f", "util/c.make",
      "NAME=" + build_name,
      "MODE=release",
      "SOURCE_DIR=" + source_dir,
      "SNIPPET=true"
    ]
    proc = Popen(args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
    out, err = proc.communicate()

    if proc.returncode != 0:
      print("{} {} / {}".format(term.red("FAIL"), chapter, snippet_name))
      print(out.decode('utf-8'))
      print(err.decode('utf-8'))
      print()
      all_passed = False
    else:
      print("{} {} / {}".format(term.green("PASS"), chapter, snippet_name))

if not all_passed:
  sys.exit(1)
Esempio n. 9
0
def print_tb(tb, nlines=5, ncols=80):
    """Pretty print the traceback TB.  NLINES of Python source lines are
    displayed.  All output lines are fitted within NCOLS column."""
    f = tb.tb_frame
    lineno = tb.tb_lineno
    co = f.f_code
    filename = co.co_filename
    name = co.co_name

    # display frame header
    name_str = term.blue(name, True)
    filename_str = term.green(filename)
    _print('----', name_str, filename_str)

    # display source lines
    linecache.checkcache(filename)
    errline = ''
    for n in range(lineno - nlines + 1, lineno + 1):
        line = linecache.getline(filename, n, f.f_globals).rstrip()
        if line is not None:
            lineno_str = term.gray('{:5} '.format(n))
            _print(lineno_str, end='')
            if n == lineno:
                line_str = term.red(line)
                errline = line
            else:
                line_str = term.reset(line)
            _print(line_str)

    def _by_location(key):
        pos = errline.find(key)
        if 0 <= pos <= 255:
            # keys matching the error line come first
            return chr(pos)
        elif key.startswith('__'):
            # keys starting with __ come last
            return '~' + key
        else:
            # sorted in the alphabetical order
            return key

    # dump all local variables in the frame
    keys = sorted(f.f_locals.keys(), key=_by_location)
    for key in keys:
        key_str = term.yellow('{:>20}'.format(key))
        if key in set([
                'linecache', 'pdb', 'sys', 'os', 're', 'term', 'traceback',
                '__builtins__'
        ]):
            _print(key_str, '= ...')
            continue
        else:
            val_str = trimmed_str(repr(f.f_locals[key]), ncols - 20)
            _print(key_str, '=', val_str)

        # dump all attributes for objects
        attr = getattr(f.f_locals[key], '__dict__', None)
        if attr:
            keys = sorted(attr.keys(), key=_by_location)
            for key in keys:
                key_str = term.cyan('{:>28}'.format(key))
                val_str = trimmed_str(repr(attr[key]), ncols - 28)
                _print(key_str, val_str)
Esempio n. 10
0
File: build.py Progetto: zyeri/clox
def format_file(path, skip_up_to_date, dependencies_mod):
    basename = os.path.basename(path)
    basename = basename.split('.')[0]

    output_path = "site/" + basename + ".html"

    # See if the HTML is up to date.
    if skip_up_to_date:
        source_mod = max(os.path.getmtime(path), dependencies_mod)
        dest_mod = os.path.getmtime(output_path)

        if source_mod < dest_mod:
            return

    title = ''
    title_html = ''
    part = None
    template_file = 'page'

    errors = []
    sections = []
    header_index = 0
    subheader_index = 0
    has_challenges = False
    design_note = None
    snippets = None

    # Read the markdown file and preprocess it.
    contents = ''
    with open(path, 'r') as input:
        # Read each line, preprocessing the special codes.
        for line in input:
            stripped = line.lstrip()
            indentation = line[:len(line) - len(stripped)]

            if line.startswith('^'):
                command, _, arg = stripped.rstrip('\n').lstrip('^').partition(
                    ' ')
                arg = arg.strip()

                if command == 'title':
                    title = arg
                    title_html = title

                    # Remove any discretionary hyphens from the title.
                    title = title.replace('&shy;', '')

                    # Load the code snippets now that we know the title.
                    snippets = source_code.find_all(title)

                    # If there were any errors loading the code, include them.
                    if title in book.CODE_CHAPTERS:
                        errors.extend(source_code.errors[title])
                elif command == 'part':
                    part = arg
                elif command == 'template':
                    template_file = arg
                elif command == 'code':
                    contents = insert_snippet(snippets, arg, contents, errors)
                else:
                    raise Exception('Unknown command "^{} {}"'.format(
                        command, arg))

            elif stripped.startswith('## Challenges'):
                has_challenges = True
                contents += '<h2><a href="#challenges" name="challenges">Challenges</a></h2>\n'

            elif stripped.startswith('## Design Note:'):
                has_design_note = True
                design_note = stripped[len('## Design Note:') + 1:]
                contents += '<h2><a href="#design-note" name="design-note">Design Note: {}</a></h2>\n'.format(
                    design_note)

            elif stripped.startswith('# ') or stripped.startswith(
                    '## ') or stripped.startswith('### '):
                # Build the section navigation from the headers.
                index = stripped.find(" ")
                header_type = stripped[:index]
                header = pretty(stripped[index:].strip())
                anchor = book.get_file_name(header)
                anchor = re.sub(r'[.?!:/"]', '', anchor)

                # Add an anchor to the header.
                contents += indentation + header_type

                if len(header_type) == 2:
                    header_index += 1
                    subheader_index = 0
                    page_number = book.chapter_number(title)
                    number = '{0}&#8202;.&#8202;{1}'.format(
                        page_number, header_index)
                elif len(header_type) == 3:
                    subheader_index += 1
                    page_number = book.chapter_number(title)
                    number = '{0}&#8202;.&#8202;{1}&#8202;.&#8202;{2}'.format(
                        page_number, header_index, subheader_index)

                header_line = '<a href="#{0}" name="{0}"><small>{1}</small> {2}</a>\n'.format(
                    anchor, number, header)
                contents += header_line

                # Build the section navigation.
                if len(header_type) == 2:
                    sections.append([header_index, header])

            else:
                contents += pretty(line)

    # Validate that every snippet for the chapter is included.
    for name, snippet in snippets.items():
        if name != 'not-yet' and name != 'omit' and snippet != False:
            errors.append("Unused snippet {}".format(name))

    # Show any errors at the top of the file.
    if errors:
        error_markdown = ""
        for error in errors:
            error_markdown += "**Error: {}**\n\n".format(error)
        contents = error_markdown + contents

    # Fix up em dashes. We do this on the entire contents instead of in pretty()
    # so that we can handle surrounding whitespace even when the "--" is at the
    # beginning of end of a line in Markdown.
    contents = EM_DASH_PATTERN.sub('<span class="em">&mdash;</span>', contents)

    # Allow processing markdown inside some tags.
    contents = contents.replace('<aside', '<aside markdown="1"')
    contents = contents.replace('<div class="challenges">',
                                '<div class="challenges" markdown="1">')
    contents = contents.replace('<div class="design-note">',
                                '<div class="design-note" markdown="1">')
    body = markdown.markdown(contents,
                             extensions=['extra', 'codehilite', 'smarty'])

    # Turn aside markers in code into spans. In the empty span case, insert a
    # zero-width space because Chrome seems to lose the span's position if it has
    # no content.
    # <span class="c1">// [repl]</span>
    body = ASIDE_COMMENT_PATTERN.sub(r'<span name="\1">&#8203;</span>', body)
    body = ASIDE_WITH_COMMENT_PATTERN.sub(
        r'<span class="c1" name="\2">// \1</span>', body)

    up = 'Table of Contents'
    if part:
        up = part
    elif title == 'Table of Contents':
        up = 'Crafting Interpreters'

    data = {
        'title': title,
        'part': part,
        'body': body,
        'sections': sections,
        'chapters': get_part_chapters(title),
        'design_note': design_note,
        'has_challenges': has_challenges,
        'number': book.chapter_number(title),
        'prev': book.adjacent_page(title, -1),
        'prev_type': book.adjacent_type(title, -1),
        'next': book.adjacent_page(title, 1),
        'next_type': book.adjacent_type(title, 1),
        'up': up,
        'toc': book.TOC
    }

    template = environment.get_template(template_file + '.html')
    output = template.render(data)

    # Write the output.
    with codecs.open(output_path, "w", encoding="utf-8") as out:
        out.write(output)

    global total_words
    global num_chapters
    global empty_chapters

    word_count = len(contents.split(None))
    num = book.chapter_number(title)
    if num:
        num = '{}. '.format(num)

    # Non-chapter pages aren't counted like regular chapters.
    if part:
        num_chapters += 1
        if word_count < 50:
            empty_chapters += 1
            print("    " + term.gray("{}{}".format(num, title)))
        elif part != "Backmatter" and word_count < 2000:
            empty_chapters += 1
            print("  {} {}{} ({} words)".format(term.yellow("-"), num, title,
                                                word_count))
        else:
            total_words += word_count
            print("  {} {}{} ({} words)".format(term.green("✓"), num, title,
                                                word_count))
    elif title in ["Crafting Interpreters", "Table of Contents"]:
        print("{} {}{}".format(term.green("•"), num, title))
    else:
        if word_count < 50:
            print("    " + term.gray("{}{}".format(num, title)))
        else:
            print("{} {}{} ({} words)".format(term.green("✓"), num, title,
                                              word_count))