guard-openscad 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/.rspec +1 -0
- data/.simplecov +55 -0
- data/Gemfile +20 -0
- data/Guardfile +13 -0
- data/LICENSE.txt +20 -0
- data/README.rdoc +19 -0
- data/Rakefile +50 -0
- data/VERSION +1 -0
- data/guard-openscad.gemspec +87 -0
- data/lib/guard/openscad.rb +124 -0
- data/lib/guard/openscad/templates/Guardfile +5 -0
- data/spec/fixtures/scad/cube.scad +1 -0
- data/spec/guard/openscad_spec.rb +240 -0
- data/spec/integration/guard/openscad_spec.rb +52 -0
- data/spec/spec_helper.rb +13 -0
- data/spec/support/core_ext/hash/except.rb +6 -0
- data/spec/support/matchers/run_files_matcher.rb +17 -0
- metadata +244 -0
data/.document
ADDED
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/.simplecov
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
require 'simplecov-csv'
|
2
|
+
|
3
|
+
def isolation_mode?
|
4
|
+
ENV.fetch("ISOLATION_MODE",false)
|
5
|
+
end
|
6
|
+
|
7
|
+
def stats_mode?
|
8
|
+
ENV.fetch("STATS_MODE", false)
|
9
|
+
end
|
10
|
+
|
11
|
+
module SimpleCov::Formatter
|
12
|
+
class MutedHTMLFormatter < HTMLFormatter
|
13
|
+
def puts(*args)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class MutedCSVFormatter < CSVFormatter
|
18
|
+
def puts(*args)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class MutedMergedFormatter
|
23
|
+
def format(results)
|
24
|
+
[MutedHTMLFormatter, MutedCSVFormatter].each do |formatter|
|
25
|
+
formatter.new.format(results)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class MergedFormatter
|
31
|
+
def format(results)
|
32
|
+
[HTMLFormatter, CSVFormatter].each do |formatter|
|
33
|
+
formatter.new.format(results)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
if isolation_mode?
|
40
|
+
SimpleCov.formatter = SimpleCov::Formatter::MutedCSVFormatter
|
41
|
+
SimpleCov.use_merging false
|
42
|
+
elsif stats_mode?
|
43
|
+
SimpleCov.formatter = SimpleCov::Formatter::MutedCSVFormatter
|
44
|
+
else
|
45
|
+
SimpleCov.formatter = SimpleCov::Formatter::MergedFormatter
|
46
|
+
end
|
47
|
+
|
48
|
+
SimpleCov.start do
|
49
|
+
add_filter 'bin/'
|
50
|
+
add_filter 'features/'
|
51
|
+
add_filter 'spec/'
|
52
|
+
|
53
|
+
add_group "Use Cases", "use_cases"
|
54
|
+
add_group "Entities", "lib"
|
55
|
+
end
|
data/Gemfile
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
source "http://rubygems.org"
|
2
|
+
|
3
|
+
gem "growl"
|
4
|
+
gem "guard"
|
5
|
+
|
6
|
+
gem "rb-fsevent"
|
7
|
+
|
8
|
+
gem "scad4r", git: "git://github.com/cpb/scad4r.git"
|
9
|
+
|
10
|
+
group :development do
|
11
|
+
gem "rspec"
|
12
|
+
gem "rdoc"
|
13
|
+
gem "bundler"
|
14
|
+
gem "jeweler"
|
15
|
+
|
16
|
+
gem "simplecov"
|
17
|
+
gem "simplecov-csv"
|
18
|
+
|
19
|
+
gem "guard-rspec", git: "git://github.com/guard/guard-rspec.git"
|
20
|
+
end
|
data/Guardfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
# A sample Guardfile
|
2
|
+
# More info at https://github.com/guard/guard#readme
|
3
|
+
|
4
|
+
guard 'rspec', focused_on_failed: true do
|
5
|
+
watch(%r{^spec/.+_spec\.rb$})
|
6
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
|
7
|
+
watch(%r{^lib/(.+)\.rb$}) { |m| "spec/integration/#{m[1]}_spec.rb" }
|
8
|
+
watch("lib/guard/openscad/templates/Guardfile") { |m| "spec/integration" }
|
9
|
+
|
10
|
+
watch('spec/spec_helper.rb') { "spec" }
|
11
|
+
watch(%r{^spec/support/(.+)\.rb$}) { "spec" }
|
12
|
+
end
|
13
|
+
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2013 Caleb Buxton
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
= guard-openscad
|
2
|
+
|
3
|
+
Description goes here.
|
4
|
+
|
5
|
+
== Contributing to guard-openscad
|
6
|
+
|
7
|
+
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet.
|
8
|
+
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it.
|
9
|
+
* Fork the project.
|
10
|
+
* Start a feature/bugfix branch.
|
11
|
+
* Commit and push until you are happy with your contribution.
|
12
|
+
* Make sure to add tests for it. This is important so I don't break it in a future version unintentionally.
|
13
|
+
* Please try not to mess with the Rakefile, version, or history. If you want to have your own version, or is otherwise necessary, that is fine, but please isolate to its own commit so I can cherry-pick around it.
|
14
|
+
|
15
|
+
== Copyright
|
16
|
+
|
17
|
+
Copyright (c) 2013 Caleb Buxton. See LICENSE.txt for
|
18
|
+
further details.
|
19
|
+
|
data/Rakefile
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
|
14
|
+
require 'jeweler'
|
15
|
+
Jeweler::Tasks.new do |gem|
|
16
|
+
# gem is a Gem::Specification... see http://docs.rubygems.org/read/chapter/20 for more options
|
17
|
+
gem.name = "guard-openscad"
|
18
|
+
gem.homepage = "http://github.com/cpb/guard-openscad"
|
19
|
+
gem.license = "MIT"
|
20
|
+
gem.summary = %Q{Guard plugin for OpenSCAD}
|
21
|
+
gem.description = %Q{Checks syntax of .scad files and generates .stl files.}
|
22
|
+
gem.email = "me@cpb.ca"
|
23
|
+
gem.authors = ["Caleb Buxton"]
|
24
|
+
# dependencies defined in Gemfile
|
25
|
+
end
|
26
|
+
Jeweler::RubygemsDotOrgTasks.new
|
27
|
+
|
28
|
+
require 'rspec/core'
|
29
|
+
require 'rspec/core/rake_task'
|
30
|
+
RSpec::Core::RakeTask.new(:spec) do |spec|
|
31
|
+
spec.pattern = FileList['spec/**/*_spec.rb']
|
32
|
+
spec.rspec_opts = "-r simplecov -p"
|
33
|
+
end
|
34
|
+
|
35
|
+
RSpec::Core::RakeTask.new(:rcov) do |spec|
|
36
|
+
spec.pattern = 'spec/**/*_spec.rb'
|
37
|
+
spec.rcov = true
|
38
|
+
end
|
39
|
+
|
40
|
+
task :default => :spec
|
41
|
+
|
42
|
+
require 'rdoc/task'
|
43
|
+
Rake::RDocTask.new do |rdoc|
|
44
|
+
version = File.exist?('VERSION') ? File.read('VERSION') : ""
|
45
|
+
|
46
|
+
rdoc.rdoc_dir = 'rdoc'
|
47
|
+
rdoc.title = "guard-openscad #{version}"
|
48
|
+
rdoc.rdoc_files.include('README*')
|
49
|
+
rdoc.rdoc_files.include('lib/**/*.rb')
|
50
|
+
end
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.1.0
|
@@ -0,0 +1,87 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "guard-openscad"
|
8
|
+
s.version = "0.1.0"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Caleb Buxton"]
|
12
|
+
s.date = "2013-01-26"
|
13
|
+
s.description = "Checks syntax of .scad files and generates .stl files."
|
14
|
+
s.email = "me@cpb.ca"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.rdoc"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
".rspec",
|
22
|
+
".simplecov",
|
23
|
+
"Gemfile",
|
24
|
+
"Guardfile",
|
25
|
+
"LICENSE.txt",
|
26
|
+
"README.rdoc",
|
27
|
+
"Rakefile",
|
28
|
+
"VERSION",
|
29
|
+
"guard-openscad.gemspec",
|
30
|
+
"lib/guard/openscad.rb",
|
31
|
+
"lib/guard/openscad/templates/Guardfile",
|
32
|
+
"spec/fixtures/scad/cube.scad",
|
33
|
+
"spec/guard/openscad_spec.rb",
|
34
|
+
"spec/integration/guard/openscad_spec.rb",
|
35
|
+
"spec/spec_helper.rb",
|
36
|
+
"spec/support/core_ext/hash/except.rb",
|
37
|
+
"spec/support/matchers/run_files_matcher.rb"
|
38
|
+
]
|
39
|
+
s.homepage = "http://github.com/cpb/guard-openscad"
|
40
|
+
s.licenses = ["MIT"]
|
41
|
+
s.require_paths = ["lib"]
|
42
|
+
s.rubygems_version = "1.8.23"
|
43
|
+
s.summary = "Guard plugin for OpenSCAD"
|
44
|
+
|
45
|
+
if s.respond_to? :specification_version then
|
46
|
+
s.specification_version = 3
|
47
|
+
|
48
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
49
|
+
s.add_runtime_dependency(%q<growl>, [">= 0"])
|
50
|
+
s.add_runtime_dependency(%q<guard>, [">= 0"])
|
51
|
+
s.add_runtime_dependency(%q<rb-fsevent>, [">= 0"])
|
52
|
+
s.add_runtime_dependency(%q<scad4r>, [">= 0"])
|
53
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
54
|
+
s.add_development_dependency(%q<rdoc>, [">= 0"])
|
55
|
+
s.add_development_dependency(%q<bundler>, [">= 0"])
|
56
|
+
s.add_development_dependency(%q<jeweler>, [">= 0"])
|
57
|
+
s.add_development_dependency(%q<simplecov>, [">= 0"])
|
58
|
+
s.add_development_dependency(%q<simplecov-csv>, [">= 0"])
|
59
|
+
s.add_development_dependency(%q<guard-rspec>, [">= 0"])
|
60
|
+
else
|
61
|
+
s.add_dependency(%q<growl>, [">= 0"])
|
62
|
+
s.add_dependency(%q<guard>, [">= 0"])
|
63
|
+
s.add_dependency(%q<rb-fsevent>, [">= 0"])
|
64
|
+
s.add_dependency(%q<scad4r>, [">= 0"])
|
65
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
66
|
+
s.add_dependency(%q<rdoc>, [">= 0"])
|
67
|
+
s.add_dependency(%q<bundler>, [">= 0"])
|
68
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
69
|
+
s.add_dependency(%q<simplecov>, [">= 0"])
|
70
|
+
s.add_dependency(%q<simplecov-csv>, [">= 0"])
|
71
|
+
s.add_dependency(%q<guard-rspec>, [">= 0"])
|
72
|
+
end
|
73
|
+
else
|
74
|
+
s.add_dependency(%q<growl>, [">= 0"])
|
75
|
+
s.add_dependency(%q<guard>, [">= 0"])
|
76
|
+
s.add_dependency(%q<rb-fsevent>, [">= 0"])
|
77
|
+
s.add_dependency(%q<scad4r>, [">= 0"])
|
78
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
79
|
+
s.add_dependency(%q<rdoc>, [">= 0"])
|
80
|
+
s.add_dependency(%q<bundler>, [">= 0"])
|
81
|
+
s.add_dependency(%q<jeweler>, [">= 0"])
|
82
|
+
s.add_dependency(%q<simplecov>, [">= 0"])
|
83
|
+
s.add_dependency(%q<simplecov-csv>, [">= 0"])
|
84
|
+
s.add_dependency(%q<guard-rspec>, [">= 0"])
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
@@ -0,0 +1,124 @@
|
|
1
|
+
require 'benchmark'
|
2
|
+
|
3
|
+
require 'scad4r/runner'
|
4
|
+
require 'scad4r/notification'
|
5
|
+
require 'scad4r/result_parser'
|
6
|
+
|
7
|
+
require 'guard'
|
8
|
+
require 'guard/guard'
|
9
|
+
|
10
|
+
module Guard
|
11
|
+
class Openscad < Guard
|
12
|
+
|
13
|
+
attr_reader :runner
|
14
|
+
def initialize(watches=[], options = {})
|
15
|
+
super
|
16
|
+
|
17
|
+
net_options = {all_on_start: true,
|
18
|
+
benchmark: true,
|
19
|
+
|
20
|
+
runner: Scad4r::Runner,
|
21
|
+
result_parser: Scad4r::ResultParser,
|
22
|
+
format: :stl,
|
23
|
+
|
24
|
+
notifier: Notifier,
|
25
|
+
notification_parser: Scad4r::Notification}.merge(options)
|
26
|
+
|
27
|
+
# Behaviour options
|
28
|
+
@all_on_start = net_options.fetch(:all_on_start)
|
29
|
+
@benchmark = net_options.fetch(:benchmark)
|
30
|
+
|
31
|
+
@runner = build_runner(net_options)
|
32
|
+
|
33
|
+
@notifier = net_options.fetch(:notifier)
|
34
|
+
@notification_parser = net_options.fetch(:notification_parser)
|
35
|
+
|
36
|
+
@failed = false
|
37
|
+
end
|
38
|
+
|
39
|
+
def start
|
40
|
+
run_all if all_on_start?
|
41
|
+
end
|
42
|
+
|
43
|
+
def run_all
|
44
|
+
run_on_changes(all_watched_files)
|
45
|
+
end
|
46
|
+
|
47
|
+
def run_on_changes(paths)
|
48
|
+
failed = false
|
49
|
+
|
50
|
+
run_list(paths).each do |path|
|
51
|
+
result = process(path)
|
52
|
+
|
53
|
+
if result.has_key?(:error) || result.has_key?(:warning)
|
54
|
+
failed = true
|
55
|
+
end
|
56
|
+
|
57
|
+
notifications = parse_results(result)
|
58
|
+
notifications.each { |notification| notify(notification) }
|
59
|
+
end
|
60
|
+
|
61
|
+
if failed
|
62
|
+
throw :task_has_failed
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
attr_reader :notifier, :notification_parser
|
68
|
+
|
69
|
+
def build_runner(options)
|
70
|
+
result_parser = options.fetch(:result_parser).new
|
71
|
+
format = options.fetch(:format)
|
72
|
+
runner_class = options.fetch(:runner)
|
73
|
+
|
74
|
+
runner_class.new(parser: result_parser,
|
75
|
+
format: format)
|
76
|
+
end
|
77
|
+
|
78
|
+
def process(path)
|
79
|
+
result = nil
|
80
|
+
benchmark("Processing #{path}") do
|
81
|
+
result = runner.run(path)
|
82
|
+
end
|
83
|
+
result
|
84
|
+
end
|
85
|
+
|
86
|
+
def notify(notification)
|
87
|
+
benchmark("Sending Notification") do
|
88
|
+
notifier.notify(notification.message,
|
89
|
+
title: notification.title,
|
90
|
+
image: notification.image,
|
91
|
+
priority: notification.priority)
|
92
|
+
UI.info([notification.title,notification.message].join(' '))
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def parse_results(result)
|
97
|
+
notification = nil
|
98
|
+
benchmark("Parsing Results") do
|
99
|
+
notification = notification_parser.parse(result)
|
100
|
+
end
|
101
|
+
notification
|
102
|
+
end
|
103
|
+
|
104
|
+
def benchmark(message,&block)
|
105
|
+
if @benchmark
|
106
|
+
UI.info(message + " " + Benchmark.measure(&block).to_s)
|
107
|
+
else
|
108
|
+
block.call
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def run_list(paths)
|
113
|
+
Array(paths)
|
114
|
+
end
|
115
|
+
|
116
|
+
def all_on_start?
|
117
|
+
@all_on_start
|
118
|
+
end
|
119
|
+
|
120
|
+
def all_watched_files
|
121
|
+
Watcher.match_files(self,Dir.glob('{,**/}*{,.*}').uniq)
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
cube(10);
|
@@ -0,0 +1,240 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'guard/openscad'
|
3
|
+
|
4
|
+
module Guard
|
5
|
+
module UI
|
6
|
+
|
7
|
+
end
|
8
|
+
|
9
|
+
describe Openscad do
|
10
|
+
|
11
|
+
before do
|
12
|
+
UI.stub(:info)
|
13
|
+
end
|
14
|
+
|
15
|
+
include RunFilesMatcher
|
16
|
+
|
17
|
+
def di(instance)
|
18
|
+
double("DI Faker", new: instance)
|
19
|
+
end
|
20
|
+
|
21
|
+
let(:runner) {
|
22
|
+
double("Scad Runner", run: run_result) }
|
23
|
+
|
24
|
+
let(:run_result) { {} }
|
25
|
+
|
26
|
+
let(:watches) { [double("Watch")] }
|
27
|
+
let(:notifier) { double("Notifier", notify: true) }
|
28
|
+
let(:notification_parser) { double("Notification Parser", parse: []) }
|
29
|
+
|
30
|
+
let(:notification) { double("Scad4r::Notification",message: notification_message,
|
31
|
+
title: notification_title,
|
32
|
+
priority: notification_priority,
|
33
|
+
image: notification_image)}
|
34
|
+
|
35
|
+
let(:notification_message) { "a message" }
|
36
|
+
let(:notification_title) { "a title" }
|
37
|
+
let(:notification_priority) { 2 }
|
38
|
+
let(:notification_image) { :error }
|
39
|
+
|
40
|
+
let(:test_mock_options) { { benchmark: false,
|
41
|
+
notifier: notifier,
|
42
|
+
notification_parser: notification_parser } }
|
43
|
+
|
44
|
+
describe ".initialize" do
|
45
|
+
context "creating a runner" do
|
46
|
+
|
47
|
+
it "should use the Scad4r::ResultParser by default" do
|
48
|
+
Scad4r::Runner.
|
49
|
+
should_receive(:new).
|
50
|
+
with(hash_including(parser: an_instance_of(Scad4r::ResultParser)))
|
51
|
+
|
52
|
+
described_class.new
|
53
|
+
end
|
54
|
+
|
55
|
+
let(:runner_dependency) { Scad4r::Runner }
|
56
|
+
|
57
|
+
it "should pass the format option to the runner" do
|
58
|
+
runner_dependency.
|
59
|
+
should_receive(:new).
|
60
|
+
with(hash_including(format: :csg))
|
61
|
+
|
62
|
+
described_class.new(watches, format: :csg)
|
63
|
+
end
|
64
|
+
|
65
|
+
context ":runner option injected" do
|
66
|
+
let(:alternate_runner) {
|
67
|
+
double("An Alernate Runner Class", new: true) }
|
68
|
+
|
69
|
+
it "should initialize the injected class instead" do
|
70
|
+
Scad4r::Runner.should_not_receive(:new)
|
71
|
+
alternate_runner.should_receive(:new)
|
72
|
+
|
73
|
+
described_class.new(watches,test_mock_options.merge(runner: alternate_runner))
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
describe "#start" do
|
80
|
+
it "calls #run_all" do
|
81
|
+
subject.should_receive(:run_all)
|
82
|
+
|
83
|
+
subject.start
|
84
|
+
end
|
85
|
+
|
86
|
+
context ":all_on_start option is false" do
|
87
|
+
subject { described_class.new(watches, test_mock_options.merge(all_on_start: false)) }
|
88
|
+
|
89
|
+
it "doesn't call #run_all" do
|
90
|
+
subject.should_not_receive(:run_all)
|
91
|
+
|
92
|
+
subject.start
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "#run_all" do
|
98
|
+
subject {
|
99
|
+
described_class.new(watches, test_mock_options.merge(runner: di(runner))) }
|
100
|
+
|
101
|
+
subject { described_class.new(watches, test_mock_options.merge(
|
102
|
+
runner: di(runner))) }
|
103
|
+
|
104
|
+
it "should run all scad files which match the watches" do
|
105
|
+
Watcher.should_receive(:match_files).
|
106
|
+
with(subject,an_instance_of(Array)).
|
107
|
+
and_return([:matched_files])
|
108
|
+
|
109
|
+
subject.should_receive(:run_on_changes).with([:matched_files])
|
110
|
+
subject.run_all
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
describe "#run_on_changes" do
|
115
|
+
subject {
|
116
|
+
described_class.new(watches, test_mock_options.merge(runner: di(runner))) }
|
117
|
+
|
118
|
+
it "runs with paths" do
|
119
|
+
subject.should run_files("scad/cube.scad")
|
120
|
+
|
121
|
+
subject.run_on_changes("scad/cube.scad")
|
122
|
+
|
123
|
+
subject.should run_files(["scad/cube.scad", "scad/jhead.scad"])
|
124
|
+
|
125
|
+
subject.run_on_changes(["scad/cube.scad", "scad/jhead.scad"])
|
126
|
+
end
|
127
|
+
|
128
|
+
context "during failure" do
|
129
|
+
it "throws :task_has_failed if the results include a warning or error" do
|
130
|
+
runner.should_receive(:run).and_return({warning: true, error: true})
|
131
|
+
|
132
|
+
expect { subject.run_on_changes("scad/cube.scad") }.to throw_symbol(:task_has_failed)
|
133
|
+
|
134
|
+
runner.should_receive(:run).and_return({error: true})
|
135
|
+
|
136
|
+
expect { subject.run_on_changes("scad/cube.scad") }.to throw_symbol(:task_has_failed)
|
137
|
+
|
138
|
+
runner.should_receive(:run).and_return({warning: true})
|
139
|
+
|
140
|
+
expect { subject.run_on_changes("scad/cube.scad") }.to throw_symbol(:task_has_failed)
|
141
|
+
|
142
|
+
runner.should_receive(:run).and_return({})
|
143
|
+
|
144
|
+
expect { subject.run_on_changes("scad/cube.scad") }.to_not throw_symbol(:task_has_failed)
|
145
|
+
end
|
146
|
+
|
147
|
+
it "keeps failed drawings and rerun them later"
|
148
|
+
end
|
149
|
+
|
150
|
+
context "the changed specs pass after failing" do
|
151
|
+
it "calls #run_all"
|
152
|
+
|
153
|
+
context ":all_after_pass option is false" do
|
154
|
+
it "doesn't call #run_all"
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
context "the changed specs pass without failing" do
|
159
|
+
it "doesn't call #run_all"
|
160
|
+
end
|
161
|
+
|
162
|
+
context "#run_on_changes focus_on_failed" do
|
163
|
+
it "switches focus if a single spec changes"
|
164
|
+
it "keeps focus if a single spec remains"
|
165
|
+
it "keeps focus if random stuff changes"
|
166
|
+
it "reruns the tests on the file if keep_failed is true and focused tests pass"
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
describe "notifications" do
|
171
|
+
subject {
|
172
|
+
described_class.new(watches, test_mock_options.merge(runner: di(runner))) }
|
173
|
+
|
174
|
+
context ":notification_parser is a mock" do
|
175
|
+
it "should receive parse" do
|
176
|
+
notification_parser.should_receive(:parse).with(run_result).and_return([])
|
177
|
+
|
178
|
+
subject.run_on_changes("scad/cube.scad")
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
context "default notification_parser" do
|
183
|
+
subject {
|
184
|
+
described_class.new(watches, test_mock_options.
|
185
|
+
except(:notification_parser).merge(
|
186
|
+
runner: di(runner))) }
|
187
|
+
|
188
|
+
it "should parse with Scad4r::Notification" do
|
189
|
+
Scad4r::Notification.should_receive(:parse).with(run_result).and_return([])
|
190
|
+
|
191
|
+
subject.run_on_changes("scad/cube.scad")
|
192
|
+
end
|
193
|
+
end
|
194
|
+
|
195
|
+
context ":notifier is a mock" do
|
196
|
+
it "should notify the notifier" do
|
197
|
+
notifier.should_receive(:notify)
|
198
|
+
|
199
|
+
notification_parser.should_receive(:parse).and_return([notification])
|
200
|
+
|
201
|
+
subject.run_on_changes("scad/cube.scad")
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
context "default notifier" do
|
206
|
+
subject {
|
207
|
+
described_class.new(watches, test_mock_options.
|
208
|
+
except(:notifier).merge(
|
209
|
+
runner: di(runner))) }
|
210
|
+
|
211
|
+
it "should notify Guard::Notifier" do
|
212
|
+
Notifier.should_receive(:notify)
|
213
|
+
|
214
|
+
notification_parser.should_receive(:parse).and_return([notification])
|
215
|
+
|
216
|
+
subject.run_on_changes("scad/cube.scad")
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
context "with notifications" do
|
221
|
+
before do
|
222
|
+
notification_parser.stub(:parse).and_return([notification])
|
223
|
+
end
|
224
|
+
|
225
|
+
after do
|
226
|
+
subject.run_on_changes("scad/cube.scad")
|
227
|
+
end
|
228
|
+
|
229
|
+
it "should notify with the notification message" do
|
230
|
+
notifier.should_receive(:notify).with(notification_message, an_instance_of(Hash))
|
231
|
+
end
|
232
|
+
|
233
|
+
it "should notify with the notification title" do
|
234
|
+
notifier.should_receive(:notify).with(an_instance_of(String), hash_including(
|
235
|
+
title: notification_title))
|
236
|
+
end
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
240
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'guard/openscad'
|
3
|
+
|
4
|
+
# I am aware that I have stubs in an integration test.
|
5
|
+
# I am just trying to rush out the outline of a full Guard.
|
6
|
+
|
7
|
+
describe Guard::Openscad do
|
8
|
+
context "finding the Openscad Guard" do
|
9
|
+
it "should be a Guard::Guard" do
|
10
|
+
should be_a(Guard::Guard)
|
11
|
+
end
|
12
|
+
end
|
13
|
+
|
14
|
+
context "group should not be nil" do
|
15
|
+
its(:group) { should eql(:default) }
|
16
|
+
end
|
17
|
+
|
18
|
+
context "initializing" do
|
19
|
+
it "should accept watches and options" do
|
20
|
+
described_class.new([:watches],{options: :accepted})
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
context "'s generated template" do
|
25
|
+
before do
|
26
|
+
Guard.stub(:locate_guard).and_return(FileUtils.pwd)
|
27
|
+
end
|
28
|
+
|
29
|
+
let(:scanner) { StringScanner.new(guard_template) }
|
30
|
+
let(:guard_template) { described_class.template(:openscad) }
|
31
|
+
|
32
|
+
subject { guard_template }
|
33
|
+
|
34
|
+
it { should include "group :csg do" }
|
35
|
+
|
36
|
+
context "csg group" do
|
37
|
+
subject { scanner.scan_until(/group :csg do\n/) ; scanner.rest }
|
38
|
+
|
39
|
+
it "should guard openscad" do
|
40
|
+
should include("guard :openscad")
|
41
|
+
end
|
42
|
+
|
43
|
+
it "should be configured for the csg format" do
|
44
|
+
should include(", format: :csg do")
|
45
|
+
end
|
46
|
+
|
47
|
+
it "should watch all scad files in scad/" do
|
48
|
+
should include("watch(%r{^scad/.+\\.scad$})")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
2
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
3
|
+
require 'rspec'
|
4
|
+
|
5
|
+
# Requires supporting files with custom matchers and macros, etc,
|
6
|
+
# in ./support/ and its subdirectories.
|
7
|
+
Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each {|f| require f}
|
8
|
+
|
9
|
+
RSpec.configure do |config|
|
10
|
+
config.before(:each) do
|
11
|
+
@fixture_path = Pathname.new(File.expand_path('../fixtures/', __FILE__))
|
12
|
+
end
|
13
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module RunFilesMatcher
|
2
|
+
extend RSpec::Matchers::DSL
|
3
|
+
|
4
|
+
matcher :run_files do |expected_files|
|
5
|
+
@expected_files = Array(expected_files)
|
6
|
+
|
7
|
+
match_for_should do |with_running_member|
|
8
|
+
if @expected_files.empty?
|
9
|
+
fail "Expected #{with_running_member} to run some files, but you provided none."
|
10
|
+
else
|
11
|
+
@expected_files.each do |expected_file|
|
12
|
+
with_running_member.runner.should_receive(:run).with(expected_file)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
metadata
ADDED
@@ -0,0 +1,244 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: guard-openscad
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 0.1.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Caleb Buxton
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-01-26 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
type: :runtime
|
16
|
+
version_requirements: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
name: growl
|
23
|
+
prerelease: false
|
24
|
+
requirement: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
type: :runtime
|
32
|
+
version_requirements: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
name: guard
|
39
|
+
prerelease: false
|
40
|
+
requirement: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
type: :runtime
|
48
|
+
version_requirements: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
name: rb-fsevent
|
55
|
+
prerelease: false
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
type: :runtime
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '0'
|
70
|
+
name: scad4r
|
71
|
+
prerelease: false
|
72
|
+
requirement: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '0'
|
78
|
+
- !ruby/object:Gem::Dependency
|
79
|
+
type: :development
|
80
|
+
version_requirements: !ruby/object:Gem::Requirement
|
81
|
+
none: false
|
82
|
+
requirements:
|
83
|
+
- - ! '>='
|
84
|
+
- !ruby/object:Gem::Version
|
85
|
+
version: '0'
|
86
|
+
name: rspec
|
87
|
+
prerelease: false
|
88
|
+
requirement: !ruby/object:Gem::Requirement
|
89
|
+
none: false
|
90
|
+
requirements:
|
91
|
+
- - ! '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
- !ruby/object:Gem::Dependency
|
95
|
+
type: :development
|
96
|
+
version_requirements: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
name: rdoc
|
103
|
+
prerelease: false
|
104
|
+
requirement: !ruby/object:Gem::Requirement
|
105
|
+
none: false
|
106
|
+
requirements:
|
107
|
+
- - ! '>='
|
108
|
+
- !ruby/object:Gem::Version
|
109
|
+
version: '0'
|
110
|
+
- !ruby/object:Gem::Dependency
|
111
|
+
type: :development
|
112
|
+
version_requirements: !ruby/object:Gem::Requirement
|
113
|
+
none: false
|
114
|
+
requirements:
|
115
|
+
- - ! '>='
|
116
|
+
- !ruby/object:Gem::Version
|
117
|
+
version: '0'
|
118
|
+
name: bundler
|
119
|
+
prerelease: false
|
120
|
+
requirement: !ruby/object:Gem::Requirement
|
121
|
+
none: false
|
122
|
+
requirements:
|
123
|
+
- - ! '>='
|
124
|
+
- !ruby/object:Gem::Version
|
125
|
+
version: '0'
|
126
|
+
- !ruby/object:Gem::Dependency
|
127
|
+
type: :development
|
128
|
+
version_requirements: !ruby/object:Gem::Requirement
|
129
|
+
none: false
|
130
|
+
requirements:
|
131
|
+
- - ! '>='
|
132
|
+
- !ruby/object:Gem::Version
|
133
|
+
version: '0'
|
134
|
+
name: jeweler
|
135
|
+
prerelease: false
|
136
|
+
requirement: !ruby/object:Gem::Requirement
|
137
|
+
none: false
|
138
|
+
requirements:
|
139
|
+
- - ! '>='
|
140
|
+
- !ruby/object:Gem::Version
|
141
|
+
version: '0'
|
142
|
+
- !ruby/object:Gem::Dependency
|
143
|
+
type: :development
|
144
|
+
version_requirements: !ruby/object:Gem::Requirement
|
145
|
+
none: false
|
146
|
+
requirements:
|
147
|
+
- - ! '>='
|
148
|
+
- !ruby/object:Gem::Version
|
149
|
+
version: '0'
|
150
|
+
name: simplecov
|
151
|
+
prerelease: false
|
152
|
+
requirement: !ruby/object:Gem::Requirement
|
153
|
+
none: false
|
154
|
+
requirements:
|
155
|
+
- - ! '>='
|
156
|
+
- !ruby/object:Gem::Version
|
157
|
+
version: '0'
|
158
|
+
- !ruby/object:Gem::Dependency
|
159
|
+
type: :development
|
160
|
+
version_requirements: !ruby/object:Gem::Requirement
|
161
|
+
none: false
|
162
|
+
requirements:
|
163
|
+
- - ! '>='
|
164
|
+
- !ruby/object:Gem::Version
|
165
|
+
version: '0'
|
166
|
+
name: simplecov-csv
|
167
|
+
prerelease: false
|
168
|
+
requirement: !ruby/object:Gem::Requirement
|
169
|
+
none: false
|
170
|
+
requirements:
|
171
|
+
- - ! '>='
|
172
|
+
- !ruby/object:Gem::Version
|
173
|
+
version: '0'
|
174
|
+
- !ruby/object:Gem::Dependency
|
175
|
+
type: :development
|
176
|
+
version_requirements: !ruby/object:Gem::Requirement
|
177
|
+
none: false
|
178
|
+
requirements:
|
179
|
+
- - ! '>='
|
180
|
+
- !ruby/object:Gem::Version
|
181
|
+
version: '0'
|
182
|
+
name: guard-rspec
|
183
|
+
prerelease: false
|
184
|
+
requirement: !ruby/object:Gem::Requirement
|
185
|
+
none: false
|
186
|
+
requirements:
|
187
|
+
- - ! '>='
|
188
|
+
- !ruby/object:Gem::Version
|
189
|
+
version: '0'
|
190
|
+
description: Checks syntax of .scad files and generates .stl files.
|
191
|
+
email: me@cpb.ca
|
192
|
+
executables: []
|
193
|
+
extensions: []
|
194
|
+
extra_rdoc_files:
|
195
|
+
- LICENSE.txt
|
196
|
+
- README.rdoc
|
197
|
+
files:
|
198
|
+
- .document
|
199
|
+
- .rspec
|
200
|
+
- .simplecov
|
201
|
+
- Gemfile
|
202
|
+
- Guardfile
|
203
|
+
- LICENSE.txt
|
204
|
+
- README.rdoc
|
205
|
+
- Rakefile
|
206
|
+
- VERSION
|
207
|
+
- guard-openscad.gemspec
|
208
|
+
- lib/guard/openscad.rb
|
209
|
+
- lib/guard/openscad/templates/Guardfile
|
210
|
+
- spec/fixtures/scad/cube.scad
|
211
|
+
- spec/guard/openscad_spec.rb
|
212
|
+
- spec/integration/guard/openscad_spec.rb
|
213
|
+
- spec/spec_helper.rb
|
214
|
+
- spec/support/core_ext/hash/except.rb
|
215
|
+
- spec/support/matchers/run_files_matcher.rb
|
216
|
+
homepage: http://github.com/cpb/guard-openscad
|
217
|
+
licenses:
|
218
|
+
- MIT
|
219
|
+
post_install_message:
|
220
|
+
rdoc_options: []
|
221
|
+
require_paths:
|
222
|
+
- lib
|
223
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
224
|
+
none: false
|
225
|
+
requirements:
|
226
|
+
- - ! '>='
|
227
|
+
- !ruby/object:Gem::Version
|
228
|
+
segments:
|
229
|
+
- 0
|
230
|
+
hash: -185614055011576550
|
231
|
+
version: '0'
|
232
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
233
|
+
none: false
|
234
|
+
requirements:
|
235
|
+
- - ! '>='
|
236
|
+
- !ruby/object:Gem::Version
|
237
|
+
version: '0'
|
238
|
+
requirements: []
|
239
|
+
rubyforge_project:
|
240
|
+
rubygems_version: 1.8.23
|
241
|
+
signing_key:
|
242
|
+
specification_version: 3
|
243
|
+
summary: Guard plugin for OpenSCAD
|
244
|
+
test_files: []
|