Esempio n. 1
0
    def update(self, view, coverage=None):
        """
        Updates a view with the coverage data in a particular file
        """
        self.remove(view)

        if not coverage:
            return

        self.annotate_lines(
            view=view, name="SublimePHPCoverageGood", lines=coverage.good_lines, scope="markup.inserted", icon="dot"
        )

        self.annotate_lines(
            view=view, name="SublimePHPCoverageBad", lines=coverage.bad_lines, scope="markup.deleted", icon="bookmark"
        )

        try:
            percentage = 100 * coverage.covered / float(coverage.statements)
        except ZeroDivisionError:
            percentage = 0

        status = "%d/%d lines (%.2f%%)" % (coverage.covered, coverage.statements, percentage)
        debug_message("Code coverage: %s" % status)
        view.set_status("SublimePHPCoveragePercentage", "Code coverage: %s" % status)
Esempio n. 2
0
    def update(self, view, coverage=None):
        """
        Updates a view with the coverage data in a particular file
        """
        self.remove(view)

        if not coverage:
            return

        self.annotate_lines(
            view=view,
            name='SublimePHPCoverageGood',
            lines=coverage.good_lines,
            scope='markup.inserted',
            icon='dot',
        )

        self.annotate_lines(
            view=view,
            name='SublimePHPCoverageBad',
            lines=coverage.bad_lines,
            scope='markup.deleted',
            icon='bookmark',
        )

        try:
            percentage = 100 * coverage.covered / float(coverage.statements)
        except ZeroDivisionError:
            percentage = 0

        status = '%d/%d lines (%.2f%%)' % (
            coverage.covered, coverage.statements, percentage)
        debug_message('Code coverage: %s' % status)
        view.set_status(
            'SublimePHPCoveragePercentage', 'Code coverage: %s' % status)
Esempio n. 3
0
 def start(self):
     self.last_mtime = self.mtime()
     self.last_hash = self.hash()
     if self.last_mtime:
         debug_message("[FileWatcher] exists: %s" % self.filename)
     else:
         debug_message("[FileWatcher] doesn't exist: %s" % self.filename)
     super(FileWatcher, self).start()
    def run(self, edit, coverage=None, **kwargs):
        filename = self.view.file_name()

        if not self.should_include(filename):
            debug_message("Ignoring excluded file '%s'" % filename)
            return

        if not coverage:
            coverage = self.coverage()

        update_view(self.view, coverage)
Esempio n. 5
0
 def get_setting(self, key):
     """
     Gets a configuration value by key.
     """
     if key in self.project:
         value = self.project.get(key)
         debug_message("[config] [project] %s: '%s'" % (key, value))
         return value
     else:
         value = self.settings.get(key, None)
         debug_message("[config]: %s: '%s'" % (key, value))
         return value
Esempio n. 6
0
 def get_setting(self, key):
     """
     Gets a configuration value by key.
     """
     if key in self.project:
         value = self.project.get(key)
         debug_message("[config] [project] %s: '%s'" % (key, value))
         return value
     else:
         value = self.settings.get(key, None)
         debug_message("[config]: %s: '%s'" % (key, value))
         return value
Esempio n. 7
0
    def load(self):
        """
        Loads the settings from disk into structured data.
        """
        debug_message('[config] Loading config')
        import sublime

        self.filename = "SublimePHPCoverage.sublime-settings"
        self.settings = sublime.load_settings(self.filename)
        self.project = {}

        if sublime.active_window() is not None:
            debug_message('[config] Window is active, loading project')
            project = sublime.active_window().active_view().settings()

            if project.has('phpcoverage'):
                debug_message("[config] Found project settings")
                project.clear_on_change('phpcoverage')
                self.project = project.get('phpcoverage')
                project.add_on_change('phpcoverage', config.load)
            else:
                debug_message("[config] No 'phpcoverage' key, ignoring")

        for key in self.keys:
            self.settings.clear_on_change(key)
            setattr(self, key, self.get_setting(key))
            self.settings.add_on_change(key, config.load)

        self.loaded = True
Esempio n. 8
0
    def load(self):
        """
        Loads the settings from disk into structured data.
        """
        debug_message('[config] Loading config')
        import sublime

        self.filename = "SublimePHPCoverage.sublime-settings"
        self.settings = sublime.load_settings(self.filename)
        self.project = {}

        if sublime.active_window() is not None:
            debug_message('[config] Window is active, loading project')
            project = sublime.active_window().active_view().settings()

            if project.has('phpcoverage'):
                debug_message("[config] Found project settings")
                project.clear_on_change('phpcoverage')
                self.project = project.get('phpcoverage')
                project.add_on_change('phpcoverage', config.load)
            else:
                debug_message("[config] No 'phpcoverage' key, ignoring")

        for key in self.keys:
            self.settings.clear_on_change(key)
            setattr(self, key, self.get_setting(key))
            self.settings.add_on_change(key, config.load)

        self.loaded = True
Esempio n. 9
0
    def remove(self, view):
        """
        Unregisters any set-up listeners for a recently closed view.
        """
        # loop over the watchers
        for id, watcher in list(self.watchers.items()):
            # delete any callback related to this view
            watcher.remove_callback(view.id())

            # if no more callbacks on this watcher, stop and remove it
            if not watcher.has_callbacks():
                filename = watcher.filename
                debug_message("Stopping CoverageWatcher for '%s'" % filename)
                watcher.stop(1)
                del self.watchers[id]
Esempio n. 10
0
    def remove(self, view):
        """
        Unregisters any set-up listeners for a recently closed view.
        """
        # loop over the watchers
        for id, watcher in list(self.watchers.items()):
            # delete any callback related to this view
            watcher.remove_callback(view.id())

            # if no more callbacks on this watcher, stop and remove it
            if not watcher.has_callbacks():
                filename = watcher.filename
                debug_message("Stopping CoverageWatcher for '%s'" % filename)
                watcher.stop(1)
                del self.watchers[id]
def update_view(view, coverage=None):
    """
    Updates the coverage data displayed in a view.

    Arguments are the view to update, and the coverage data. The
    coverage data should be a CoverageData object, which contains
    the relevant coverage data for the file shown in the view. If the
    coverage data doesn't exist for the file shown in the view, or the
    coverage data is None, then the displayed coverage data will be
    removed from the view.
    """

    filename = view.file_name()
    debug_message('Updating coverage for ' + filename)

    file_coverage = coverage.get_file(filename) if coverage else None
    ViewUpdater().update(view, file_coverage)
Esempio n. 12
0
    def find(self, filename):
        """
        Finds the coverage file for a given filename.
        """
        # start from the file's directory
        parent, current = os.path.split(os.path.abspath(filename))
        path = os.path.normcase(os.path.normpath(config.report_path))

        # iterate through parent directories until coverage file found
        while current:
            coverage = os.path.join(parent, path)
            if os.path.exists(coverage):
                debug_message("Coverage for %s in %s" % (filename, coverage))
                return coverage

            parent, current = os.path.split(parent)

        debug_message("Coverage file not found for " + str(filename))
        return None
Esempio n. 13
0
    def find(self, filename):
        """
        Finds the coverage file for a given filename.
        """
        # start from the file's directory
        parent, current = os.path.split(os.path.abspath(filename))
        path = os.path.normcase(os.path.normpath(config.report_path))

        # iterate through parent directories until coverage file found
        while current:
            coverage = os.path.join(parent, path)
            if os.path.exists(coverage):
                debug_message("Coverage for %s in %s" % (filename, coverage))
                return coverage

            parent, current = os.path.split(parent)

        debug_message("Coverage file not found for " + str(filename))
        return None
Esempio n. 14
0
    def dispatch(self, event):
        """
        Dispatches an event, calling all relevant callbacks.
        """
        callbacks = self.callbacks[event]

        debug_message("[FileWatcher] %s '%s'" % (event, self.filename))
        debug_message("[FileWatcher] %d callbacks" % len(callbacks))

        for callback in callbacks.values():
            debug_message("[FileWatcher] Calling %s" % repr(callback))
            callback()
Esempio n. 15
0
    def add(self, view):
        """
        Sets up a watcher for a newly opened view.
        """
        if not config.watch_report:
            return

        # find coverage file for the view's file
        filename = view.file_name()

        if filename is None:
            return

        if not self.matcher.should_include(filename):
            debug_message("Ignoring excluded file '%s'" % filename)
            return

        coverage = self.coverage_finder.find(filename)

        # nothing can be done if the coverage file can't be found
        if not coverage:
            return

        # ensure a CoverageWatcher exists for the coverage file
        if not coverage in self.watchers:
            debug_message("Creating CoverageWatcher for " + coverage)
            self.watchers[coverage] = CoverageWatcher(coverage)
        else:
            debug_message("Found existing CoverageWatcher for " + coverage)

        watcher = self.watchers[coverage]

        # add callbacks as defined at construction time, also adding in
        # the relevant view as a parameter to the callback
        for event, callback in self.callbacks.items():
            wrapped = self.prepare_callback(callback, view)
            watcher.add_callback(event, view.id(), wrapped)

        # start the watcher if it's not already running
        if not watcher.is_alive():
            debug_message("Starting CoverageWatcher for " + coverage)
            watcher.start()
Esempio n. 16
0
    def add(self, view):
        """
        Sets up a watcher for a newly opened view.
        """
        if not config.watch_report:
            return

        # find coverage file for the view's file
        filename = view.file_name()

        if filename is None:
            return

        if not self.matcher.should_include(filename):
            debug_message("Ignoring excluded file '%s'" % filename)
            return

        coverage = self.coverage_finder.find(filename)

        # nothing can be done if the coverage file can't be found
        if not coverage:
            return

        # ensure a CoverageWatcher exists for the coverage file
        if not coverage in self.watchers:
            debug_message("Creating CoverageWatcher for " + coverage)
            self.watchers[coverage] = CoverageWatcher(coverage)
        else:
            debug_message("Found existing CoverageWatcher for " + coverage)

        watcher = self.watchers[coverage]

        # add callbacks as defined at construction time, also adding in
        # the relevant view as a parameter to the callback
        for event, callback in self.callbacks.items():
            wrapped = self.prepare_callback(callback, view)
            watcher.add_callback(event, view.id(), wrapped)

        # start the watcher if it's not already running
        if not watcher.is_alive():
            debug_message("Starting CoverageWatcher for " + coverage)
            watcher.start()
Esempio n. 17
0
    def dispatch(self, event):
        """
        Dispatches an event, calling all relevant callbacks.

        Overridden to pass coverage data to the callback, taken from
        the coverage file being watched by this CoverageWatcher.
        """
        callbacks = self.callbacks[event]

        debug_message("[CoverageWatcher] %s '%s'" % (event, self.filename))
        debug_message("[CoverageWatcher] %d callbacks" % len(callbacks))

        data = self.get_coverage_factory().factory(self.filename)

        for callback in callbacks.values():
            debug_message("[CoverageWatcher] Calling %s" % repr(callback))
            callback(data)
def plugin_loaded():
    """
    Called automatically by Sublime when the API is ready to be used.
    Updates coverage for any open views, and adds them to the mediator.
    """

    config.load()

    # add open views to the mediator
    for window in sublime.windows():
        debug_message("[plugin_loaded] Found window %d" % window.id())
        for view in window.views():
            debug_message("[plugin_loaded] Found view %d" % view.id())
            mediator.add(view)
            set_timeout_async(
                lambda: view.run_command('phpcoverage_update'),
                1
            )

    debug_message("[plugin_loaded] Finished.")
Esempio n. 19
0
import sublime
from php_coverage.debug import debug_message

sublime3 = int(sublime.version()) >= 3000

if sublime3:
    set_timeout_async = sublime.set_timeout_async
else:
    debug_message("Adding Sublime 3 polyfills")
    set_timeout_async = sublime.set_timeout