<s> import sys <EOL> import os . path <EOL> sys . path . insert ( <NUM_LIT:0> , os . path . dirname ( os . path . abspath ( __file__ ) ) ) <EOL> import threading <EOL> import subprocess <EOL> import time <EOL> import sublime <EOL> import sublime_plugin <EOL> import logging <EOL> import logging . handlers <EOL> logger = logging . getLogger ( '<STR_LIT>' ) <EOL> logger . debug ( '<STR_LIT>' , __name__ ) <EOL> try : <EOL> from . test_runner import parsers <EOL> from . test_runner . decorators import throttle <EOL> except ( ValueError ) : <EOL> from test_runner import parsers <EOL> from test_runner . decorators import throttle <EOL> def plugin_loaded ( ) : <EOL> global package_name <EOL> if st_version == <NUM_LIT:3> : <EOL> package_name , _ = __name__ . split ( '<STR_LIT:.>' ) <EOL> elif st_version == <NUM_LIT:2> : <EOL> package_name = os . path . basename ( os . getcwd ( ) ) <EOL> setup_logger ( ) <EOL> def setup_logger ( ) : <EOL> global logger <EOL> log_levels = { <EOL> '<STR_LIT>' : logging . CRITICAL , <EOL> '<STR_LIT>' : logging . ERROR , <EOL> '<STR_LIT>' : logging . WARNING , <EOL> '<STR_LIT>' : logging . INFO , <EOL> '<STR_LIT>' : logging . DEBUG <EOL> } <EOL> settings . clear_on_change ( '<STR_LIT>' ) <EOL> logger . handlers = [ ] <EOL> formatter = logging . Formatter ( '<STR_LIT>' ) <EOL> log_path = os . path . join ( sublime . installed_packages_path ( ) , package_name + '<STR_LIT>' ) <EOL> hdlr = logging . handlers . TimedRotatingFileHandler ( log_path , interval = <NUM_LIT:1> , backupCount = <NUM_LIT:4> ) <EOL> hdlr . setFormatter ( formatter ) <EOL> logger . addHandler ( hdlr ) <EOL> log_level = settings . get ( '<STR_LIT>' , '<STR_LIT>' ) . upper ( ) <EOL> logger . setLevel ( log_levels [ log_level ] ) <EOL> logger . info ( '<STR_LIT>' % log_level ) <EOL> settings . add_on_change ( '<STR_LIT>' , setup_logger ) <EOL> class Settings ( ) : <EOL> def __init__ ( self ) : <EOL> self . s = None <EOL> def load ( self ) : <EOL> if self . s is None : <EOL> self . s = sublime . load_settings ( '<STR_LIT>' ) <EOL> def get ( self , key , default = None ) : <EOL> self . load ( ) <EOL> value = self . s . get ( key , default ) <EOL> return value or default <EOL> def set ( self , key , value ) : <EOL> self . load ( ) <EOL> return self . s . set ( key , value ) <EOL> def add_on_change ( self , key , on_change ) : <EOL> self . load ( ) <EOL> self . s . add_on_change ( key , on_change ) <EOL> def clear_on_change ( self , key ) : <EOL> self . load ( ) <EOL> self . s . clear_on_change ( key ) <EOL> def project_directory ( path ) : <EOL> path = os . path . normpath ( os . path . dirname ( path ) ) <EOL> path_parts = path . split ( os . path . sep ) <EOL> spec_filenames = settings . get ( '<STR_LIT>' , [ ] ) <EOL> while path_parts : <EOL> for spec_directory in spec_filenames : <EOL> joined = os . path . normpath ( <EOL> os . path . sep . join ( path_parts + [ spec_directory ] ) <EOL> ) <EOL> if os . path . exists ( joined ) : <EOL> project_directory_path = os . path . normpath ( os . path . sep . join ( path_parts ) ) <EOL> return project_directory_path <EOL> path_parts . pop ( ) <EOL> class RunTestsCommand ( sublime_plugin . TextCommand ) : <EOL> description = '<STR_LIT>' <EOL> def run ( self , * args , ** kwargs ) : <EOL> logger . debug ( '<STR_LIT>' % ( kwargs ) ) <EOL> command = settings . get ( '<STR_LIT>' ) <EOL> if '<STR_LIT>' in kwargs and kwargs [ '<STR_LIT>' ] : <EOL> command = settings . get ( '<STR_LIT>' ) <EOL> logger . debug ( '<STR_LIT>' % command ) <EOL> working_directory = project_directory ( self . view . file_name ( ) ) <EOL> logger . debug ( '<STR_LIT>' % working_directory ) <EOL> if working_directory : <EOL> TestRunner . start ( self . view , working_directory , command ) <EOL> class TestRunner ( ) : <EOL> worker = None <EOL> @ classmethod <EOL> def start ( self , view , working_directory , command ) : <EOL> logger . debug ( '<STR_LIT>' ) <EOL> if self . worker and self . worker . is_alive ( ) : <EOL> logger . debug ( '<STR_LIT>' ) <EOL> if ( settings . get ( '<STR_LIT>' ) ) : <EOL> logger . debug ( '<STR_LIT>' ) <EOL> self . worker . stop ( ) <EOL> else : <EOL> logger . debug ( '<STR_LIT>' ) <EOL> return <EOL> logger . debug ( '<STR_LIT>' ) <EOL> self . worker = TestRunnerWorker ( view , working_directory , command ) <EOL> class TestRunnerWorker ( threading . Thread ) : <EOL> def __init__ ( self , view , working_directory , command ) : <EOL> self . view = view <EOL> self . working_directory = working_directory <EOL> self . command = command <EOL> self . process = None <EOL> self . start_time = time . time ( ) <EOL> self . timeout = settings . get ( '<STR_LIT>' , <NUM_LIT> ) <EOL> self . result = { <EOL> '<STR_LIT>' : <NUM_LIT:0> , <EOL> '<STR_LIT>' : <NUM_LIT:0> , <EOL> '<STR_LIT>' : <NUM_LIT:0> , <EOL> '<STR_LIT>' : <NUM_LIT:0> , <EOL> '<STR_LIT>' : <NUM_LIT:0> , <EOL> '<STR_LIT>' : <NUM_LIT:0> , <EOL> '<STR_LIT>' : <NUM_LIT:0> , <EOL> '<STR_LIT:status>' : '<STR_LIT>' , <EOL> '<STR_LIT:message>' : '<STR_LIT>' <EOL> } <EOL> threading . Thread . __init__ ( self ) <EOL> self . logger = logging . getLogger ( '<STR_LIT>' % self . name ) <EOL> self . start ( ) <EOL> def run ( self ) : <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> try : <EOL> self . check_timeout ( ) <EOL> self . update_status ( ) <EOL> self . update_panel ( ) <EOL> self . logger . debug ( '<STR_LIT>' , self . command ) <EOL> self . logger . debug ( '<STR_LIT>' , self . working_directory ) <EOL> self . process = subprocess . Popen ( <EOL> self . command , <EOL> shell = True , <EOL> cwd = self . working_directory , <EOL> universal_newlines = True , <EOL> bufsize = <NUM_LIT:1> , <EOL> stdout = subprocess . PIPE , <EOL> stderr = subprocess . PIPE <EOL> ) <EOL> tapParser = parsers . TapParser ( self . process . stdout ) <EOL> tapParser . signal [ '<STR_LIT>' ] . add ( self . stdout_line ) <EOL> tapParser . signal [ '<STR_LIT>' ] . add ( self . tests_planned ) <EOL> tapParser . signal [ '<STR_LIT>' ] . add ( self . test_case ) <EOL> tapParser . signal [ '<STR_LIT>' ] . add ( self . tests_completed ) <EOL> tapParser . parse ( ) <EOL> lineParser = parsers . LineParser ( self . process . stderr ) <EOL> lineParser . signal [ '<STR_LIT>' ] . add ( self . stderr_line ) <EOL> lineParser . parse ( ) <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> except RuntimeError : <EOL> print ( '<STR_LIT>' ) <EOL> self . logger . exception ( '<STR_LIT>' ) <EOL> except Exception : <EOL> print ( '<STR_LIT>' ) <EOL> self . logger . exception ( '<STR_LIT>' ) <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> def stop ( self ) : <EOL> if self . process and self . process . poll ( ) is None : <EOL> self . process . terminate ( ) <EOL> self . process = None <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> def tests_planned ( self , start , end ) : <EOL> self . logger . debug ( '<STR_LIT>' % ( start , end ) ) <EOL> self . result [ '<STR_LIT>' ] = end <EOL> self . update_status ( ) <EOL> def tests_completed ( self ) : <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> self . result [ '<STR_LIT>' ] = self . result [ '<STR_LIT>' ] - self . result [ '<STR_LIT>' ] <EOL> self . result [ '<STR_LIT>' ] = self . result [ '<STR_LIT>' ] <EOL> self . result [ '<STR_LIT:status>' ] = '<STR_LIT>' <EOL> self . update_panel ( ) <EOL> self . update_status ( ) <EOL> def test_case ( self , status , number , description , directive ) : <EOL> if status : <EOL> self . result [ '<STR_LIT>' ] += <NUM_LIT:1> <EOL> status_message = '<STR_LIT>' <EOL> elif directive [ '<STR_LIT:type>' ] == '<STR_LIT>' : <EOL> self . result [ '<STR_LIT>' ] += <NUM_LIT:1> <EOL> status_message = '<STR_LIT>' <EOL> elif directive [ '<STR_LIT:type>' ] == '<STR_LIT>' : <EOL> self . result [ '<STR_LIT>' ] += <NUM_LIT:1> <EOL> status_message = '<STR_LIT>' <EOL> else : <EOL> self . result [ '<STR_LIT>' ] += <NUM_LIT:1> <EOL> status_message = '<STR_LIT>' <EOL> self . logger . debug ( '<STR_LIT>' % ( number , status_message ) ) <EOL> self . result [ '<STR_LIT>' ] += <NUM_LIT:1> <EOL> self . result [ '<STR_LIT:message>' ] += '<STR_LIT>' . format ( <EOL> status = status_message , <EOL> number = number , <EOL> description = description <EOL> ) <EOL> self . update_status ( ) <EOL> self . update_panel ( ) <EOL> def stdout_line ( self , line ) : <EOL> self . logger . debug ( '<STR_LIT>' , line . rstrip ( ) ) <EOL> def stderr_line ( self , line ) : <EOL> self . logger . debug ( '<STR_LIT>' , line . rstrip ( ) ) <EOL> @ throttle ( <NUM_LIT:1> / <NUM_LIT> ) <EOL> def update_status ( self ) : <EOL> if self . result [ '<STR_LIT>' ] > <NUM_LIT:0> : <EOL> parts = [ '<STR_LIT>' ] <EOL> elif self . result [ '<STR_LIT>' ] > <NUM_LIT:0> : <EOL> parts = [ '<STR_LIT>' ] <EOL> else : <EOL> parts = [ '<STR_LIT>' ] <EOL> for status in ( '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' , '<STR_LIT>' ) : <EOL> if self . result [ status ] > <NUM_LIT:0> : <EOL> parts . append ( '<STR_LIT>' . format ( status = status ) ) <EOL> spinner = settings . get ( '<STR_LIT>' , '<STR_LIT>' ) <EOL> ticks = int ( ( time . time ( ) - self . start_time ) * <NUM_LIT:5> ) <EOL> message = '<STR_LIT>' + '<STR_LIT>' . join ( parts ) + '<STR_LIT>' <EOL> if self . result [ '<STR_LIT:status>' ] == '<STR_LIT>' : <EOL> message = spinner [ ticks % len ( spinner ) ] + '<STR_LIT:U+0020>' + message <EOL> self . view . set_status ( '<STR_LIT>' , message . format ( <EOL> status = self . result [ '<STR_LIT:status>' ] , <EOL> passed = self . result [ '<STR_LIT>' ] , <EOL> failed = self . result [ '<STR_LIT>' ] , <EOL> skipped = self . result [ '<STR_LIT>' ] , <EOL> todo = self . result [ '<STR_LIT>' ] , <EOL> executed = self . result [ '<STR_LIT>' ] , <EOL> missing = self . result [ '<STR_LIT>' ] , <EOL> total = self . result [ '<STR_LIT>' ] ) <EOL> ) <EOL> if self . is_alive ( ) : <EOL> self . update_status ( ) <EOL> @ throttle ( <NUM_LIT:0.1> ) <EOL> def update_panel ( self ) : <EOL> window = sublime . active_window ( ) <EOL> try : <EOL> result_panel = window . create_output_panel ( '<STR_LIT>' ) <EOL> except : <EOL> result_panel = window . get_output_panel ( '<STR_LIT>' ) <EOL> result_panel . set_syntax_file ( '<STR_LIT>' ) <EOL> result_panel . run_command ( <EOL> '<STR_LIT>' , <EOL> { '<STR_LIT:message>' : self . result [ '<STR_LIT:message>' ] } <EOL> ) <EOL> if ( self . result [ '<STR_LIT>' ] > <NUM_LIT:0> or <EOL> settings . get ( '<STR_LIT>' , False ) ) : <EOL> window . run_command ( '<STR_LIT>' , { '<STR_LIT>' : '<STR_LIT>' } ) <EOL> elif self . result [ '<STR_LIT:status>' ] == '<STR_LIT>' : <EOL> window . run_command ( '<STR_LIT>' , { '<STR_LIT>' : '<STR_LIT>' } ) <EOL> if self . is_alive ( ) : <EOL> self . update_panel ( ) <EOL> @ throttle ( <NUM_LIT:1> ) <EOL> def check_timeout ( self ) : <EOL> current_time = time . time ( ) <EOL> elapsed_time = current_time - self . start_time <EOL> if self . is_alive ( ) : <EOL> self . logger . debug ( '<STR_LIT>' % elapsed_time ) <EOL> if elapsed_time > self . timeout : <EOL> self . logger . debug ( '<STR_LIT>' ) <EOL> self . stop ( ) <EOL> if self . is_alive ( ) : <EOL> self . check_timeout ( ) <EOL> class UpdatePanelCommand ( sublime_plugin . TextCommand ) : <EOL> description = '<STR_LIT>' <EOL> def run ( self , edit , message , * args , ** kwargs ) : <EOL> self . view . erase ( edit , sublime . Region ( <NUM_LIT:0> , self . view . size ( ) ) ) <EOL> self . view . insert ( edit , self . view . size ( ) , message ) <EOL> self . view . show ( self . view . size ( ) ) <EOL> class PostSaveListener ( sublime_plugin . EventListener ) : <EOL> def on_post_save ( self , view ) : <EOL> logger . debug ( '<STR_LIT>' ) <EOL> if not settings . get ( '<STR_LIT>' , True ) : <EOL> logger . debug ( '<STR_LIT>' ) <EOL> return <EOL> if settings . get ( '<STR_LIT>' , False ) : <EOL> logger . debug ( '<STR_LIT>' ) <EOL> view . run_command ( '<STR_LIT>' , { '<STR_LIT>' : True } ) <EOL> else : <EOL> logger . debug ( '<STR_LIT>' ) <EOL> view . run_command ( '<STR_LIT>' ) <EOL> logger . debug ( '<STR_LIT>' , __name__ ) <EOL> settings = Settings ( ) <EOL> st_version = <NUM_LIT:2> <EOL> package_name = '<STR_LIT>' <EOL> if sublime . version ( ) == '<STR_LIT>' : <EOL> st_version = <NUM_LIT:3> <EOL> print ( '<STR_LIT>' ) <EOL> elif int ( sublime . version ( ) ) > <NUM_LIT> : <EOL> st_version = <NUM_LIT:3> <EOL> if st_version == <NUM_LIT:2> : <EOL> plugin_loaded ( ) </s>
