rspec-approvals 0.0.4 → 0.0.5

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore CHANGED
@@ -2,3 +2,5 @@
2
2
  .bundle
3
3
  Gemfile.lock
4
4
  pkg/*
5
+ *.received.txt
6
+ .approvals
data/README.md CHANGED
@@ -31,7 +31,7 @@ You can change this using the configuration option
31
31
 
32
32
  The basic format of the approval is modeled after RSpec's `it`:
33
33
 
34
- approve "something" do
34
+ verify "something" do
35
35
  "this is the received contents"
36
36
  end
37
37
 
@@ -56,14 +56,18 @@ The contents of the two files are compared, and the approval will fail at this p
56
56
  ### Formatting
57
57
 
58
58
  You can pass options to format output before it gets written to the file.
59
- At the moment, only xml and html are supported.
59
+ At the moment, only xml, html, and json are supported.
60
60
 
61
- Simply add a `:format => :xml` or `:format => :html` option to the example:
61
+ Simply add a `:format => :xml`, `:format => :html`, or `:format => :json` option to the example:
62
62
 
63
- approve "some html", :format => :html do
63
+ verify "some html", :format => :html do
64
64
  "<html><head></head><body><h1>ZOMG</h1></body></html>"
65
65
  end
66
66
 
67
+ verify "some json", :format => :json do
68
+ {"beverage" => "coffee"}.to_json
69
+ end
70
+
67
71
 
68
72
  ### Approving a spec
69
73
 
@@ -76,22 +80,23 @@ For an example who's full description is `My Spec`:
76
80
 
77
81
  When you rerun the spec, it should now pass.
78
82
 
79
- ### Formatters
80
-
81
- You can specify a custom formatter when you run the specs.
83
+ ### Expensive computations
82
84
 
83
- E.g.
85
+ The Executable class allows you to perform expensive operations only when the command to execute it changes.
84
86
 
85
- rspec --require /path/to/lib/rspec/approvals/formatters/opendiff_formatter.rb \
86
- -f RSpec::Approvals::Formatters::OpendiffFormatter spec/
87
+ For example, if you have a SQL query that is very slow, you can create an executable with the actual SQL to be performed.
87
88
 
88
- The OpendiffFormatter automatically launches opendiff for each failed
89
- approval. It falls back on the ProgressFormatter for all non-approval
90
- specs.
91
-
92
- That's pretty unweildy, so I'm looking at options to add shortcuts for
93
- this.
89
+ The first time the spec runs, it will fail, allowing you to inspect the results.
90
+ If this output looks right, approve the query. The next time the spec is run, it will compare only the actual SQL.
94
91
 
92
+ If someone changes the query, then the comparison will fail. Both the previously approved command and the received command will be executed so that you can inspect the difference between the results of the two.
95
93
 
94
+ verify "an executable" do
95
+ sql = subject.expensive_sql # the actual sql as a string
96
+ RSpec::Approvals::Executable.new(sql) do |command|
97
+ result = ActiveRecord::Base.connection.execute(command)
98
+ # do something to display the result
99
+ end
100
+ end
96
101
 
97
102
  Copyright (c) 2011 Katrina Owen, released under the MIT license
@@ -0,0 +1,10 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'thor'
5
+ require 'rspec'
6
+ require 'rspec-approvals'
7
+ require 'rspec/approvals/cli'
8
+
9
+ RSpec::Approvals::CLI.start
10
+
@@ -3,13 +3,15 @@ require 'xml'
3
3
  require "rspec/approvals/version"
4
4
  require "rspec/approvals/approval"
5
5
  require "rspec/approvals/dsl"
6
- require 'rspec/approvals/formatters/opendiff_formatter'
7
-
6
+ require 'rspec/approvals/dotfile'
7
+ require 'rspec/approvals/formatter'
8
+ require 'rspec/approvals/executable'
8
9
 
9
10
  module RSpec
10
11
  RSpec.configure do |c|
11
12
  c.extend RSpec::Approvals::DSL
12
13
  c.add_setting :approvals_path, :default => 'spec/approvals'
14
+ c.before(:suite) { RSpec::Approvals.reset }
13
15
  end
14
16
 
15
17
  module Approvals
@@ -22,6 +24,11 @@ module RSpec
22
24
  def path
23
25
  RSpec.configuration.approvals_path + "/"
24
26
  end
27
+
28
+ def reset
29
+ Dotfile.reset
30
+ end
31
+
25
32
  end
26
33
 
27
34
  end
@@ -1,41 +1,37 @@
1
1
  require 'rspec/expectations/errors'
2
+ require 'rspec/approvals/empty_approval'
2
3
 
3
4
  module RSpec
4
5
  module Approvals
5
6
 
6
7
  class ReceivedDiffersError < RSpec::Expectations::ExpectationNotMetError; end
7
8
 
8
- class EmptyApproval
9
- def inspect
10
- ""
11
- end
12
- def strip; end
13
- end
14
-
15
9
  class Approval
16
10
 
17
- def self.normalize(s)
18
- s.gsub(/[\W]/, ' ').strip.squeeze(" ").gsub(' ', '_').downcase
19
- end
20
-
21
- def self.base_path(s)
22
- Approvals.path + normalize(s)
11
+ class << self
12
+ def normalize(s)
13
+ s.gsub(/[\W]/, ' ').strip.squeeze(" ").gsub(' ', '_').downcase
14
+ end
23
15
  end
24
16
 
25
- attr_reader :location
17
+ attr_reader :location, :name, :options, :path, :received
26
18
 
27
19
  def initialize(example, received = '', options = {})
28
- @path = Approval.base_path(example.full_description)
20
+ @name = Approval.normalize(example.full_description)
21
+ @path = Approvals.path + name
29
22
  @options = options
23
+ @received = received
24
+ @formatter = Formatter.new(self)
30
25
 
31
26
  example.options[:approval] = true
32
27
  example.options[:approval_diff_paths] = {
33
28
  :received => received_path,
34
29
  :approved => approved_path,
35
30
  }
31
+ end
36
32
 
37
- write(:approved, EmptyApproval.new) unless File.exists?(approved_path)
38
- write(:received, received)
33
+ def location=(backtrace)
34
+ @location = [backtrace.first.gsub(Dir.pwd, '.').gsub(/:in\ .*$/, '')]
39
35
  end
40
36
 
41
37
  def approved_path
@@ -46,82 +42,53 @@ module RSpec
46
42
  "#{@path}.received.txt"
47
43
  end
48
44
 
49
- def write(suffix, contents)
50
- File.open("#{@path}.#{suffix}.txt", 'w') do |f|
51
- if xml?
52
- parser = XML::Parser.string contents.strip
53
- doc = parser.parse
54
- f.write doc.to_s
55
- elsif contents.respond_to?(:each_pair)
56
- contents.each_pair do |k,v|
57
- f.write "#{k.inspect} => #{v.inspect}\n"
58
- end
59
- elsif contents.respond_to?(:each_with_index)
60
- contents.each_with_index do |v,i|
61
- f.write "[#{i.inspect}] #{v.inspect}\n"
62
- end
63
- else
64
- f.write contents.inspect
45
+ def diff_path
46
+ "#{received_path} #{approved_path}"
47
+ end
48
+
49
+ def approved_text
50
+ if File.exists?(approved_path)
51
+ File.read(approved_path)
52
+ else
53
+ EmptyApproval.new.inspect
54
+ end
55
+ end
56
+
57
+ def received_text
58
+ @received_text ||= Formatter.new(self).as_s(received)
59
+ end
60
+
61
+ def verify
62
+ unless received_text == approved_text
63
+ write(received_path, received_text)
64
+ Dotfile.append(diff_path)
65
+ if received.respond_to?(:on_failure)
66
+ received.on_failure.call(approved_text)
67
+ received.on_failure.call(received_text)
65
68
  end
69
+ raise RSpec::Approvals::ReceivedDiffersError, failure_message, location
66
70
  end
67
71
  end
68
72
 
69
- def failure_message
70
- return failure_message_exposing_received if show_received?
71
- return default_failure_message
73
+ def write(path, contents)
74
+ File.open(path, 'w') do |f|
75
+ f.write contents
76
+ end
72
77
  end
73
78
 
74
- def default_failure_message
79
+ def failure_message
75
80
  <<-FAILURE_MESSAGE
76
81
 
77
82
  Approval Failure:
78
-
79
- The received contents did not match the approved contents.
83
+ The received contents did not match the approved contents.
80
84
 
81
85
  Inspect the differences in the following files:
82
86
  #{received_path}
83
87
  #{approved_path}
84
88
 
85
- If you like what you see in the *.received.txt file, you can approve it
86
- by renaming it with the .approved.txt suffix.
87
-
88
- mv #{received_path} #{approved_path}
89
-
90
-
91
89
  FAILURE_MESSAGE
92
90
  end
93
91
 
94
- def failure_message_exposing_received
95
- default_failure_message << " received:\n " << received << "\n\n\n"
96
- end
97
-
98
- def location=(backtrace)
99
- @location = [backtrace.first.gsub(Dir.pwd, '.')]
100
- end
101
-
102
- def verify
103
- if FileUtils.cmp(received_path, approved_path)
104
- File.unlink(received_path)
105
- else
106
- raise RSpec::Approvals::ReceivedDiffersError, failure_message, location
107
- end
108
- end
109
-
110
- def approved
111
- File.read(approved_path)
112
- end
113
-
114
- def received
115
- File.read(received_path)
116
- end
117
-
118
- def xml?
119
- [:xml, :html].include? @options[:format]
120
- end
121
-
122
- def show_received?
123
- @options[:show_received]
124
- end
125
92
  end
126
93
  end
127
94
  end
@@ -0,0 +1,30 @@
1
+ module RSpec
2
+ module Approvals
3
+ class CLI < Thor
4
+
5
+ desc "verify", "Go through all failing approvals with a diff tool"
6
+ method_option :diff, :type => :string, :default => 'vimdiff', :aliases => '-d', :desc => 'The difftool to use'
7
+ method_option :ask, :type => :boolean, :default => false, :aliases => "-a", :desc => 'Offer to approve the received file for you.'
8
+ def verify
9
+
10
+ approvals = File.read('.approvals').split("\n")
11
+
12
+ rejected = []
13
+ approvals.each do |approval|
14
+ system("#{options[:diff]} #{approval}")
15
+
16
+ if options[:ask] && yes?("Approve?")
17
+ system("mv #{approval}")
18
+ else
19
+ rejected << approval
20
+ end
21
+ end
22
+
23
+ File.open('.approvals', 'w') do |f|
24
+ f.write rejected.join("\n")
25
+ end
26
+ end
27
+
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,40 @@
1
+ module RSpec
2
+ module Approvals
3
+
4
+ class Dotfile
5
+ class << self
6
+
7
+ def reset
8
+ File.delete(path) if File.exists?(path)
9
+ touch
10
+ end
11
+
12
+ def path
13
+ '.approvals'
14
+ end
15
+
16
+ def touch
17
+ FileUtils.touch(path)
18
+ end
19
+
20
+ def append(text)
21
+ unless includes?(text)
22
+ write text
23
+ end
24
+ end
25
+
26
+ def includes?(text)
27
+ system("cat #{path} | grep -q \"^#{text}$\"")
28
+ end
29
+
30
+ def write(text)
31
+ File.open(path, 'a+') do |f|
32
+ f.write "#{text}\n"
33
+ end
34
+ end
35
+
36
+ end
37
+ end
38
+
39
+ end
40
+ end
@@ -4,15 +4,16 @@ module RSpec
4
4
  module Approvals
5
5
  module DSL
6
6
 
7
- def approve(description, options = {})
7
+ def verify(description, options = {})
8
8
 
9
+ origin = caller
9
10
  specify(description) do
10
11
  approval = Approval.new(example, yield, options)
11
12
 
12
13
  # We may be able to set file_path and
13
14
  # line_number on example in the approval
14
15
  # see RSpec::Core::Metadata::LocationKeys
15
- approval.location = caller
16
+ approval.location = origin
16
17
 
17
18
  approval.verify
18
19
  end
@@ -0,0 +1,12 @@
1
+ module RSpec
2
+ module Approvals
3
+
4
+ class EmptyApproval
5
+ def inspect
6
+ ""
7
+ end
8
+ def strip; end
9
+ end
10
+
11
+ end
12
+ end
@@ -0,0 +1,16 @@
1
+ module RSpec
2
+ module Approvals
3
+ class Executable
4
+
5
+ attr_accessor :command, :on_failure
6
+ def initialize(command, &block)
7
+ self.command = command
8
+ self.on_failure = block
9
+ end
10
+
11
+ def to_s
12
+ command
13
+ end
14
+ end
15
+ end
16
+ end
@@ -0,0 +1,58 @@
1
+ module RSpec
2
+ module Approvals
3
+ class Formatter
4
+ attr_accessor :approval
5
+ def initialize(approval)
6
+ self.approval = approval
7
+ end
8
+
9
+ def as_s(contents)
10
+ if xml?
11
+ as_xml(contents)
12
+ elsif json?
13
+ as_json(contents)
14
+ elsif contents.respond_to?(:each_pair)
15
+ as_hash(contents)
16
+ elsif contents.respond_to?(:each_with_index)
17
+ as_array(contents)
18
+ else
19
+ contents.inspect
20
+ end
21
+ end
22
+
23
+ def xml?
24
+ [:xml, :html].include? approval.options[:format]
25
+ end
26
+
27
+ def json?
28
+ approval.options[:format] == :json
29
+ end
30
+
31
+ def as_json(contents)
32
+ JSON.pretty_generate(JSON.parse(contents))
33
+ end
34
+
35
+ def as_xml(contents)
36
+ parser = XML::Parser.string contents.strip
37
+ parser.parse.to_s
38
+ end
39
+
40
+ def as_hash(contents)
41
+ s = ""
42
+ contents.each_pair do |k,v|
43
+ s << "#{k.inspect} => #{v.inspect}\n"
44
+ end
45
+ s
46
+ end
47
+
48
+ def as_array(contents)
49
+ s = ""
50
+ contents.each_with_index do |v,i|
51
+ s << "[#{i.inspect}] #{v.inspect}\n"
52
+ end
53
+ s
54
+ end
55
+ end
56
+
57
+ end
58
+ end
@@ -1,5 +1,5 @@
1
1
  module RSpec
2
2
  module Approvals
3
- VERSION = "0.0.4"
3
+ VERSION = "0.0.5"
4
4
  end
5
5
  end
@@ -18,6 +18,7 @@ Gem::Specification.new do |s|
18
18
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
19
  s.require_paths = ["lib"]
20
20
 
21
- s.add_dependency 'rspec', '~> 2.6'
21
+ s.add_dependency 'rspec', '~> 2.7'
22
+ s.add_dependency 'thor'
22
23
  s.add_dependency 'libxml-ruby'
23
24
  end
@@ -1,28 +1,27 @@
1
- require 'spec_helper'
1
+ require 'rspec/approvals'
2
2
 
3
- describe Approvals::Approval do
4
- let(:description) { 'spec/approvals/fairy_dust_and_unicorns' }
5
- let(:example) { stub('example', :full_description => 'fairy dust and unicorns').as_null_object }
3
+ describe RSpec::Approvals::Approval do
4
+ include RSpec::Approvals
6
5
 
7
6
  describe "#normalize" do
8
7
  it "downcases" do
9
- Approvals::Approval.normalize("KTHXBYE").should eq("kthxbye")
8
+ Approval.normalize("KTHXBYE").should eq("kthxbye")
10
9
  end
11
10
 
12
11
  it "replaces spaces with underscores" do
13
- Approvals::Approval.normalize("the spec").should eq("the_spec")
12
+ Approval.normalize("the spec").should eq("the_spec")
14
13
  end
15
14
 
16
15
  it "leaves numbers alone" do
17
- Approvals::Approval.normalize('a 2009 party').should eq("a_2009_party")
16
+ Approval.normalize('a 2009 party').should eq("a_2009_party")
18
17
  end
19
18
 
20
19
  it "deletes funky characters" do
21
- Approvals::Approval.normalize('the !@\#$%^&*(){}+| name').should eq("the_name")
20
+ Approval.normalize('the !@\#$%^&*(){}+| name').should eq("the_name")
22
21
  end
23
22
 
24
23
  it "collapses spaces before replacing with underscores" do
25
- Approvals::Approval.normalize('omf g').should eq('omf_g')
24
+ Approval.normalize('omf g').should eq('omf_g')
26
25
  end
27
26
 
28
27
  it "deletes all sorts of spaces" do
@@ -30,152 +29,88 @@ describe Approvals::Approval do
30
29
 
31
30
  The::Class \t \r\n \fname
32
31
  FUNKY_NAME
33
- Approvals::Approval.normalize(name).should eq('the_class_name')
32
+ Approval.normalize(name).should eq('the_class_name')
34
33
  end
35
34
  end
36
35
 
37
- it "knows the approved_path" do
38
- approval = Approvals::Approval.new(example)
39
- approval.approved_path.should eq("#{description}.approved.txt")
40
- end
41
-
42
- it "knows the received path" do
43
- approval = Approvals::Approval.new(example)
44
- approval.received_path.should eq("#{description}.received.txt")
45
- end
36
+ let(:example) { stub('example', :full_description => 'fairy dust and unicorns').as_null_object }
46
37
 
47
- it "can set a location" do
48
- Dir.stub(:pwd => 'the/path')
49
- approval = Approvals::Approval.new(example)
50
- approval.location = ['the/path/to/my/heart:9372 <is through my stomach>', 'bla bla bla']
51
- approval.location.should eq(['./to/my/heart:9372 <is through my stomach>'])
52
- end
38
+ describe "an approval" do
39
+ let(:path) { 'spec/approvals/fairy_dust_and_unicorns' }
40
+ subject { Approval.new(example) }
53
41
 
54
- context "approvals" do
55
- before :each do
56
- @approved_file = "#{description}.approved.txt"
57
- @received_file = "#{description}.received.txt"
58
- end
42
+ its(:approved_path) { should eq("#{path}.approved.txt") }
43
+ its(:received_path) { should eq("#{path}.received.txt") }
59
44
 
60
- after :each do
61
- File.delete(@approved_file) if File.exists?(@approved_file)
62
- File.delete(@received_file) if File.exists?(@received_file)
45
+ it "can set a location" do
46
+ Dir.stub(:pwd => 'the/path')
47
+ subject.location = ['the/path/to/my/heart:9372:in <is through my stomach>', 'bla bla bla']
48
+ subject.location.should eq(['./to/my/heart:9372'])
63
49
  end
50
+ end
64
51
 
65
- describe "on the filesystem" do
66
-
67
- it "writes the approved file if it doesn't exist" do
68
- File.delete(@approved_file) if File.exists?(@approved_file)
69
-
70
- Approvals::Approval.new(example)
52
+ describe "verification" do
53
+ let(:approval) { Approval.new(example, 'xyz') }
71
54
 
72
- File.exists?(@approved_file).should be_true
73
- File.read(@approved_file).should eq('')
55
+ context "with a match" do
56
+ before :each do
57
+ approval.stub(:approved_text => 'xyz', :received_text => 'xyz')
74
58
  end
75
59
 
76
- it "doesn't overwrite an existing approved file" do
77
- File.open(@approved_file, 'w') do |f|
78
- f.write "this doesn't get deleted"
79
- end
80
-
81
- Approvals::Approval.new(example)
82
-
83
- File.exists?(@approved_file).should be_true
84
- File.read(@approved_file).should eq("this doesn't get deleted")
60
+ it "does not raise an error" do
61
+ lambda { approval.verify }.should_not raise_error(RSpec::Approvals::ReceivedDiffersError)
85
62
  end
86
63
 
87
- it "writes the received contents to file" do
88
- approval = Approvals::Approval.new(example, 'oooh, shiney!')
89
-
90
- File.exists?(@received_file).should be_true
91
- File.read(@received_file).should eq('"oooh, shiney!"')
64
+ it "does not leave a received file" do
65
+ lambda { approval.verify }.call
66
+ File.exists?(approval.received_path).should be_false
92
67
  end
93
68
  end
94
69
 
95
- describe "verification" do
96
-
97
- context "with a match" do
98
- before :each do
99
- @approval = Approvals::Approval.new(example, 'xyz')
100
- @approval.write(:approved, 'xyz')
101
- end
70
+ context "with a mismatch" do
71
+ before :each do
72
+ approval.stub(:approved_text => 'xyz', :received_text => 'abc')
73
+ end
102
74
 
103
- it "does not raise an error" do
104
- lambda { @approval.verify }.should_not raise_error(RSpec::Approvals::ReceivedDiffersError)
105
- end
75
+ after :each do
76
+ File.delete(approval.received_path) if File.exists?(approval.received_path)
77
+ end
106
78
 
107
- it "does not leave a received file" do
108
- lambda { @approval.verify }.call
109
- File.exists?(@approval.received_path).should be_false
110
- end
79
+ it "raises an error" do
80
+ lambda { approval.verify }.should raise_error(RSpec::Approvals::ReceivedDiffersError)
111
81
  end
112
82
 
113
- context "with a mismatch" do
114
- before :each do
115
- @approval = Approvals::Approval.new(example, 'xyz')
116
- @approval.write(:approved, 'abc')
83
+ it "leaves a received file" do
84
+ begin
85
+ approval.verify
86
+ rescue RSpec::Approvals::ReceivedDiffersError => e
87
+ # we want to land here and then move on
117
88
  end
89
+ File.exists?(approval.received_path).should be_true
90
+ end
118
91
 
119
- it "raises an error" do
120
- lambda { @approval.verify }.should raise_error(RSpec::Approvals::ReceivedDiffersError)
121
- end
92
+ it "appends to the dotfile" do
93
+ approval.stub(:diff_path => 'the diff path')
94
+ Dotfile.should_receive(:append).with "the diff path"
122
95
 
123
- it "leaves a received file" do
124
- begin
125
- @approval.verify
126
- rescue RSpec::Approvals::ReceivedDiffersError => e
127
- # we want to land here and then move on
128
- end
129
- File.exists?(@approval.received_path).should be_true
96
+ begin
97
+ approval.verify
98
+ rescue RSpec::Approvals::ReceivedDiffersError => e
99
+ # moving on
130
100
  end
131
101
  end
132
102
  end
133
103
 
134
104
  it "fails magnificently" do
135
- approval = Approvals::Approval.new(example, 'xyz')
136
105
  message = <<-FAILURE_MESSAGE
137
106
 
138
107
  Approval Failure:
139
-
140
- The received contents did not match the approved contents.
108
+ The received contents did not match the approved contents.
141
109
 
142
110
  Inspect the differences in the following files:
143
111
  #{approval.received_path}
144
112
  #{approval.approved_path}
145
113
 
146
- If you like what you see in the *.received.txt file, you can approve it
147
- by renaming it with the .approved.txt suffix.
148
-
149
- mv #{approval.received_path} #{approval.approved_path}
150
-
151
-
152
- FAILURE_MESSAGE
153
-
154
- approval.failure_message.should eq(message)
155
- end
156
-
157
- it "fails with exposed 'received'" do
158
- approval = Approvals::Approval.new(example, 'aoeu', :show_received => true)
159
- message = <<-FAILURE_MESSAGE
160
-
161
- Approval Failure:
162
-
163
- The received contents did not match the approved contents.
164
-
165
- Inspect the differences in the following files:
166
- #{approval.received_path}
167
- #{approval.approved_path}
168
-
169
- If you like what you see in the *.received.txt file, you can approve it
170
- by renaming it with the .approved.txt suffix.
171
-
172
- mv #{approval.received_path} #{approval.approved_path}
173
-
174
-
175
- received:
176
- #{approval.received}
177
-
178
-
179
114
  FAILURE_MESSAGE
180
115
 
181
116
  approval.failure_message.should eq(message)
@@ -1,6 +1,8 @@
1
- require 'spec_helper'
1
+ require 'rspec/approvals'
2
+ require 'json'
2
3
 
3
- describe Approvals do
4
+ describe RSpec::Approvals do
5
+ include RSpec
4
6
 
5
7
  it "defaults the output dir to spec/approvals" do
6
8
  RSpec.configuration.approvals_path.should == 'spec/approvals'
@@ -24,13 +26,11 @@ describe Approvals do
24
26
  end
25
27
  end
26
28
 
27
- it "needs to be able to run with :filtered => true"
28
-
29
- approve "a string" do
29
+ verify "a string" do
30
30
  "We have, I fear, confused power with greatness."
31
31
  end
32
32
 
33
- approve "a hash" do
33
+ verify "a hash" do
34
34
  {
35
35
  :universe => {
36
36
  :side => :dark,
@@ -41,7 +41,7 @@ describe Approvals do
41
41
  }
42
42
  end
43
43
 
44
- approve "an array" do
44
+ verify "an array" do
45
45
  [
46
46
  "abc",
47
47
  123,
@@ -50,7 +50,7 @@ describe Approvals do
50
50
  ]
51
51
  end
52
52
 
53
- approve "a complex object" do
53
+ verify "a complex object with implicit #inspect" do
54
54
  hello = Object.new
55
55
  def hello.to_s
56
56
  "Hello, World!"
@@ -60,17 +60,27 @@ describe Approvals do
60
60
  "#<The World Says: Hello!>"
61
61
  end
62
62
 
63
- hello # => output matches hello.inspect
63
+ hello
64
64
  end
65
65
 
66
- approve "formats html nicely", :format => :html, :show_received => true do
66
+ verify "formats html nicely", :format => :html do
67
67
  <<-XML
68
68
  <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "DTD/xhtml1-strict.dtd"><html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en"><head><meta content="text/html; charset=utf-8" http-equiv="Content-Type"/><title>blog</title><script type="text/javascript" src="/blog/static/jquery-1.1.3.pack.js"></script><script type="text/javascript" src="/blog/static/blog.js"></script><link type="text/css" rel="stylesheet" href="/blog/styles.css" media="screen"/></head><body><h1 class="header"><a href="/blog/">blog</a></h1><div class="content"><h1 class="post_head"><a href="/blog/view/2">Hej</a><a class="edit_link" href="/blog/edit/2">edit</a></h1><p>ASDJlksdjfsld
69
69
  </p><h2 class="comment_head"><a href="javascript:getComments(2)">See comments (2)</a></h2><div id="comments"><h3>tyysen</h3><p>miljoooner</p><h3>hej</h3><p>bulan</p></div><h2 class="add_comment_head"><a href="#comment_form">Add comment</a></h2><form method="post" name="comment_form" id="comment_form" action="/blog/comment"><label for="post_username">Name</label><br/><input type="text" name="post_username"/><br/><label for="post_body">Comment</label><br/><textarea name="post_body"></textarea><br/><input type="hidden" name="post_id" value="2"/><input type="submit" value="Add comment"/></form></div></body></html>
70
70
  XML
71
71
  end
72
72
 
73
- approve "formats xml nicely", :format => :xml, :show_received => true do
73
+ verify "formats xml nicely", :format => :xml, do
74
74
  "<xml testsdf=\"dsfsdf\"><test/><node><content attr='fgsd' /></node><node id='2'><content /></node></xml>"
75
75
  end
76
+
77
+ verify "formats json nicely", :format => :json do
78
+ {"hello" => "world"}.to_json
79
+ end
80
+
81
+ verify "an executable" do
82
+ executable = RSpec::Approvals::Executable.new('SELECT 1') do |command|
83
+ puts "your slip is showing (#{command})"
84
+ end
85
+ end
76
86
  end
@@ -0,0 +1,22 @@
1
+ require 'rspec/approvals/dotfile'
2
+
3
+ describe RSpec::Approvals::Dotfile do
4
+ include RSpec::Approvals
5
+ let(:dotfile) { '/tmp/.approvals' }
6
+
7
+ before(:each) do
8
+ Dotfile.stub(:path => dotfile)
9
+ Dotfile.reset
10
+ end
11
+
12
+ it "appends the text" do
13
+ Dotfile.append('text')
14
+ File.readlines(dotfile).map(&:chomp).should eq(['text'])
15
+ end
16
+
17
+ it "appends the text exactly once" do
18
+ Dotfile.append('text')
19
+ Dotfile.append('text')
20
+ File.readlines(dotfile).map(&:chomp).should eq(['text'])
21
+ end
22
+ end
@@ -0,0 +1,15 @@
1
+ require 'rspec/approvals/executable'
2
+
3
+ describe RSpec::Approvals::Executable do
4
+ include RSpec::Approvals
5
+
6
+ subject { Executable.new('SELECT 1') }
7
+ its(:inspect) { should eq('SELECT 1') }
8
+
9
+ it "takes a block" do
10
+ executable = Executable.new('SELECT 1') do |command|
11
+ "execute query: #{command}"
12
+ end
13
+ executable.on_failure.call('SELECT 1').should eq('execute query: SELECT 1')
14
+ end
15
+ end
metadata CHANGED
@@ -1,111 +1,110 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: rspec-approvals
3
- version: !ruby/object:Gem::Version
4
- prerelease: false
5
- segments:
6
- - 0
7
- - 0
8
- - 4
9
- version: 0.0.4
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.5
5
+ prerelease:
10
6
  platform: ruby
11
- authors:
7
+ authors:
12
8
  - Katrina Owen
13
9
  autorequire:
14
10
  bindir: bin
15
11
  cert_chain: []
16
-
17
- date: 2011-07-29 00:00:00 +02:00
18
- default_executable:
19
- dependencies:
20
- - !ruby/object:Gem::Dependency
12
+ date: 2012-02-12 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
21
15
  name: rspec
22
- prerelease: false
23
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &70165236704760 !ruby/object:Gem::Requirement
24
17
  none: false
25
- requirements:
18
+ requirements:
26
19
  - - ~>
27
- - !ruby/object:Gem::Version
28
- segments:
29
- - 2
30
- - 6
31
- version: "2.6"
20
+ - !ruby/object:Gem::Version
21
+ version: '2.7'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *70165236704760
25
+ - !ruby/object:Gem::Dependency
26
+ name: thor
27
+ requirement: &70165236701340 !ruby/object:Gem::Requirement
28
+ none: false
29
+ requirements:
30
+ - - ! '>='
31
+ - !ruby/object:Gem::Version
32
+ version: '0'
32
33
  type: :runtime
33
- version_requirements: *id001
34
- - !ruby/object:Gem::Dependency
35
- name: libxml-ruby
36
34
  prerelease: false
37
- requirement: &id002 !ruby/object:Gem::Requirement
35
+ version_requirements: *70165236701340
36
+ - !ruby/object:Gem::Dependency
37
+ name: libxml-ruby
38
+ requirement: &70165236698420 !ruby/object:Gem::Requirement
38
39
  none: false
39
- requirements:
40
- - - ">="
41
- - !ruby/object:Gem::Version
42
- segments:
43
- - 0
44
- version: "0"
40
+ requirements:
41
+ - - ! '>='
42
+ - !ruby/object:Gem::Version
43
+ version: '0'
45
44
  type: :runtime
46
- version_requirements: *id002
47
- description: An RSpec extension that adds support for approvals. Based on the idea of the Golden Master.
48
- email:
45
+ prerelease: false
46
+ version_requirements: *70165236698420
47
+ description: An RSpec extension that adds support for approvals. Based on the idea
48
+ of the Golden Master.
49
+ email:
49
50
  - katrina.owen@gmail.com
50
- executables: []
51
-
51
+ executables:
52
+ - approvals
52
53
  extensions: []
53
-
54
54
  extra_rdoc_files: []
55
-
56
- files:
55
+ files:
57
56
  - .gitignore
58
57
  - Gemfile
59
58
  - License.txt
60
59
  - README.md
61
60
  - Rakefile
61
+ - bin/approvals
62
62
  - lib/rspec-approvals.rb
63
63
  - lib/rspec/approvals.rb
64
64
  - lib/rspec/approvals/approval.rb
65
+ - lib/rspec/approvals/cli.rb
66
+ - lib/rspec/approvals/dotfile.rb
65
67
  - lib/rspec/approvals/dsl.rb
66
- - lib/rspec/approvals/formatters/opendiff_formatter.rb
68
+ - lib/rspec/approvals/empty_approval.rb
69
+ - lib/rspec/approvals/executable.rb
70
+ - lib/rspec/approvals/formatter.rb
67
71
  - lib/rspec/approvals/version.rb
68
72
  - rspec-approvals.gemspec
69
73
  - spec/approval_spec.rb
70
- - spec/approvals/rspec_approvals_a_complex_object.approved.txt
74
+ - spec/approvals/fairy_dust_and_unicorns.approved.txt
75
+ - spec/approvals/rspec_approvals_a_complex_object_with_implicit_inspect.approved.txt
71
76
  - spec/approvals/rspec_approvals_a_hash.approved.txt
72
77
  - spec/approvals/rspec_approvals_a_string.approved.txt
73
78
  - spec/approvals/rspec_approvals_an_array.approved.txt
79
+ - spec/approvals/rspec_approvals_an_executable.approved.txt
74
80
  - spec/approvals/rspec_approvals_formats_html_nicely.approved.txt
81
+ - spec/approvals/rspec_approvals_formats_json_nicely.approved.txt
75
82
  - spec/approvals/rspec_approvals_formats_xml_nicely.approved.txt
76
83
  - spec/approvals_spec.rb
77
- - spec/spec_helper.rb
78
- has_rdoc: true
79
- homepage: ""
84
+ - spec/dotfile_spec.rb
85
+ - spec/executable_spec.rb
86
+ homepage: ''
80
87
  licenses: []
81
-
82
88
  post_install_message:
83
89
  rdoc_options: []
84
-
85
- require_paths:
90
+ require_paths:
86
91
  - lib
87
- required_ruby_version: !ruby/object:Gem::Requirement
92
+ required_ruby_version: !ruby/object:Gem::Requirement
88
93
  none: false
89
- requirements:
90
- - - ">="
91
- - !ruby/object:Gem::Version
92
- segments:
93
- - 0
94
- version: "0"
95
- required_rubygems_version: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ! '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
96
99
  none: false
97
- requirements:
98
- - - ">="
99
- - !ruby/object:Gem::Version
100
- segments:
101
- - 0
102
- version: "0"
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
103
104
  requirements: []
104
-
105
105
  rubyforge_project: rspec-approvals
106
- rubygems_version: 1.3.7
106
+ rubygems_version: 1.8.10
107
107
  signing_key:
108
108
  specification_version: 3
109
109
  summary: Approval Tests for Ruby
110
110
  test_files: []
111
-
@@ -1,22 +0,0 @@
1
- require 'rspec/core/formatters/progress_formatter'
2
-
3
- module RSpec
4
- module Approvals
5
- module Formatters
6
-
7
- class OpendiffFormatter < RSpec::Core::Formatters::ProgressFormatter
8
- def dump_failures
9
- super
10
- failed_examples.each do |example|
11
- if example.options[:approval]
12
- paths = example.options[:approval_diff_paths]
13
- system("opendiff #{paths[:received]} #{paths[:approved]} &")
14
- end
15
- end
16
- end
17
-
18
- end
19
-
20
- end
21
- end
22
- end
@@ -1,2 +0,0 @@
1
- require 'rspec/approvals'
2
- include RSpec