def syntax_testing(self, stream, package): total_assertions = 0 failed_assertions = 0 try: tests = sublime.find_resources("syntax_test*") if package != "__all__": tests = [t for t in tests if t.startswith("Packages/%s/" % package)] # remove UnitTesting syntax_tests tests = [t for t in tests if not t.startswith("Packages/UnitTesting/")] if not tests: raise RuntimeError("No syntax_test files are found in %s!" % package) for t in tests: assertions, test_output_lines = sublime_api.run_syntax_test(t) total_assertions += assertions if len(test_output_lines) > 0: failed_assertions += len(test_output_lines) for line in test_output_lines: stream.write(line + "\n") if failed_assertions > 0: stream.write("FAILED: %d of %d assertions in %d files failed\n" % (failed_assertions, total_assertions, len(tests))) else: stream.write("Success: %d assertions in %s files passed\n" % (total_assertions, len(tests))) stream.write("OK\n") except Exception as e: if not stream.closed: stream.write("ERROR: %s\n" % e) stream.write("\n") stream.write(DONE_MESSAGE) stream.close()
def _test_syntaxes(self, name, configuration, tests): test_working_path = TESTS_PATH / name test_working_path.file_path().mkdir(parents=True) build_configurations({name: configuration}, test_working_path) syntax_path = test_working_path / (name + '.sublime-syntax') yield syntax_path.exists yield SYNTAX_DELAY # Hope this gives Sublime long enough to compile it. syntax_test_header = '// SYNTAX TEST "{!s}"\n'.format(syntax_path) all_failures = [] for test_source in self.all_tests: if test_source.parent.name in tests: test_dest = test_working_path / test_source.name text = test_source.read_text().split('\n', 1)[1] with test_dest.file_path().open('w', encoding='utf-8') as file: file.write(syntax_test_header) file.write(text) yield test_dest.exists assertion_count, failures = sublime_api.run_syntax_test( str(test_dest)) if failures and failures[0].endswith( 'does not match scope [text.plain]'): raise RuntimeError( 'Sublime did not compile {!s} in time.'.format( test_dest)) else: all_failures.extend(failures) self.assertEqual(all_failures, [])
def run(self, cmd, code): """Perform linting.""" if not code: return # The syntax test runner only operates on resource files that the resource loader can load, # which must reside in a "Packages" folder # and has the restriction of only working on saved files. with _temporary_resource_file(code, prefix="syntax_test_") as resource_path: # Some change in ST caused the newly created file not to get picked up in time, # so we add an artificial delay. # This is a sucky solution, # but I can't think of anything else. # TOFIX Remove this hack import time time.sleep(0.2) assertions, test_output_lines = sublime_api.run_syntax_test( resource_path) logger.debug('assertions: {}'.format(assertions)) output = "\n".join(test_output_lines) if "unable to read file" in output: logger.error(output) return output
def syntax_testing(self, package, stream): output = "" total_assertions = 0 failed_assertions = 0 if version < "3103": stream.write("Warning: Syntax test is only avaliable on Sublime Text >3103.\n") stream.write("OK\n") stream.close() return try: tests = sublime.find_resources("syntax_test*") tests = [t for t in tests if t.startswith("Packages/%s/" % package)] if not tests: raise RuntimeError("No syntax_test files are found in %s!" % package) for t in tests: assertions, test_output_lines = sublime_api.run_syntax_test(t) total_assertions += assertions if len(test_output_lines) > 0: failed_assertions += len(test_output_lines) for line in test_output_lines: stream.write(line + "\n") if failed_assertions > 0: stream.write("FAILED: %d of %d assertions in %d files failed\n" % (failed_assertions, total_assertions, len(tests))) else: stream.write("Success: %d assertions in %s files passed\n" % (total_assertions, len(tests))) stream.write("OK\n") except Exception as e: if not stream.closed: stream.write("ERROR: %s\n" % e) stream.close()
def run(self, cmd, code): """Check if file is 'lintable' and perform linting.""" # It has to start with `"syntax_test"` # and has a specific first line, technically. # We only require one of each # (to also lint unsaved views). basename = os.path.basename(self.filename) if not basename or not basename.startswith("syntax_test"): # This actually gets reported by the test runner, # so we only check for an additionally qualifying file # if the filename check fails. first_line = code[:code.find("\n")] match = re.match(r'^(\S*) SYNTAX TEST "([^"]*)"', first_line) if not match: return # The syntax test runner only operates on resource files that the resource loader can load, # which must reside in a "Packages" folder # and has the restriction of only working on saved files. # Instead, we create a temporary file somewhere in the packages folder # and pass that. with _temporary_resource_file(code, prefix="syntax_test_") as resource_path: assertions, test_output_lines = sublime_api.run_syntax_test( resource_path) output = "\n".join(test_output_lines) if persist.debug_mode(): persist.printf('{}: "{}" assertions: {}'.format( p_name, basename, assertions)) # SublimeLinter internally already prints the output we return # persist.printf('{}: "{}" output: \n {}'.format(p_name, basename, # "\n ".join(test_output_lines))) return output
def _test_syntaxes(self, *, name, configuration, tests, exclude=[]): test_working_path = TESTS_PATH / name test_working_path.file_path().mkdir(parents=True) output = OutputPanel.create(sublime.active_window(), 'YAMLMacros') syntax_path = test_working_path / (name + '.sublime-syntax') build_configuration(name, configuration, syntax_path.file_path(), output) sublime.run_command( 'build_js_custom_tests', { 'syntax_path': str(syntax_path), 'suites': tests, 'exclude': exclude, 'destination_directory': str(test_working_path.file_path()), }) yield syntax_path.exists yield SYNTAX_DELAY # Hope this gives Sublime long enough to compile it. all_failures = [] for test_dest in test_working_path.glob('syntax_test*'): assertion_count, failures = sublime_api.run_syntax_test( str(test_dest)) if failures and failures[0].endswith( 'does not match scope [text.plain]'): raise RuntimeError( 'Sublime did not compile {!s} in time.'.format(test_dest)) else: all_failures.extend(failures) self.assertEqual(all_failures, [])
def run(self): totalFiles = 0 totalAssertions = 0 totalFailedAssertions = 0 testsPath = packages_path() + '/Naomi/tests/syntaxes' self.outputPanel = OutputPanel(self.sublime_window, {'name': 'naomi'}) self.outputPanel.show() self.outputPanel.append('Naomi: Running syntax tests...') # Find the test files and run them. for path, directories, files in os.walk(testsPath): for file in files: # Get the full path to the file. target = os.path.join(path, file) # Remove anything before "Packages/Naomi". target = target[target.index('Packages/Naomi'):] # Run the tests. assertionsFound, messagesFound = run_syntax_test(target) # Print the error messages and update the counters. if messagesFound != '': for message in messagesFound: self.outputPanel.append(message) totalFailedAssertions += 1 totalFiles += 1 totalAssertions += assertionsFound if totalFailedAssertions < 1: self.outputPanel.append('Success: %d assertion(s) in %d file(s).' % (totalAssertions, totalFiles)) else: self.outputPanel.append( 'Error: %d/%d assertion(s) in %d file(s) failed.' % (totalFailedAssertions, totalAssertions, totalFiles))
def run(self, file_regex = "", line_regex = "", working_dir = "", quiet = False, word_wrap = True, syntax = "Packages/Text/Plain text.tmLanguage", **kwargs): if not hasattr(self, 'output_view'): # Try not to call get_output_panel until the regexes are assigned self.output_view = self.window.create_output_panel("exec") # Default the to the current files directory if no working directory was given if (working_dir == "" and self.window.active_view() and self.window.active_view().file_name()): working_dir = os.path.dirname(self.window.active_view().file_name()) self.output_view.settings().set("result_file_regex", file_regex) self.output_view.settings().set("result_line_regex", line_regex) self.output_view.settings().set("result_base_dir", working_dir) self.output_view.settings().set("word_wrap", word_wrap) self.output_view.settings().set("line_numbers", False) self.output_view.settings().set("gutter", False) self.output_view.settings().set("scroll_past_end", False) self.output_view.assign_syntax(syntax) # Call create_output_panel a second time after assigning the above # settings, so that it'll be picked up as a result buffer self.window.create_output_panel("exec") show_panel_on_build = sublime.load_settings("Preferences.sublime-settings").get("show_panel_on_build", True) if show_panel_on_build: self.window.run_command("show_panel", {"panel": "output.exec"}) # Change to the working dir, rather than spawning the process with it, # so that emitted working dir relative path names make sense if working_dir != "": os.chdir(working_dir) output = "" tests = sublime.find_resources("syntax_test*") num_failed = 0 for t in tests: test_output = sublime_api.run_syntax_test(t) if len(test_output) > 0: num_failed += 1 output += test_output + "\n" self.append_string(output) if num_failed > 0: self.append_string("FAILED: %d of %d tests failed\n" % (num_failed, len(tests))) else: self.append_string("Success: %d tests passed\n" % len(tests)) self.append_string("[Finished]")
def _test_syntaxes(self, *, name, configuration, tests, exclude=[]): test_working_path = TESTS_PATH / name test_working_path.file_path().mkdir(parents=True) syntax_path = test_working_path / (name + '.sublime-syntax') sublime.active_window().run_command( 'build_js_custom_syntax', { 'name': name, 'configuration': configuration, 'destination_path': str(syntax_path.file_path()), }) sublime.run_command( 'build_js_custom_tests', { 'syntax_path': str(syntax_path), 'suites': tests, 'exclude': exclude, 'destination_directory': str(test_working_path.file_path()), }) def syntax_exists(): syntax = sublime.syntax_from_path(str(syntax_path)) return syntax is not None yield syntax_exists all_failures = [] for test_dest in test_working_path.glob('syntax_test*'): yield 1 _, failures = sublime_api.run_syntax_test(str(test_dest)) if failures and failures[0].endswith( 'does not match scope [text.plain]'): raise RuntimeError( 'Sublime did not compile {!s} in time.'.format(test_dest)) else: all_failures.extend(failures) self.assertEqual(all_failures, [])
def run(self, cmd, code): """Perform linting.""" if not code: return # The syntax test runner only operates on resource files that the resource loader can load, # which must reside in a "Packages" folder # and has the restriction of only working on saved files. with _temporary_resource_file(code, prefix="syntax_test_") as resource_path: # Some change in ST caused the newly created file not to get picked up in time, # so we wait until the file can be loaded. import time start_time = time.time() while time.time() <= start_time + 1: try: sublime.load_binary_resource(resource_path) except OSError: logger.debug( "ST couldn't find our temporary file; re-polling…") time.sleep(0.1) else: break else: logger.warning( "Waiting for ST to find our temporary file '%r' timed out", resource_path) assertions, test_output_lines = sublime_api.run_syntax_test( resource_path) logger.debug('assertions: {}'.format(assertions)) output = "\n".join(test_output_lines) if "unable to read file" in output: logger.error(output) return output
def run(self, find_all=False, **kwargs): if not hasattr(self, 'output_view'): # Try not to call get_output_panel until the regexes are assigned self.output_view = self.window.create_output_panel('exec') settings = self.output_view.settings() settings.set('result_file_regex', PACKAGES_FILE_REGEX) settings.set('result_base_dir', sublime.packages_path()) settings.set('word_wrap', True) settings.set('line_numbers', False) settings.set('gutter', False) settings.set('scroll_past_end', False) # Call create_output_panel a second time after assigning the above # settings, so that it'll be picked up as a result buffer self.window.create_output_panel('exec') if not find_all: relative_path = package_relative_path(self.window.active_view()) if not relative_path: return file_name = os.path.basename(relative_path) if is_syntax(relative_path): tests = [] for t in sublime.find_resources('syntax_test*'): first_line = sublime.load_resource(t).splitlines()[0] match = re.match('^.*SYNTAX TEST "(.*?)"', first_line) if not match: continue syntax = match.group(1) if syntax == relative_path or syntax == file_name: tests.append(t) elif file_name.startswith('syntax_test'): tests = [relative_path] else: sublime.error_message( 'The current file is not a *.sublime-syntax, *.tmLanguage ' 'or syntax_test* file') return else: tests = sublime.find_resources('syntax_test*') show_panel_on_build(self.window) total_assertions = 0 failed_assertions = 0 for t in tests: assertions, test_output_lines = sublime_api.run_syntax_test(t) total_assertions += assertions if len(test_output_lines) > 0: failed_assertions += len(test_output_lines) for line in test_output_lines: append(self.output_view, line + '\n') if failed_assertions > 0: message = 'FAILED: {} of {} assertions in {} files failed\n' params = (failed_assertions, total_assertions, len(tests)) else: message = 'Success: {} assertions in {} files passed\n' params = (total_assertions, len(tests)) append(self.output_view, message.format(*params)) append(self.output_view, '[Finished]')
def run(self, file_regex = "", line_regex = "", working_dir = "", quiet = False, word_wrap = True, syntax = "Packages/Text/Plain text.tmLanguage", find_all = False, **kwargs): if not hasattr(self, 'output_view'): # Try not to call get_output_panel until the regexes are assigned self.output_view = self.window.create_output_panel("exec") # Default the to the current files directory if no working directory was given if (working_dir == "" and self.window.active_view() and self.window.active_view().file_name()): working_dir = os.path.dirname(self.window.active_view().file_name()) self.output_view.settings().set("result_file_regex", file_regex) self.output_view.settings().set("result_line_regex", line_regex) self.output_view.settings().set("result_base_dir", working_dir) self.output_view.settings().set("word_wrap", word_wrap) self.output_view.settings().set("line_numbers", False) self.output_view.settings().set("gutter", False) self.output_view.settings().set("scroll_past_end", False) self.output_view.assign_syntax(syntax) # Call create_output_panel a second time after assigning the above # settings, so that it'll be picked up as a result buffer self.window.create_output_panel("exec") tests = sublime.find_resources("syntax_test*") if not find_all: path = None file_name = None relative_path = None packages_path = sublime.packages_path() data_dir = os.path.dirname(packages_path) + os.sep view = self.window.active_view() if view: path = view.file_name() file_name = os.path.basename(path) if path.startswith(data_dir): relative_path = "Packages" + path[len(packages_path):] # Detect symlinked files that are opened from outside of the Packages dir else: prefix = os.path.dirname(path) suffix = file_name while not prefix.endswith(os.sep): if os.path.exists(os.path.join(packages_path, suffix)): relative_path = os.path.join("Packages", suffix) break prefix, tail = os.path.split(prefix) suffix = os.path.join(tail, suffix) if relative_path and os.name == 'nt': relative_path = relative_path.replace('\\', '/') is_syntax = path and path.endswith('.sublime-syntax') or path.endswith('.tmLanguage') if is_syntax: new_tests = [] for t in tests: first_line = sublime.load_resource(t).splitlines()[0] match = re.match('^.*SYNTAX TEST "(.*?)"', first_line) if match: syntax_path = match.group(1) if syntax_path == relative_path or syntax_path == file_name: new_tests.append(t) tests = new_tests elif relative_path and file_name.startswith('syntax_test'): tests = [relative_path] else: sublime.error_message("The current file is not a *.sublime-syntax, *.tmLanguage or syntax_test* file") return show_panel_on_build = sublime.load_settings("Preferences.sublime-settings").get("show_panel_on_build", True) if show_panel_on_build: self.window.run_command("show_panel", {"panel": "output.exec"}) output = "" total_assertions = 0 failed_assertions = 0 for t in tests: assertions, test_output_lines = sublime_api.run_syntax_test(t) total_assertions += assertions if len(test_output_lines) > 0: failed_assertions += len(test_output_lines) for line in test_output_lines: output += line + "\n" self.append_string(output) if failed_assertions > 0: self.append_string( "FAILED: %d of %d assertions in %d files failed\n" % (failed_assertions, total_assertions, len(tests)) ) else: self.append_string( "Success: %d assertions in %s files passed\n" % (total_assertions, len(tests)) ) self.append_string("[Finished]")