guard-compat-1.2.1/0000755000175000017500000000000013207217000012142 5ustar daidaiguard-compat-1.2.1/spec/0000755000175000017500000000000013207217000013074 5ustar daidaiguard-compat-1.2.1/spec/spec_helper.rb0000644000175000017500000000601613207217000015715 0ustar daidai# The `.rspec` file also contains a few flags that are not defaults but that # users commonly want. # # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration RSpec.configure do |config| # rspec-expectations config goes here. You can use an alternate # assertion/expectation library such as wrong or the stdlib/minitest # assertions if you prefer. config.expect_with :rspec do |expectations| # This option will default to `true` in RSpec 4. It makes the `description` # and `failure_message` of custom matchers include text for helper methods # defined using `chain`, e.g.: # be_bigger_than(2).and_smaller_than(4).description # # => "be bigger than 2 and smaller than 4" # ...rather than: # # => "be bigger than 2" expectations.include_chain_clauses_in_custom_matcher_descriptions = true end # rspec-mocks config goes here. You can use an alternate test double # library (such as bogus or mocha) by changing the `mock_with` option here. config.mock_with :rspec do |mocks| # Prevents you from mocking or stubbing a method that does not exist on # a real object. This is generally recommended, and will default to # `true` in RSpec 4. mocks.verify_doubled_constant_names = true mocks.verify_partial_doubles = true end # The settings below are suggested to provide a good initial experience # with RSpec, but feel free to customize to your heart's content. # These two settings work together to allow you to limit a spec run # to individual examples or groups you care about by tagging them with # `:focus` metadata. When nothing is tagged with `:focus`, all examples # get run. config.filter_run focus: ENV['CI'] != 'true' config.run_all_when_everything_filtered = true config.disable_monkey_patching! # This setting enables warnings. It's recommended, but in some cases may # be too noisy due to issues in dependencies. config.warnings = true # Many RSpec users commonly either run the entire suite or an individual # file, and it's useful to allow more verbose output when running an # individual spec file. if config.files_to_run.one? # Use the documentation formatter for detailed output, # unless a formatter has already been configured # (e.g. via a command-line flag). config.default_formatter = 'doc' end # Print the 10 slowest examples and example groups at the # end of the spec run, to help surface which specs are running # particularly slow. # config.profile_examples = 10 # Run specs in random order to surface order dependencies. If you find an # order dependency and want to debug it, you can fix the order by providing # the seed, which is printed after each run. # --seed 1234 config.order = :random # Seed global randomization in this process using the `--seed` CLI option. # Setting this allows you to use `--seed` to deterministically reproduce # test failures related to randomization by passing the same `--seed` value # as the one that triggered the failure. Kernel.srand config.seed end guard-compat-1.2.1/spec/guard/0000755000175000017500000000000013207217000014176 5ustar daidaiguard-compat-1.2.1/spec/guard/compat/0000755000175000017500000000000013207217000015461 5ustar daidaiguard-compat-1.2.1/spec/guard/compat/no_guard_spec.rb0000644000175000017500000000304513207217000020620 0ustar daidai# This test requires UI be not defined to simulate using plugin outside Guard require 'guard/compat/plugin' Guard.send(:remove_const, :UI) if Guard.const_defined?(:UI) RSpec.describe Guard::Compat do context 'when Guard is not loaded' do describe '.color' do it 'returns uncolored text' do expect(Guard::Compat::UI.color('foo', 'red')).to eq('foo') end end describe '.color_enabled?' do it 'returns false' do expect(Guard::Compat::UI.color_enabled?).to be(false) end end describe '.info' do it 'outputs to stdout' do expect($stdout).to receive(:puts).with('foo') Guard::Compat::UI.info('foo') end end describe '.warning' do it 'outputs to stdout' do expect($stdout).to receive(:puts).with('foo') Guard::Compat::UI.warning('foo') end end describe '.error' do it 'outputs to stdout' do expect($stderr).to receive(:puts).with('foo') Guard::Compat::UI.error('foo') end end describe '.debug' do it 'outputs to stdout' do expect($stdout).to receive(:puts).with('foo') Guard::Compat::UI.debug('foo') end end describe '.deprecation' do it 'outputs to stdout' do expect($stdout).to receive(:puts).with('foo') Guard::Compat::UI.deprecation('foo') end end describe '.notify' do it 'outputs to stdout' do expect($stdout).to receive(:puts).with('foo') Guard::Compat::UI.notify('foo') end end end end guard-compat-1.2.1/spec/guard/compat/example_template_spec.rb0000644000175000017500000000141313207217000022345 0ustar daidairequire 'guard/compat/test/template' require 'guard/compat/example' RSpec.describe Guard::MyPlugin do describe 'template' do subject { Guard::Compat::Test::Template.new(described_class) } # Stub the template, because we are testing the helper, not the plugin let(:template_contents) do <<-EOS guard :myplugin do watch(/(foo).rb/) { |m| "spec/\#{m[1]}_spec.rb" } watch(/bar.rb/) end EOS end before do allow(IO).to receive(:read) .with('lib/guard/myplugin/templates/Guardfile') .and_return(template_contents) end it 'translates changes' do expect(subject.changed('foo.rb')).to eq(['spec/foo_spec.rb']) expect(subject.changed('bar.rb')).to eq(['bar.rb']) end end end guard-compat-1.2.1/spec/guard/compat/example_spec.rb0000644000175000017500000000273613207217000020463 0ustar daidai# This is the only file the plugin should require require 'guard/compat/test/helper' require 'guard/compat/example' RSpec.describe Guard::MyPlugin, exclude_stubs: [Guard::Plugin] do let(:options) { { foo: :bar } } subject { described_class.new(options) } before do meths = %w(info warning error deprecation debug notify color color_enabled?) meths.each do |type| allow(Guard::Compat::UI).to receive(type.to_sym) end end it 'passes options' do expect(subject.options).to include(foo: :bar) end it 'works without options' do expect { described_class.new }.to_not raise_error end describe '#start' do before { subject.start } %w(info warning error deprecation debug notify).each do |type| specify do expect(Guard::Compat::UI).to have_received(type.to_sym).with('foo') end end end describe '#run_all' do before { subject.run_all } %w(info warning error deprecation debug notify).each do |type| specify do expect(Guard::Compat::UI).to have_received(type.to_sym) .with('foo', bar: :baz) end end end describe '#run_on_modifications' do before do allow(Guard::Compat).to receive(:matching_files) allow(Guard::Compat).to receive(:watched_directories) end before { subject.run_on_modifications } specify { expect(Guard::Compat::UI).to have_received(:color_enabled?) } specify { expect(Guard::Compat).to have_received(:matching_files) } end end guard-compat-1.2.1/lib/0000755000175000017500000000000013207217000012710 5ustar daidaiguard-compat-1.2.1/lib/guard/0000755000175000017500000000000013207217000014012 5ustar daidaiguard-compat-1.2.1/lib/guard/compat/0000755000175000017500000000000013207217000015275 5ustar daidaiguard-compat-1.2.1/lib/guard/compat/version.rb0000644000175000017500000000007513207217000017311 0ustar daidaimodule Guard module Compat VERSION = '1.2.1' end end guard-compat-1.2.1/lib/guard/compat/test/0000755000175000017500000000000013207217000016254 5ustar daidaiguard-compat-1.2.1/lib/guard/compat/test/template.rb0000644000175000017500000000336413207217000020422 0ustar daidaimodule Guard module Compat module Test class Template class Session class MultipleGuardNotImplemented < NotImplementedError def message 'multiple guards not supported!' end end class GlobalWatchesNotImplemented < NotImplementedError def message 'global watches not supported!' end end def initialize(path, content) @watches = {} @current = nil instance_eval(content, path, 1) end def match(file) _watches.map do |expr, block| next unless (match = file.match(expr)) block.nil? ? [file] : block.call([file] + match.captures) end.flatten.compact.uniq end def guard(name, _options = {}) @current = name @watches[@current] = [] yield @current = nil end def watch(expr, &block) @watches[@current] << [expr, block] end private def _watches keys = @watches.keys fail ArgumentError, 'no watches!' if keys.empty? fail MultipleGuardNotImplemented if keys.size > 1 key = keys.first fail GlobalWatchesNotImplemented if key.nil? @watches[key] end end def initialize(plugin_class) name = plugin_class.to_s.sub('Guard::', '').downcase path = format('lib/guard/%s/templates/Guardfile', name) content = File.read(path) @session = Session.new(path, content) end def changed(file) @session.match(file) end end end end end guard-compat-1.2.1/lib/guard/compat/test/helper.rb0000644000175000017500000000161513207217000020063 0ustar daidai# Minimal stub allowing a plugin to work require 'guard/compat/plugin' module Guard # Monkey patch Plugin to just keep the interface class Plugin attr_reader :options alias_method :old_initialize, :initialize def initialize(options = {}) @options = options end remove_method(:old_initialize) end # Stub, but allow real Notifier to be used, because e.g. guard-minitest uses # is while guard-process is being tested unless Guard.const_defined?('Notifier') module Notifier # NOTE: do not implement anything here, so using any UI methods # causes tests to fail end end # Stub, but allow real UI to be used, because e.g. guard-minitest uses it # through using Guard::Notifier unless Guard.const_defined?('UI') module UI # NOTE: do not implement anything here, so using any UI methods # causes tests to fail end end end guard-compat-1.2.1/lib/guard/compat/plugin.rb0000644000175000017500000000651613207217000017130 0ustar daidai# Note: currently, this file only exists to allow Bundler to require this file # without crashing (e.g. when Guard hasn't been included) unless Object.const_defined?('Guard') module Guard end end unless Guard.const_defined?('Plugin') # Provided empty definition so requiring the plugin without Guard won't crash # (e.g. when added to a Gemfile without `require: false`) module Guard class Plugin def initialize(_options = {}) msg = 'either Guard has not been required or you did not' \ ' include guard/compat/test/helper' fail NotImplementedError, msg end end end end module Guard module Compat # TODO: this is just a temporary workaround to allow plugins # to use watcher patterns in run_all def self.matching_files(plugin, files) unless Guard.const_defined?('Watcher') msg = 'either Guard has not been required or you did not' \ ' stub this method in your plugin tests' fail NotImplementedError, msg end # TODO: uniq not tested # TODO: resolve symlinks and then uniq? Guard::Watcher.match_files(plugin, files).uniq end def self.watched_directories unless Guard.const_defined?('CLI') fail NotImplementedError, 'either Guard has not been required or'\ ' you did not stub this method in your plugin tests' end if Guard.respond_to?(:state) # TODO: the new version is temporary Guard.state.session.watchdirs.map { |d| Pathname(d) } else dirs = Array(Guard.options(:watchdir)) dirs.empty? ? [Pathname.pwd] : dirs.map { |d| Pathname(d) } end end module UI def self.color(text, *colors) if Guard.const_defined?(:UI) Guard::UI.send(:color, text, *colors) else text end end def self.color_enabled? if Guard.const_defined?(:UI) Guard::UI.send(:color_enabled?) else false end end def self.info(message, options = {}) if Guard.const_defined?(:UI) Guard::UI.info(message, options) else $stdout.puts(message) end end def self.warning(message, options = {}) if Guard.const_defined?(:UI) Guard::UI.warning(message, options) else $stdout.puts(message) end end def self.error(message, options = {}) if Guard.const_defined?(:UI) Guard::UI.error(message, options) else $stderr.puts(message) end end def self.debug(message, options = {}) if Guard.const_defined?(:UI) Guard::UI.debug(message, options) else $stdout.puts(message) end end def self.deprecation(message, options = {}) if Guard.const_defined?(:UI) Guard::UI.deprecation(message, options) else $stdout.puts(message) end end def self.notify(msg, options = {}) return $stdout.puts(msg) unless Guard.const_defined?(:UI) return Notifier.notify(msg, options) if Notifier.respond_to?(:notify) # test helper was included note = 'NOTE: Notification is disabled when testing Guard plugins'\ ' (it makes no sense)' $stderr.puts(note) $stdout.puts(msg) end end end end guard-compat-1.2.1/lib/guard/compat/example.rb0000644000175000017500000000174513207217000017264 0ustar daidai# NOTE: Do NOT require "guard/plugin" - it will either be already required, or # a stub will be supplied by the test class module Guard class MyPlugin < Plugin def start Guard::Compat::UI.notify('foo') Guard::Compat::UI.color('foo') Guard::Compat::UI.info('foo') Guard::Compat::UI.warning('foo') Guard::Compat::UI.error('foo') Guard::Compat::UI.debug('foo') Guard::Compat::UI.deprecation('foo') end def run_all Guard::Compat::UI.notify('foo', bar: :baz) Guard::Compat::UI.color('foo', :white) Guard::Compat::UI.info('foo', bar: :baz) Guard::Compat::UI.warning('foo', bar: :baz) Guard::Compat::UI.error('foo', bar: :baz) Guard::Compat::UI.debug('foo', bar: :baz) Guard::Compat::UI.deprecation('foo', bar: :baz) end def run_on_modifications Guard::Compat::UI.color_enabled? Guard::Compat.matching_files(self, ['foo']) Guard::Compat.watched_directories end end end guard-compat-1.2.1/lib/guard/compat.rb0000644000175000017500000000014413207217000015621 0ustar daidairequire 'guard/compat/version' module Guard module Compat # Your code goes here... end end guard-compat-1.2.1/guard-compat.gemspec0000644000175000017500000000160413207217000016073 0ustar daidai# coding: utf-8 lib = File.expand_path('../lib', __FILE__) $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib) require 'guard/compat/version' Gem::Specification.new do |spec| spec.name = 'guard-compat' spec.version = Guard::Compat::VERSION spec.authors = ['Cezary Baginski'] spec.email = ['cezary@chronomantic.net'] spec.summary = 'Tools for developing Guard compatible plugins' spec.description = 'Helps creating valid Guard plugins and testing them' spec.homepage = '' spec.license = 'MIT' spec.files = `git ls-files -z`.split("\x0") spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) } spec.test_files = spec.files.grep(%r{^(test|spec|features)/}) spec.require_paths = ['lib'] spec.add_development_dependency 'bundler', '~> 1.7' spec.add_development_dependency 'rake', '~> 10.0' end guard-compat-1.2.1/Rakefile0000644000175000017500000000035713207217000013614 0ustar daidairequire 'bundler/gem_tasks' require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) do |t| t.verbose = false unless ENV.key?('CI') end require 'rubocop/rake_task' RuboCop::RakeTask.new(:rubocop) task default: [:spec, :rubocop] guard-compat-1.2.1/README.md0000644000175000017500000000522613207217000013426 0ustar daidai# Guard::Compat Currently, provides only a test helper for testing custom Guard plugins. ## Usage (in a Guard plugin) In your gemspec: ```ruby s.add_dependency('guard-compat', '~> 1.0') ``` In all your plugin files (e.g. `lib/guard/myplugin.rb`): ```ruby # Don't require "guard/plugin" here or in any other plugin's files require 'guard/compat/plugin' module Guard class MyPlugin < Plugin # (...) end end ``` ### IMPORTANT 1. Do not include *any* files from Guard directly (if you need something from Guard which Guard::Compat doesn't provide, file an issue) 2. Include 'guard/compat/plugin' is *all* your files which use `Guard::Plugin` 3. Make sure you include the `< Plugin` part in *every* file which add classes or methods to your plugin class (important if your plugin consists of multiple files/sub class) 4. Remove requires from your spec_helper and explicitly add them to each test/file And in your plugin tests (e.g. `spec/lib/guard/myplugin_spec.rb`): ```ruby require 'guard/compat/test/helper' require 'guard/myplugin' # And your tests instantiating your plugin go here... RSpec.describe Guard::Myplugin do ``` ### Migrating your API calls `Guard::UI` => `Guard::Compat::UI` (or Compat::UI for short) `Guard::Notifier.notify` => `Guard::Compat::UI.notify` `Guard::Watcher.match_files` => `Guard::Compat.matching_files` (Watcher is otherwise unavailable - see Guard::Less template for passing patterns as plugin options) ### New API * `Guard::UI.color` => for creating ANSI colored text if currently enabled in Guard * `Guard::UI.color_enabled?` => for checking if ANSI color output is currently enabled in Guard * `Guard::UI.watched_directories` => compatible way of obtaining watched_directories (recommended instead of accessing Watcher patterns or pattern subgroup hacks) (Open an issue if you feel something important is missing) ## Example See [lib/guard/compat/example.rb](https://github.com/guard/guard-compat/blob/master/lib/guard/compat/example.rb ) for an example plugin implementation. See [spec/guard/compat/example_spec.rb](https://github.com/guard/guard-compat/blob/master/spec/guard/compat/example_spec.rb) for an example on how to test plugins using Guard::Compat. See [spec/guard/compat/example_template_spec.rb](https://github.com/guard/guard-compat/blob/master/spec/guard/compat/example_template_spec.rb) for an example on how to test plugin templates. ## Contributing 1. Fork it ( https://github.com/guard/guard-compat/fork ) 2. Create your feature branch (`git checkout -b my-new-feature`) 3. Commit your changes (`git commit -am 'Add some feature'`) 4. Push to the branch (`git push origin my-new-feature`) 5. Create a new Pull Request guard-compat-1.2.1/LICENSE.txt0000644000175000017500000000206013207217000013763 0ustar daidaiCopyright (c) 2014 Cezary Baginski MIT License Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. guard-compat-1.2.1/Gemfile0000644000175000017500000000027213207217000013436 0ustar daidaisource 'https://rubygems.org' # Specify your gem's dependencies in guard-compat.gemspec gemspec group :development do gem 'rspec', require: false gem 'rubocop', require: false end guard-compat-1.2.1/.rubocop_todo.yml0000644000175000017500000000067613207217000015452 0ustar daidai# This configuration was generated by `rubocop --auto-gen-config` # on 2014-12-05 08:15:00 +0100 using RuboCop version 0.27.1. # The point is for the user to remove these configuration records # one by one as the offenses are removed from the code base. # Note that changes in the inspected code, or installation of new # versions of RuboCop, may require this file to be generated again. # Offense count: 4 Style/Documentation: Enabled: false guard-compat-1.2.1/.rubocop.yml0000644000175000017500000000012413207217000014411 0ustar daidaiinherit_from: - .rubocop_todo.yml AllCops: Exclude: - guard-compat.gemspec guard-compat-1.2.1/.rspec0000644000175000017500000000005313207217000013255 0ustar daidai--color --require spec_helper --format doc guard-compat-1.2.1/.gitignore0000644000175000017500000000016613207217000014135 0ustar daidai/.bundle/ /.yardoc /Gemfile.lock /_yardoc/ /coverage/ /doc/ /pkg/ /spec/reports/ /tmp/ *.bundle *.so *.o *.a mkmf.log