br-approvals 0.0.22

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (110) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.travis.yml +15 -0
  4. data/CHANGELOG.md +71 -0
  5. data/Gemfile +6 -0
  6. data/License.txt +22 -0
  7. data/README.md +263 -0
  8. data/Rakefile +6 -0
  9. data/approvals.gemspec +29 -0
  10. data/bin/approvals +8 -0
  11. data/ext/mkrf_conf.rb +22 -0
  12. data/lib/approvals.rb +33 -0
  13. data/lib/approvals/approval.rb +144 -0
  14. data/lib/approvals/cli.rb +36 -0
  15. data/lib/approvals/configuration.rb +29 -0
  16. data/lib/approvals/dotfile.rb +33 -0
  17. data/lib/approvals/dsl.rb +7 -0
  18. data/lib/approvals/error.rb +21 -0
  19. data/lib/approvals/executable.rb +18 -0
  20. data/lib/approvals/extensions/rspec.rb +13 -0
  21. data/lib/approvals/extensions/rspec/dsl.rb +44 -0
  22. data/lib/approvals/filter.rb +45 -0
  23. data/lib/approvals/namers/default_namer.rb +20 -0
  24. data/lib/approvals/namers/directory_namer.rb +30 -0
  25. data/lib/approvals/namers/rspec_namer.rb +32 -0
  26. data/lib/approvals/reporters.rb +14 -0
  27. data/lib/approvals/reporters/diff_reporter/diffmerge_reporter.rb +18 -0
  28. data/lib/approvals/reporters/diff_reporter/opendiff_reporter.rb +18 -0
  29. data/lib/approvals/reporters/diff_reporter/tortoisediff_reporter.rb +18 -0
  30. data/lib/approvals/reporters/diff_reporter/vimdiff_reporter.rb +18 -0
  31. data/lib/approvals/reporters/filelauncher_reporter.rb +18 -0
  32. data/lib/approvals/reporters/first_working_reporter.rb +21 -0
  33. data/lib/approvals/reporters/image_reporter.rb +13 -0
  34. data/lib/approvals/reporters/image_reporter/html_image_reporter.rb +35 -0
  35. data/lib/approvals/reporters/image_reporter/image_magick_reporter.rb +20 -0
  36. data/lib/approvals/reporters/launcher.rb +49 -0
  37. data/lib/approvals/reporters/reporter.rb +30 -0
  38. data/lib/approvals/rspec.rb +4 -0
  39. data/lib/approvals/scrubber.rb +43 -0
  40. data/lib/approvals/system_command.rb +13 -0
  41. data/lib/approvals/version.rb +3 -0
  42. data/lib/approvals/writer.rb +39 -0
  43. data/lib/approvals/writers/array_writer.rb +17 -0
  44. data/lib/approvals/writers/binary_writer.rb +49 -0
  45. data/lib/approvals/writers/hash_writer.rb +20 -0
  46. data/lib/approvals/writers/html_writer.rb +15 -0
  47. data/lib/approvals/writers/json_writer.rb +31 -0
  48. data/lib/approvals/writers/text_writer.rb +21 -0
  49. data/lib/approvals/writers/xml_writer.rb +15 -0
  50. data/spec/approvals_spec.rb +172 -0
  51. data/spec/configuration_spec.rb +28 -0
  52. data/spec/dotfile_spec.rb +22 -0
  53. data/spec/executable_spec.rb +17 -0
  54. data/spec/extensions/rspec_approvals_spec.rb +105 -0
  55. data/spec/filter_spec.rb +123 -0
  56. data/spec/fixtures/approvals/approvals_custom_writer_verifies_a_complex_object.approved.txt +1 -0
  57. data/spec/fixtures/approvals/approvals_passes_approved_files_through_erb.approved.txt +1 -0
  58. data/spec/fixtures/approvals/approvals_passes_the_received_files_through_erb.approved.txt +1 -0
  59. data/spec/fixtures/approvals/approvals_supports_excluded_keys_option_also_supports_an_array_of_hashes.approved.json +10 -0
  60. data/spec/fixtures/approvals/approvals_supports_excluded_keys_option_supports_the_array_writer.approved.txt +1 -0
  61. data/spec/fixtures/approvals/approvals_supports_excluded_keys_option_supports_the_hash_writer.approved.txt +1 -0
  62. data/spec/fixtures/approvals/approvals_supports_excluded_keys_option_verifies_json_with_excluded_keys.approved.json +8 -0
  63. data/spec/fixtures/approvals/approvals_verifies_a_complex_object.approved.txt +1 -0
  64. data/spec/fixtures/approvals/approvals_verifies_a_hash.approved.txt +6 -0
  65. data/spec/fixtures/approvals/approvals_verifies_a_malformed_html_fragment.approved.html +11 -0
  66. data/spec/fixtures/approvals/approvals_verifies_a_string.approved.txt +1 -0
  67. data/spec/fixtures/approvals/approvals_verifies_an_array.approved.txt +4 -0
  68. data/spec/fixtures/approvals/approvals_verifies_an_array_as_json_when_format_is_set_to_json.approved.json +10 -0
  69. data/spec/fixtures/approvals/approvals_verifies_an_executable.approved.txt +1 -0
  70. data/spec/fixtures/approvals/approvals_verifies_html.approved.html +11 -0
  71. data/spec/fixtures/approvals/approvals_verifies_json.approved.json +7 -0
  72. data/spec/fixtures/approvals/approvals_verifies_json_and_is_newline_agnostic.approved.json +7 -0
  73. data/spec/fixtures/approvals/approvals_verifies_xml.approved.xml +9 -0
  74. data/spec/fixtures/approvals/verifications_a_string.approved.txt +1 -0
  75. data/spec/fixtures/approvals/verifies_a_complex_object.approved.txt +1 -0
  76. data/spec/fixtures/approvals/verifies_a_failure.approved.txt +1 -0
  77. data/spec/fixtures/approvals/verifies_a_failure_diff.approved.txt +1 -0
  78. data/spec/fixtures/approvals/verifies_a_string.approved.txt +1 -0
  79. data/spec/fixtures/approvals/verifies_an_array.approved.txt +4 -0
  80. data/spec/fixtures/approvals/verifies_an_executable.approved.txt +1 -0
  81. data/spec/fixtures/approvals/verifies_directory/a_complex_object.approved.txt +1 -0
  82. data/spec/fixtures/approvals/verifies_directory/a_failure.approved.txt +0 -0
  83. data/spec/fixtures/approvals/verifies_directory/a_failure_diff.approved.txt +0 -0
  84. data/spec/fixtures/approvals/verifies_directory/a_string.approved.txt +1 -0
  85. data/spec/fixtures/approvals/verifies_directory/an_array.approved.txt +4 -0
  86. data/spec/fixtures/approvals/verifies_directory/an_executable.approved.txt +1 -0
  87. data/spec/fixtures/approvals/verifies_directory/html.approved.html +11 -0
  88. data/spec/fixtures/approvals/verifies_directory/json.approved.json +7 -0
  89. data/spec/fixtures/approvals/verifies_directory/xml.approved.xml +9 -0
  90. data/spec/fixtures/approvals/verifies_html.approved.html +11 -0
  91. data/spec/fixtures/approvals/verifies_json.approved.json +7 -0
  92. data/spec/fixtures/approvals/verifies_xml.approved.xml +9 -0
  93. data/spec/fixtures/one.png +0 -0
  94. data/spec/fixtures/one.txt +1 -0
  95. data/spec/fixtures/two.png +0 -0
  96. data/spec/fixtures/two.txt +1 -0
  97. data/spec/namers/default_namer_spec.rb +37 -0
  98. data/spec/namers/directory_namer_spec.rb +31 -0
  99. data/spec/namers/rspec_namer_spec.rb +30 -0
  100. data/spec/namers_spec.rb +16 -0
  101. data/spec/reporters/first_working_reporter_spec.rb +30 -0
  102. data/spec/reporters/html_image_reporter_spec.rb +22 -0
  103. data/spec/reporters/image_magick_reporter_spec.rb +16 -0
  104. data/spec/reporters/launcher_spec.rb +24 -0
  105. data/spec/reporters/opendiff_reporter_spec.rb +15 -0
  106. data/spec/reporters/reporter_spec.rb +21 -0
  107. data/spec/scrubber_spec.rb +26 -0
  108. data/spec/spec_helper.rb +7 -0
  109. data/spec/system_command_spec.rb +13 -0
  110. metadata +196 -0
@@ -0,0 +1,20 @@
1
+ module Approvals
2
+ module Namers
3
+ class DefaultNamer
4
+
5
+ attr_reader :name
6
+ def initialize(name = nil)
7
+ raise ArgumentError.new("DefaultNamer: You must specify a name") if name.nil?
8
+ @name = normalize(name)
9
+ end
10
+
11
+ def normalize(string)
12
+ string.strip.squeeze(" ").gsub(/[\ :-]+/, '_').gsub(/[\W]/, '').downcase
13
+ end
14
+
15
+ def output_dir
16
+ @output_dir ||= Approvals.configuration.approvals_path
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,30 @@
1
+ module Approvals
2
+ module Namers
3
+ class DirectoryNamer < RSpecNamer
4
+ private
5
+
6
+ def name_for_example(example)
7
+ directorize example
8
+ end
9
+
10
+ def directorize(example)
11
+ approvals_path = lambda do |metadata|
12
+ description = normalize metadata[:description]
13
+ example_group = if metadata.key?(:example_group)
14
+ metadata[:example_group]
15
+ else
16
+ metadata[:parent_example_group]
17
+ end
18
+
19
+ if example_group
20
+ [approvals_path[example_group], description].join('/')
21
+ else
22
+ description
23
+ end
24
+ end
25
+
26
+ approvals_path[example.metadata]
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,32 @@
1
+ module Approvals
2
+ module Namers
3
+ class RSpecNamer
4
+ attr_reader :name
5
+
6
+ def initialize(example)
7
+ @name = name_for_example(example)
8
+ @output_dir = nil
9
+ end
10
+
11
+ def name_for_example(example)
12
+ normalize example.full_description
13
+ end
14
+
15
+ def normalize(string)
16
+ string.strip.squeeze(" ").gsub(/[\ :-]+/, '_').gsub(/[\W]/, '').downcase
17
+ end
18
+
19
+ def output_dir
20
+ unless @output_dir
21
+ begin
22
+ @output_dir = ::RSpec.configuration.approvals_path
23
+ rescue NoMethodError
24
+ end
25
+ @output_dir ||= 'spec/fixtures/approvals/'
26
+ end
27
+ @output_dir
28
+ end
29
+
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,14 @@
1
+ require 'singleton'
2
+ require 'approvals/reporters/first_working_reporter'
3
+
4
+ require 'approvals/reporters/image_reporter'
5
+ require 'approvals/reporters/image_reporter/image_magick_reporter'
6
+ require 'approvals/reporters/image_reporter/html_image_reporter'
7
+
8
+ require 'approvals/reporters/launcher'
9
+ require 'approvals/reporters/reporter'
10
+ require 'approvals/reporters/diff_reporter/opendiff_reporter'
11
+ require 'approvals/reporters/diff_reporter/vimdiff_reporter'
12
+ require 'approvals/reporters/diff_reporter/diffmerge_reporter'
13
+ require 'approvals/reporters/diff_reporter/tortoisediff_reporter'
14
+ require 'approvals/reporters/filelauncher_reporter'
@@ -0,0 +1,18 @@
1
+ module Approvals
2
+ module Reporters
3
+ class DiffmergeReporter < Reporter
4
+ include Singleton
5
+
6
+ class << self
7
+ def report(received, approved)
8
+ self.instance.report(received, approved)
9
+ end
10
+ end
11
+
12
+ def default_launcher
13
+ Launcher.diffmerge
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module Approvals
2
+ module Reporters
3
+ class OpendiffReporter < Reporter
4
+ include Singleton
5
+
6
+ class << self
7
+ def report(received, approved)
8
+ self.instance.report(received, approved)
9
+ end
10
+ end
11
+
12
+ def default_launcher
13
+ Launcher.opendiff
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module Approvals
2
+ module Reporters
3
+ class TortoisediffReporter < Reporter
4
+ include Singleton
5
+
6
+ class << self
7
+ def report(received, approved)
8
+ self.instance.report(received, approved)
9
+ end
10
+ end
11
+
12
+ def default_launcher
13
+ Launcher.tortoisediff
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module Approvals
2
+ module Reporters
3
+ class VimdiffReporter < Reporter
4
+ include Singleton
5
+
6
+ class << self
7
+ def report(received, approved)
8
+ self.instance.report(received, approved)
9
+ end
10
+ end
11
+
12
+ def default_launcher
13
+ Launcher.vimdiff
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,18 @@
1
+ module Approvals
2
+ module Reporters
3
+ class FilelauncherReporter < Reporter
4
+ include Singleton
5
+
6
+ class << self
7
+ def report(received, approved = nil)
8
+ self.instance.report(received, approved)
9
+ end
10
+ end
11
+
12
+ def default_launcher
13
+ Launcher.filelauncher
14
+ end
15
+
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,21 @@
1
+ module Approvals
2
+ module Reporters
3
+ class FirstWorkingReporter
4
+
5
+ attr_accessor :reporters
6
+ def initialize(*reporters)
7
+ self.reporters = reporters
8
+ end
9
+
10
+ def working_in_this_environment?
11
+ reporters.any?(&:working_in_this_environment?)
12
+ end
13
+
14
+ def report(received, approved)
15
+ reporter = reporters.find(&:working_in_this_environment?)
16
+ reporter.report(received, approved) unless reporter.nil?
17
+ end
18
+
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,13 @@
1
+ module Approvals
2
+ module Reporters
3
+
4
+ class ImageReporter < FirstWorkingReporter
5
+ include Singleton
6
+
7
+ def initialize
8
+ super(ImageMagickReporter.instance, HtmlImageReporter.instance)
9
+ end
10
+ end
11
+
12
+ end
13
+ end
@@ -0,0 +1,35 @@
1
+ module Approvals
2
+ module Reporters
3
+ class HtmlImageReporter
4
+ include Singleton
5
+
6
+ def working_in_this_environment?
7
+ true
8
+ end
9
+
10
+ def report(received, approved)
11
+ display html(received, approved)
12
+ end
13
+
14
+ def html(received, approved)
15
+ template(File.expand_path(received), File.expand_path(approved))
16
+ end
17
+
18
+ def display(page)
19
+ filename = "#{Approvals.tmp_path}tmp-#{rand(Time.now.to_i)}.html"
20
+ File.open(filename, 'w') do |file|
21
+ file.write page
22
+ end
23
+ system("open #{filename}")
24
+ end
25
+
26
+ private
27
+ def template(received, approved)
28
+ <<-HTML.gsub(/^\ {8}/, '').chomp
29
+ <html><head><title>Approval</title></head><body><center><table style="text-align: center;" border="1"><tr><td><img src="file://#{received}"></td><td><img src="file://#{approved}"></td></tr><tr><td>received</td><td>approved</td></tr></table></center></body></html>
30
+ HTML
31
+ end
32
+
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,20 @@
1
+ module Approvals
2
+ module Reporters
3
+ class ImageMagickReporter
4
+ include Singleton
5
+
6
+ def working_in_this_environment?
7
+ Approvals::SystemCommand.exists? "compare"
8
+ end
9
+
10
+ def create_command_line(received, approved)
11
+ "compare #{received} #{approved} -compose Src x:"
12
+ end
13
+
14
+ def report(received, approved)
15
+ system(create_command_line(received, approved))
16
+ end
17
+
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,49 @@
1
+
2
+ module Approvals
3
+ module Reporters
4
+ module Launcher
5
+
6
+ class << self
7
+ REPORTERS = [:opendiff, :diffmerge, :vimdiff, :tortoisediff, :filelauncher]
8
+
9
+ def memoized(instance_variable)
10
+ unless self.instance_variable_get(instance_variable)
11
+ value = yield
12
+ self.instance_variable_set(instance_variable, value)
13
+ end
14
+ self.instance_variable_get(instance_variable)
15
+ end
16
+
17
+ REPORTERS.each do |name|
18
+ define_method name do
19
+ memoized(:"@#{name}") do
20
+ lambda {|received, approved|
21
+ self.send("#{name}_command".to_sym, received, approved)
22
+ }
23
+ end
24
+ end
25
+ end
26
+
27
+ def opendiff_command(received, approved)
28
+ "opendiff #{received} #{approved}"
29
+ end
30
+
31
+ def diffmerge_command(received, approved)
32
+ "/Applications/DiffMerge.app/Contents/MacOS/DiffMerge --nosplash \"#{received}\" \"#{approved}\""
33
+ end
34
+
35
+ def vimdiff_command(received, approved)
36
+ "vimdiff #{received} #{approved}"
37
+ end
38
+
39
+ def tortoisediff_command(received, approved)
40
+ "C:\\Program Files\\TortoiseSVN\\bin\\TortoiseMerge.exe #{received} #{approved}"
41
+ end
42
+
43
+ def filelauncher_command(received, approved)
44
+ "open #{received}"
45
+ end
46
+ end
47
+ end
48
+ end
49
+ end
@@ -0,0 +1,30 @@
1
+ module Approvals
2
+ module Reporters
3
+ class Reporter
4
+
5
+ attr_reader :launcher
6
+
7
+ def initialize(&launcher)
8
+ @launcher = launcher || default_launcher
9
+ end
10
+
11
+ def report(received, approved)
12
+ launch(received, approved)
13
+ end
14
+
15
+ def approved_when_reported?
16
+ false
17
+ end
18
+
19
+ def default_launcher
20
+ Launcher.opendiff
21
+ end
22
+
23
+ protected
24
+
25
+ def launch(received, approved)
26
+ `#{launcher.call(received, approved)}`
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,4 @@
1
+ require 'approvals'
2
+ require 'approvals/extensions/rspec'
3
+
4
+
@@ -0,0 +1,43 @@
1
+ module Approvals
2
+ class Scrubber
3
+ def initialize(string, hash = nil)
4
+ @hash = hash
5
+ @string = scrub(string)
6
+ end
7
+
8
+ def hash
9
+ @hash ||= {
10
+ 'current_dir' => File.expand_path('.')
11
+ }
12
+ end
13
+
14
+ def scrub(string)
15
+ hash.each do |key, value|
16
+ string = string.gsub(value, wrap(key))
17
+ end
18
+ string
19
+ end
20
+
21
+ def unscrub(string = @string)
22
+ hash.each do |key, value|
23
+ string = string.gsub(wrap(key), value)
24
+ end
25
+ string
26
+ end
27
+
28
+ def wrap(string)
29
+ "{{#{string}}}"
30
+ end
31
+
32
+ def to_s
33
+ @string
34
+ end
35
+
36
+ #def to_executable(&block)
37
+ # Approvals::Executable.new(@string) do |scrubbed|
38
+ # block.call(unscrub(scrubbed))
39
+ # end
40
+ #end
41
+
42
+ end
43
+ end
@@ -0,0 +1,13 @@
1
+ module Approvals
2
+
3
+ module SystemCommand
4
+
5
+ class << self
6
+ def exists?(executable)
7
+ `which #{executable}` != ""
8
+ end
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -0,0 +1,3 @@
1
+ module Approvals
2
+ VERSION = '0.0.22'
3
+ end