guard-jest 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 12086254600f743764afab326f8cd7d944139982
4
+ data.tar.gz: 754a8c45c368998d810518e74dd4968f9baa0733
5
+ SHA512:
6
+ metadata.gz: f8d72ca3d8057279249bfafe8709925b4f058ea484180c72a46764ea3e2b52f0e2f178c83ada98a12f3df29d6ea619951b11b2f5f2c0decd27779a0ae9567036
7
+ data.tar.gz: 02c4369e5df3c54de3088e940638baa79fdd81163b87b095d43a7fefd301198d0901446d0f3e030443d31c88c53776fc6fdf72308bd3e5ad305956e2333cb38c
@@ -0,0 +1,9 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
@@ -0,0 +1,13 @@
1
+ Metrics/LineLength:
2
+ Max: 100
3
+
4
+ StringLiterals:
5
+ Enabled: false
6
+
7
+ Style/IndentationWidth:
8
+ Width: 4
9
+
10
+
11
+ Style/MultilineMethodCallIndentation:
12
+ EnforcedStyle: indented_relative_to_receiver
13
+ IndentationWidth: 4
@@ -0,0 +1,9 @@
1
+ sudo: false
2
+ language: ruby
3
+ rvm:
4
+ - "2.2.5"
5
+ - "2.4.0"
6
+ cache: bundler
7
+ bundler_args: --without production --retry=6
8
+ script:
9
+ - bundle exec rake spec
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in guard-jest.gemspec
4
+ gemspec
@@ -0,0 +1,5 @@
1
+ guard :rspec, cmd: 'rspec' do
2
+ watch('spec/spec_helper.rb') { 'spec' }
3
+ watch(%r{spec/.+_spec.rb})
4
+ watch(%r{lib/(.+).rb}) { |m| "spec/#{m[1]}_spec.rb" }
5
+ end
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2017 Nathan Stitt
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,70 @@
1
+ [![Build Status](https://travis-ci.org/nathanstitt/guard-jest.svg?branch=master)](https://travis-ci.org/nathanstitt/guard-jest)
2
+
3
+ # Guard::Jest automatically tests your Jest specs when files are modified.
4
+
5
+ It runs the Jest server in watch mode, so that it can run specs more efficiently when instructed.
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ Add Guard::Jest to your `Gemfile`:
12
+
13
+ ```ruby
14
+ group :development, :test do
15
+ gem 'guard-jest'
16
+ end
17
+ ```
18
+
19
+ Add the default Guard::Jest template to your `Guardfile` by running:
20
+
21
+ ```bash
22
+ $ guard init jest
23
+ ```
24
+ ## Usage
25
+
26
+ Please read the [Guard usage documentation](https://github.com/guard/guard#readme).
27
+
28
+ ## Guardfile
29
+
30
+ Guard::Jest can be adapted to all kind of projects. Please read the
31
+ [Guard documentation](https://github.com/guard/guard#readme) for more information about the Guardfile DSL.
32
+
33
+ ```ruby
34
+ guard 'jest' do
35
+ watch(%r{spec/javascripts/spec\.(js\.coffee|js|coffee)$}) { "spec/javascripts" }
36
+ watch(%r{spec/javascripts/.+_spec\.(js\.coffee|js|coffee)$})
37
+ watch(%r{app/assets/javascripts/(.+?)\.(js\.coffee|js|coffee)$}) { |m| "spec/javascripts/#{m[1]}_spec.#{m[2]}" }
38
+ end
39
+ ```
40
+
41
+ ## Options
42
+
43
+ There are many options that can customize Guard::Jest to your needs. Options are simply supplied as hash when
44
+ defining the Guard in your `Guardfile`:
45
+
46
+ ```ruby
47
+ guard 'jest', jest_cmd: './node_modules/jest-cli/bin/jest.js' do
48
+ ...
49
+ end
50
+ ```
51
+
52
+ ### Server options
53
+
54
+ The server options configures the server environment that is needed to run Guard::Jest:
55
+
56
+ ```ruby
57
+ directory: <cwd> # Directory that should be used for running Jest
58
+ config_file: nil # Path to a [Jest configuration file](https://facebook.github.io/jest/docs/configuration.html)
59
+
60
+ jest_cmd: jest # Command to execute in order to start the Jest server
61
+ ```
62
+
63
+ ## Contributing
64
+
65
+ Bug reports and pull requests are welcome on GitHub at https://github.com/nathanstitt/guard-jest.
66
+
67
+
68
+ ## License
69
+
70
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
@@ -0,0 +1,6 @@
1
+ require "bundler/gem_tasks"
2
+ begin
3
+ require 'rspec/core/rake_task'
4
+ RSpec::Core::RakeTask.new(:spec)
5
+ rescue LoadError
6
+ end
@@ -0,0 +1,14 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require "bundler/setup"
4
+ require "guard/jest"
5
+
6
+ # You can add fixtures and/or initialization code here to make experimenting
7
+ # with your gem easier. You can also use a different console, if you like.
8
+
9
+ # (If you use this, don't forget to add pry to your Gemfile!)
10
+ # require "pry"
11
+ # Pry.start
12
+
13
+ require "irb"
14
+ IRB.start
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+ # Do any other automated setup that you need to do here
@@ -0,0 +1,38 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'guard/jest/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "guard-jest"
8
+ spec.version = Guard::Jest::VERSION
9
+ spec.authors = ["Nathan Stitt"]
10
+ spec.email = ["nathan@stitt.org"]
11
+
12
+ spec.summary = 'Guard plugin for auto-running Jest specs'
13
+ spec.description = 'Guard plugin for testing Javascript using the Jest test runner'
14
+ spec.homepage = "https://github.com/nathanstitt/guard-jest"
15
+ spec.license = "MIT"
16
+
17
+ if spec.respond_to?(:metadata)
18
+ spec.metadata['allowed_push_host'] = "https://rubygems.org"
19
+ else
20
+ raise "RubyGems 2.0 or newer is required to protect against " \
21
+ "public gem pushes."
22
+ end
23
+
24
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
25
+ f.match(%r{^(test|spec|features)/})
26
+ end
27
+ spec.bindir = "exe"
28
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
29
+ spec.require_paths = ["lib"]
30
+
31
+ spec.add_dependency 'guard-compat', '~> 1.2'
32
+ spec.add_dependency 'concurrent-ruby', '~> 1.0.4'
33
+
34
+ spec.add_development_dependency 'rake', '~> 10.0'
35
+ spec.add_development_dependency 'bundler', '~> 1.13'
36
+ spec.add_development_dependency 'rspec', '~> 3.5'
37
+ spec.add_development_dependency 'guard-rspec', '~> 4.7'
38
+ end
@@ -0,0 +1,16 @@
1
+ require 'rails/generators'
2
+
3
+ module GuardJest
4
+ class InstallGenerator < Rails::Generators::Base
5
+ desc 'Install a sample Guardfile for running Jest specs via GuardJest'
6
+
7
+ def self.source_root
8
+ @source_root ||= File.join(File.dirname(__FILE__), 'templates')
9
+ end
10
+
11
+ # Generator Code. Remember this is just suped-up Thor so methods are executed in order
12
+ def install
13
+ template 'Guardfile'
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,9 @@
1
+ # A sample Guardfile
2
+ # More info at https://github.com/guard/guard#readme
3
+
4
+ guard :jest do
5
+ watch(%r{^spec/javascripts/.*(?:_s|S)pec\.(coffee|js)$})
6
+ watch(%r{app/assets/javascripts/(.+?)\.(js\.coffee|js|coffee)(?:\.\w+)*$}) do |m|
7
+ "spec/javascripts/#{m[1]}_spec.#{m[2]}"
8
+ end
9
+ end
@@ -0,0 +1,113 @@
1
+ require 'logger'
2
+ require 'guard/compat/plugin'
3
+
4
+ require_relative 'jest/version'
5
+ require_relative 'jest/formatter'
6
+ require_relative 'jest/run_request'
7
+ require_relative 'jest/runner'
8
+ require_relative 'jest/server'
9
+
10
+ module Guard
11
+ # The Jest guard that gets notifications about the following
12
+ # Guard events: `start`, `stop`, `reload`, `run_all` and `run_on_modifications`.
13
+ class Jest < Plugin
14
+ class << self
15
+ attr_writer :logger
16
+ def logger
17
+ @logger ||= ( l = Logger.new(STDOUT); l.level = Logger::INFO; l )
18
+ end
19
+ end
20
+
21
+ DEFAULT_OPTIONS = {
22
+ jest_cmd: 'jest'
23
+ }.freeze
24
+
25
+ attr_reader :runner, :server
26
+
27
+ # Initialize Guard::Jest
28
+ #
29
+ # @param [Hash] options the options for the Guard
30
+ # @option options [String] :config_file the location of a Jest configuration file
31
+ # @option options [String] :jest_cmd path to jest application that should be executed
32
+ #
33
+ def initialize(options = {})
34
+ options = DEFAULT_OPTIONS.merge(options)
35
+ options[:server] = @server = options[:server] || Server.new(options)
36
+ @runner = options[:runner] || Runner.new(options)
37
+ super(options)
38
+ end
39
+
40
+ # Called once when Guard starts. Please override initialize method to init stuff.
41
+ #
42
+ # @raise [:task_has_failed] when start has failed
43
+ # @return [Object] the task result
44
+ #
45
+ def start
46
+ throw :task_has_failed unless server.start
47
+ run_all if options[:all_on_start]
48
+ end
49
+
50
+ # Called when `stop|quit|exit|s|q|e + enter` is pressed (when Guard quits).
51
+ #
52
+ # @raise [:task_has_failed] when stop has failed
53
+ # @return [Object] the task result
54
+ #
55
+ def stop
56
+ throw :task_has_failed unless server.stop
57
+ end
58
+
59
+ # Called when `reload|r|z + enter` is pressed.
60
+ # This method should be mainly used for "reload" (really!) actions like reloading passenger/spork/bundler/...
61
+ #
62
+ # @raise [:task_has_failed] when reload has failed
63
+ # @return [Object] the task result
64
+ #
65
+ def reload
66
+ server_success = server.reload(options)
67
+ runner_success = runner.reload(options)
68
+ throw :task_has_failed unless server_success && runner_success
69
+ end
70
+
71
+ # Called when just `enter` is pressed
72
+ # This method should be principally used for long action like running all specs/tests/...
73
+ #
74
+ # @raise [:task_has_failed] when run_all has failed
75
+ # @return [Object] the task result
76
+ #
77
+ def run_all
78
+ results = runner.test_all
79
+ throw :task_has_failed if results.failed?
80
+ end
81
+
82
+ # Called on file(s) additions that the Guard plugin watches.
83
+ #
84
+ # @param [Array<String>] paths the changes files or paths
85
+ # @raise [:task_has_failed] when run_on_additions has failed
86
+ # @return [Object] the task result
87
+ #
88
+ def run_on_additions(paths)
89
+ run_on_modifications(paths)
90
+ end
91
+
92
+ # Called on file(s) modifications that the Guard plugin watches.
93
+ #
94
+ # @param [Array<String>] paths the changes files or paths
95
+ # @raise [:task_has_failed] when run_on_modifications has failed
96
+ # @return [Object] the task result
97
+ #
98
+ def run_on_modifications(paths)
99
+ results = runner.test_paths(paths)
100
+ throw :task_has_failed if results.failed?
101
+ end
102
+
103
+ # Called on file(s) removals that the Guard plugin watches.
104
+ #
105
+ # @param [Array<String>] paths the changes files or paths
106
+ # @raise [:task_has_failed] when run_on_removals has failed
107
+ # @return [Object] the task result
108
+ #
109
+ def run_on_removals(paths)
110
+ runner.remove_paths(paths)
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,103 @@
1
+ require 'guard/compat/plugin'
2
+
3
+ module Guard
4
+ class Jest < Plugin
5
+ # The Guard::Jasmine formatter collects console and
6
+ # system notification methods and enhances them with
7
+ # some color information.
8
+ #
9
+ module Formatter
10
+ class << self
11
+ # Print an info message to the console.
12
+ #
13
+ # @param [String] message the message to print
14
+ # @param [Hash] options the output options
15
+ # @option options [Boolean] :reset reset the UI
16
+ #
17
+ def info(message, options = {})
18
+ Compat::UI.info(message, options)
19
+ end
20
+
21
+ # Print a debug message to the console.
22
+ #
23
+ # @param [String] message the message to print
24
+ # @param [Hash] options the output options
25
+ # @option options [Boolean] :reset reset the UI
26
+ #
27
+ def debug(message, options = {})
28
+ Compat::UI.debug(message, options)
29
+ end
30
+
31
+ # Print a red error message to the console.
32
+ #
33
+ # @param [String] message the message to print
34
+ # @param [Hash] options the output options
35
+ # @option options [Boolean] :reset reset the UI
36
+ #
37
+ def error(message, options = {})
38
+ Compat::UI.error(color(message, ';31'), options)
39
+ end
40
+
41
+ # Print a green success message to the console.
42
+ #
43
+ # @param [String] message the message to print
44
+ # @param [Hash] options the output options
45
+ # @option options [Boolean] :reset reset the UI
46
+ #
47
+ def success(message, options = {})
48
+ Compat::UI.info(color(message, ';32'), options)
49
+ end
50
+
51
+ # Print a yellow pending message to the console.
52
+ #
53
+ # @param [String] message the message to print
54
+ # @param [Hash] options the output options
55
+ # @option options [Boolean] :reset reset the UI
56
+ #
57
+ def spec_pending(message, options = {})
58
+ Compat::UI.info(color(message, ';33'), options)
59
+ end
60
+
61
+ # Print a red spec failed message to the console.
62
+ #
63
+ # @param [String] message the message to print
64
+ # @param [Hash] options the output options
65
+ #
66
+ def spec_failed(message, options = {})
67
+ Compat::UI.info(color(message, ';31'), options)
68
+ end
69
+
70
+ # Print a red spec failed message to the console.
71
+ #
72
+ # @param [String] message the message to print
73
+ # @param [Hash] options the output options
74
+ #
75
+ def suite_name(message, options = {})
76
+ Compat::UI.info(color(message, ';33'), options)
77
+ end
78
+
79
+ # Outputs a system notification.
80
+ #
81
+ # @param [String] message the message to print
82
+ # @param [Hash] options the output options
83
+ # @option options [Symbol, String] :image the image to use, either :failed, :pending or :success, or an image path
84
+ # @option options [String] :title the title of the system notification
85
+ #
86
+ def notify(message, options = {})
87
+ Compat::UI.notify(message, options)
88
+ end
89
+
90
+ private
91
+
92
+ # Print a info message to the console.
93
+ #
94
+ # @param [String] text the text to colorize
95
+ # @param [String] color_code the color code
96
+ #
97
+ def color(text, color_code)
98
+ Compat::UI.color_enabled? ? "\e[0#{color_code}m#{text}\e[0m" : text
99
+ end
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,41 @@
1
+ require 'concurrent/atomic/atomic_boolean'
2
+
3
+ module Guard
4
+ class Jest < Plugin
5
+ class RunRequest
6
+
7
+ attr_reader :paths, :runner, :result
8
+
9
+ def initialize(runner, paths)
10
+ @runner = runner
11
+ @paths = paths
12
+ @end_time = Time.now
13
+ @start_time = Time.now
14
+ @is_complete = Concurrent::AtomicBoolean.new(false)
15
+ end
16
+
17
+ def all?
18
+ :all == paths
19
+ end
20
+
21
+ def elapsed_seconds
22
+ if satisfied?
23
+ @end_time - @start_time
24
+ else
25
+ Time.now - @start_time
26
+ end
27
+ end
28
+
29
+ def satisfied?
30
+ @is_complete.true?
31
+ end
32
+
33
+ def satisfy(json)
34
+ @end_time = Time.now
35
+ @is_complete.make_true
36
+ @result = json
37
+ runner.notify(self)
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,78 @@
1
+ require 'guard/ui'
2
+ require 'guard/compat/plugin'
3
+
4
+ module Guard
5
+ class Jest < Plugin
6
+
7
+ class Runner
8
+ attr_reader :server, :options
9
+
10
+ attr_accessor :last_failed_paths, :last_result
11
+
12
+ def initialize(options)
13
+ reload(options)
14
+ end
15
+
16
+ def reload(options)
17
+ @options = options
18
+ @server = options[:server]
19
+ self.last_failed_paths = []
20
+ end
21
+
22
+ def test_all
23
+ server.run(RunRequest.new(self, :all))
24
+ end
25
+
26
+ def test_paths(paths)
27
+ paths = paths.concat(last_failed_paths) if options[:keep_failed]
28
+
29
+ server.run(RunRequest.new(self, paths.uniq.compact))
30
+ end
31
+
32
+ def remove_paths(paths)
33
+ self.last_failed_paths -= paths
34
+ end
35
+
36
+ def notify(request)
37
+ @last_result = r = request.result
38
+
39
+ specs = r['numTotalTests'] - r['numPendingTests']
40
+ failed = r['numFailedTests']
41
+ specs_plural = specs == 1 ? '' : 's'
42
+ failed_plural = failed == 1 ? '' : 's'
43
+
44
+ Formatter.info("Finished in #{request.elapsed_seconds} seconds")
45
+
46
+ pending = r['numPendingTests'] > 0 ? " #{r['numPendingTests']} pending," : ''
47
+ message = "#{specs} spec#{specs_plural}," \
48
+ "#{pending} #{failed} failure#{failed_plural}"
49
+ full_message = "#{message}\nin #{request.elapsed_seconds} seconds"
50
+
51
+ if failed.zero?
52
+ Formatter.success(message)
53
+ Formatter.notify(full_message, title: 'Jest suite passed')
54
+ else
55
+ Formatter.error(
56
+ collect_spec_error_messages(r['testResults']).join("\n")
57
+ )
58
+ error_title = collect_spec_error_titles(r['testResults']).join("\n")
59
+ Formatter.notify("#{error_title}\n#{full_message}",
60
+ title: 'Jest test run failed', image: :failed, priority: 2)
61
+ end
62
+ end
63
+
64
+ def collect_spec_error_titles(specs)
65
+ specs.select { |s| s['status'] == 'failed' }.map do |s|
66
+ result = s['assertionResults'].detect { |res| res['status'] == 'failed' }
67
+ result ? result['title'] : 'Unknown failure'
68
+ end
69
+ end
70
+
71
+ def collect_spec_error_messages(specs)
72
+ specs.select { |s| s['status'] == 'failed' }.map do |s|
73
+ s['message']
74
+ end
75
+ end
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,132 @@
1
+ require 'concurrent/array'
2
+ require 'concurrent/atomic/atomic_boolean'
3
+ require 'pty'
4
+ require 'json'
5
+
6
+ module Guard
7
+ class Jest < Plugin
8
+
9
+ class Server
10
+ CR = 13.chr
11
+
12
+ attr_reader :stdout, :stdin, :pid, :last_result, :options, :cmd, :pending
13
+
14
+ def initialize(options = {})
15
+ reload(options)
16
+ @work_in_progress = Concurrent::AtomicBoolean.new(false)
17
+ @pending = Concurrent::Array.new
18
+ end
19
+
20
+ def run(request)
21
+ start unless alive?
22
+ pending << request
23
+ work_fifo_queue
24
+ self
25
+ end
26
+
27
+ def failed?
28
+ @pid && !alive?
29
+ end
30
+
31
+ def busy?
32
+ @work_in_progress.true?
33
+ end
34
+
35
+ def wait_until_not_busy
36
+ sleep(0.1) while busy?
37
+ end
38
+
39
+ def start
40
+ @threads = []
41
+ @work_in_progress.make_true
42
+ @directory ? Dir.chdir(@directory) { spawn } : spawn
43
+ @threads << Thread.new do
44
+ @stdout.each { |line| record_result(line) }
45
+ end
46
+ self
47
+ end
48
+
49
+ def alive?
50
+ return false unless pid
51
+ Process.kill(0, pid)
52
+ return true
53
+ rescue Errno::ESRCH # "No such process"
54
+ return false
55
+ rescue Errno::EPERM # "Operation not permitted, but it at least exists
56
+ return true
57
+ else
58
+ return true
59
+ end
60
+
61
+ def stop
62
+ stdin.write('q')
63
+ sleep(0.1)
64
+ return unless alive?
65
+ Process.kill("TERM", pid)
66
+ sleep(0.1)
67
+ Process.kill("KILL", pid) if alive?
68
+ @pid = nil
69
+ end
70
+
71
+ def reload(options)
72
+ @options = options
73
+ @directory = options[:directory]
74
+ @cmd = options[:jest_cmd] + ' --json --silent true --watch'
75
+ @cmd << " --config #{options[:config_file]}" if options[:config_file]
76
+ if alive?
77
+ stop
78
+ start
79
+ end
80
+ self
81
+ end
82
+
83
+ private
84
+
85
+ def work_fifo_queue
86
+ return if busy? || pending.none?
87
+ request = pending.first
88
+ if request.all?
89
+ run_all
90
+ else
91
+ run_paths(request.paths)
92
+ end
93
+ end
94
+
95
+ def run_all
96
+ @work_in_progress.make_true
97
+ stdin.write('a')
98
+ end
99
+
100
+ def run_paths(paths)
101
+ @work_in_progress.make_true
102
+ stdin.write('p')
103
+ # the sleep values simply "seem to work ok" and may need refinement
104
+ sleep(0.1)
105
+ stdin.write(paths.join('|'))
106
+ sleep(0.1)
107
+ stdin.write(CR)
108
+ end
109
+
110
+ def record_result(line)
111
+ # looks vaguely jsonish if it starts with {"
112
+ return unless line.start_with?('{"')
113
+ begin
114
+ json = JSON.parse(line)
115
+ result = @pending.pop
116
+ result.satisfy(json) if result
117
+ @work_in_progress.make_false
118
+ work_fifo_queue
119
+ rescue => e
120
+ Jest.logger.warn e
121
+ end
122
+ end
123
+
124
+ def spawn
125
+ Jest.logger.debug "starting jest with #{cmd}"
126
+ @stdout, @stdin, @pid = PTY.spawn(cmd)
127
+ end
128
+
129
+ end
130
+
131
+ end
132
+ end
@@ -0,0 +1,7 @@
1
+ require 'guard/compat/plugin'
2
+
3
+ module Guard
4
+ class Jest < Plugin
5
+ VERSION = "0.1.0"
6
+ end
7
+ end
metadata ADDED
@@ -0,0 +1,148 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: guard-jest
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Nathan Stitt
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-01-17 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: guard-compat
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.2'
27
+ - !ruby/object:Gem::Dependency
28
+ name: concurrent-ruby
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: 1.0.4
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: 1.0.4
41
+ - !ruby/object:Gem::Dependency
42
+ name: rake
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '10.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '10.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: bundler
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '1.13'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '1.13'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rspec
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: '3.5'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: '3.5'
83
+ - !ruby/object:Gem::Dependency
84
+ name: guard-rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - "~>"
88
+ - !ruby/object:Gem::Version
89
+ version: '4.7'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - "~>"
95
+ - !ruby/object:Gem::Version
96
+ version: '4.7'
97
+ description: Guard plugin for testing Javascript using the Jest test runner
98
+ email:
99
+ - nathan@stitt.org
100
+ executables: []
101
+ extensions: []
102
+ extra_rdoc_files: []
103
+ files:
104
+ - ".gitignore"
105
+ - ".rubocop.yml"
106
+ - ".travis.yml"
107
+ - Gemfile
108
+ - Guardfile
109
+ - LICENSE.txt
110
+ - README.md
111
+ - Rakefile
112
+ - bin/console
113
+ - bin/setup
114
+ - guard-jest.gemspec
115
+ - lib/generators/guard_jest/install_generator.rb
116
+ - lib/generators/guard_jest/templates/Guardfile
117
+ - lib/guard/jest.rb
118
+ - lib/guard/jest/formatter.rb
119
+ - lib/guard/jest/run_request.rb
120
+ - lib/guard/jest/runner.rb
121
+ - lib/guard/jest/server.rb
122
+ - lib/guard/jest/version.rb
123
+ homepage: https://github.com/nathanstitt/guard-jest
124
+ licenses:
125
+ - MIT
126
+ metadata:
127
+ allowed_push_host: https://rubygems.org
128
+ post_install_message:
129
+ rdoc_options: []
130
+ require_paths:
131
+ - lib
132
+ required_ruby_version: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - ">="
135
+ - !ruby/object:Gem::Version
136
+ version: '0'
137
+ required_rubygems_version: !ruby/object:Gem::Requirement
138
+ requirements:
139
+ - - ">="
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ requirements: []
143
+ rubyforge_project:
144
+ rubygems_version: 2.6.8
145
+ signing_key:
146
+ specification_version: 4
147
+ summary: Guard plugin for auto-running Jest specs
148
+ test_files: []