bahuvrihi-tap 0.10.1 → 0.10.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,26 @@
1
+ module Tap
2
+ module Test
3
+ module FileMethodsClass
4
+
5
+ # Access the test root structure (a Tap::Root)
6
+ attr_accessor :trs
7
+
8
+ # Infers the test root directory from the calling file. Ex:
9
+ # 'some_class.rb' => 'some_class'
10
+ # 'some_class_test.rb' => 'some_class'
11
+ def file_test_root
12
+ # the calling file is not the direct caller of +method_root+... this method is
13
+ # only accessed from within another method call, hence the target caller is caller[1]
14
+ # rather than caller[0].
15
+
16
+ # caller[1] is considered the calling file (which should be the test case)
17
+ # note that the output of calller.first is like:
18
+ # ./path/to/file.rb:10
19
+ # ./path/to/file.rb:10:in 'method'
20
+ calling_file = caller[1].gsub(/:\d+(:in .*)?$/, "")
21
+ calling_file.chomp!("#{File.extname(calling_file)}")
22
+ calling_file.chomp("_test")
23
+ end
24
+ end
25
+ end
26
+ end
@@ -1,32 +1,15 @@
1
- require 'test/unit'
2
- require 'tap/test/file_methods'
3
1
  require 'tap/test/subset_methods'
4
2
  require 'tap/test/script_methods/script_test'
5
3
 
6
- module Test # :nodoc:
7
- module Unit # :nodoc:
8
- class TestCase
9
- class << self
10
-
11
- def acts_as_script_test(options={})
12
- options = options.inject({:root => file_test_root}) do |hash, (key, value)|
13
- hash[key.to_sym || key] = value
14
- hash
15
- end
16
- acts_as_file_test(options)
17
- include Tap::Test::SubsetMethods
18
- include Tap::Test::ScriptMethods
19
- end
20
-
21
- end
22
- end
23
- end
24
- end
25
-
26
4
  module Tap
27
5
  module Test
28
6
  module ScriptMethods
29
-
7
+
8
+ def self.included(base)
9
+ super
10
+ base.send(:include, Tap::Test::SubsetMethods)
11
+ end
12
+
30
13
  def assert_output_equal(a, b, msg)
31
14
  a = a[1..-1] if a[0] == ?\n
32
15
  if a == b
@@ -81,7 +64,7 @@ module Tap
81
64
  cmd = ScriptTest.new(default_command_path)
82
65
  yield(cmd)
83
66
 
84
- Tap::Root.indir(test_dir, true) do
67
+ Tap::Root.chdir(test_dir, true) do
85
68
  with_argv do
86
69
  puts "\n# == #{method_name}"
87
70
 
@@ -1,167 +1,5 @@
1
- require 'test/unit'
2
1
  require 'benchmark'
3
- require 'pp'
4
- require 'tap/test/env_vars'
5
-
6
- module Test # :nodoc:
7
- module Unit # :nodoc:
8
- class TestCase
9
- class << self
10
- include Tap::Test::EnvVars
11
-
12
- # Passes conditions to subclass
13
- def inherited(subclass) # :nodoc:
14
- super
15
- subclass_conditions = conditions.inject({}) do |memo, (key, value)|
16
- memo.update(key => (value.dup rescue value))
17
- end
18
- subclass.instance_variable_set(:@conditions, subclass_conditions)
19
- subclass.instance_variable_set(:@run_test_suite, nil)
20
- subclass.instance_variable_set(:@skip_messages, [])
21
-
22
- # subclass_inputs = prompt_inputs.inject({}) do |memo, (key, value)|
23
- # memo.update(key => (value.dup rescue value))
24
- # end
25
- # subclass.instance_variable_set("@prompt_inputs", subclass_inputs)
26
- end
27
-
28
- # Experimental -- The idea is to provide a way to prompt once for inputs
29
- # that get used multiple times in a test. Perhaps create accessors
30
- # automatically?
31
-
32
- # def prompt_inputs
33
- # @prompt_inputs ||= {}
34
- # end
35
-
36
- # def require_inputs(*keys, &block)
37
- # if run_subset?("PROMPT")
38
- # puts "\n#{name} requires inputs -- Enter values or 'skip'."
39
-
40
- # argv = ARGV.dup
41
- # begin
42
- # ARGV.clear
43
- # keys.collect do |key|
44
- # print "#{key}: "
45
- # value = gets.strip
46
- # if value =~ /skip/i
47
- # skip_test "missing inputs"
48
- # break
49
- # end
50
- # prompt_inputs[key] = value
51
- # end
52
- # ensure
53
- # ARGV.clear
54
- # ARGV.concat(argv)
55
- # end
56
- # else
57
- # skip_test "prompt test"
58
- # end
59
- # end
60
-
61
- #
62
- # conditions
63
- #
64
-
65
- # A hash of defined conditions
66
- def conditions
67
- @conditions ||= {}
68
- end
69
-
70
- # Defines a condition block and associated message.
71
- # Raises an error if no condition block is given.
72
- def condition(name, msg=nil, &block)
73
- raise "no condition block given" unless block_given?
74
- conditions[name.to_sym] = [msg, block]
75
- end
76
-
77
- # Returns true if the all blocks for the named conditions return true.
78
- #
79
- # condition(:is_true) { true }
80
- # condition(:is_false) { false }
81
- # satisfied?(:is_true) # => true
82
- # satisfied?(:is_true, :is_false) # => false
83
- #
84
- def satisfied?(*conditions)
85
- unsatisfied_conditions(*conditions).empty?
86
- end
87
-
88
- # Returns an array of the unsatified conditions. Raises
89
- # an error if the named condition has not been defined.
90
- #
91
- # condition(:is_true) { true }
92
- # condition(:is_false) { false }
93
- # unsatisfied_conditions(:is_true, :is_false) # => [:is_false]
94
- #
95
- def unsatisfied_conditions(*conditions)
96
- conditions = self.conditions.keys if conditions.empty?
97
- unsatified = []
98
- conditions.each do |condition|
99
- raise "Unknown condition: #{condition}" unless self.conditions.has_key?(condition)
100
- unsatified << condition unless (self.conditions[condition.to_sym].last.call() ? true : false)
101
- end
102
- unsatified
103
- end
104
-
105
- # Returns true if RUBY_PLATFORM matches one of the specfied
106
- # platforms. Use the prefix 'non_' to specify any plaform
107
- # except the specified platform (ex: 'non_mswin'). Returns
108
- # true if no platforms are specified.
109
- #
110
- # Some common platforms:
111
- # mswin Windows
112
- # darwin Mac
113
- def match_platform?(*platforms)
114
- platforms.each do |platform|
115
- platform.to_s =~ /^(non_)?(.*)/
116
-
117
- non = true if $1
118
- match_platform = !RUBY_PLATFORM.index($2).nil?
119
- return false unless (non && !match_platform) || (!non && match_platform)
120
- end
121
-
122
- true
123
- end
124
-
125
- # Returns true if the subset type or 'ALL' is specified in ENV
126
- def run_subset?(type)
127
- env_true?(type) || env_true?("ALL") ? true : false
128
- end
129
-
130
- #
131
- # Methods for skipping a test suite
132
- #
133
- attr_accessor :run_test_suite
134
-
135
- # Returns run_test_suite, or true if run_test_suite is not set.
136
- def run_test_suite?
137
- run_test_suite.nil? ? true : run_test_suite
138
- end
139
-
140
- # Causes a test suite to be skipped. If a message is given, it will
141
- # print and notify the user the test suite has been skipped.
142
- def skip_test(msg=nil)
143
- self.run_test_suite = false
144
-
145
- # experimental -- perhaps use this so that a test can be skipped
146
- # for multiple reasons?
147
- @skip_messages << msg unless msg.nil?
148
- end
149
-
150
- alias :original_suite :suite
151
-
152
- # Modifies the default suite method to include/exclude tests based on platform.
153
- def suite # :nodoc:
154
- if run_test_suite?
155
- original_suite
156
- else
157
- puts "Skipping #{name}: #{@skip_messages.join(', ')}" unless @skip_messages.empty?
158
- Test::Unit::TestSuite.new(name)
159
- end
160
- end
161
- end
162
- end
163
- end
164
- end
2
+ require 'tap/test/subset_methods_class'
165
3
 
166
4
  module Tap
167
5
  module Test
@@ -247,6 +85,11 @@ module Tap
247
85
  # See {Test::Unit::TestCase}[link:classes/Test/Unit/TestCase.html] for documentation of the class methods added by SubsetMethods
248
86
  module SubsetMethods
249
87
  include Tap::Test::EnvVars
88
+
89
+ def self.included(base)
90
+ super
91
+ base.extend SubsetMethodsClass
92
+ end
250
93
 
251
94
  def satisfied?(*conditions)
252
95
  self.class.satisfied?(*conditions)
@@ -0,0 +1,128 @@
1
+ require 'tap/test/env_vars'
2
+
3
+ module Tap
4
+ module Test
5
+ module SubsetMethodsClass
6
+ include Tap::Test::EnvVars
7
+
8
+ # Passes conditions to subclass
9
+ def inherited(subclass) # :nodoc:
10
+ super
11
+ subclass_conditions = conditions.inject({}) do |memo, (key, value)|
12
+ memo.update(key => (value.dup rescue value))
13
+ end
14
+ subclass.instance_variable_set(:@conditions, subclass_conditions)
15
+ subclass.instance_variable_set(:@run_test_suite, nil)
16
+ subclass.instance_variable_set(:@skip_messages, [])
17
+
18
+ # subclass_inputs = prompt_inputs.inject({}) do |memo, (key, value)|
19
+ # memo.update(key => (value.dup rescue value))
20
+ # end
21
+ # subclass.instance_variable_set("@prompt_inputs", subclass_inputs)
22
+ end
23
+
24
+ # Experimental -- The idea is to provide a way to prompt once for inputs
25
+ # that get used multiple times in a test. Perhaps create accessors
26
+ # automatically?
27
+
28
+ # def prompt_inputs
29
+ # @prompt_inputs ||= {}
30
+ # end
31
+
32
+ # def require_inputs(*keys, &block)
33
+ # if run_subset?("PROMPT")
34
+ # puts "\n#{name} requires inputs -- Enter values or 'skip'."
35
+
36
+ # argv = ARGV.dup
37
+ # begin
38
+ # ARGV.clear
39
+ # keys.collect do |key|
40
+ # print "#{key}: "
41
+ # value = gets.strip
42
+ # if value =~ /skip/i
43
+ # skip_test "missing inputs"
44
+ # break
45
+ # end
46
+ # prompt_inputs[key] = value
47
+ # end
48
+ # ensure
49
+ # ARGV.clear
50
+ # ARGV.concat(argv)
51
+ # end
52
+ # else
53
+ # skip_test "prompt test"
54
+ # end
55
+ # end
56
+
57
+ #
58
+ # conditions
59
+ #
60
+
61
+ # A hash of defined conditions
62
+ def conditions
63
+ @conditions ||= {}
64
+ end
65
+
66
+ # Defines a condition block and associated message.
67
+ # Raises an error if no condition block is given.
68
+ def condition(name, msg=nil, &block)
69
+ raise "no condition block given" unless block_given?
70
+ conditions[name.to_sym] = [msg, block]
71
+ end
72
+
73
+ # Returns true if the all blocks for the named conditions return true.
74
+ #
75
+ # condition(:is_true) { true }
76
+ # condition(:is_false) { false }
77
+ # satisfied?(:is_true) # => true
78
+ # satisfied?(:is_true, :is_false) # => false
79
+ #
80
+ def satisfied?(*conditions)
81
+ unsatisfied_conditions(*conditions).empty?
82
+ end
83
+
84
+ # Returns an array of the unsatified conditions. Raises
85
+ # an error if the named condition has not been defined.
86
+ #
87
+ # condition(:is_true) { true }
88
+ # condition(:is_false) { false }
89
+ # unsatisfied_conditions(:is_true, :is_false) # => [:is_false]
90
+ #
91
+ def unsatisfied_conditions(*conditions)
92
+ conditions = self.conditions.keys if conditions.empty?
93
+ unsatified = []
94
+ conditions.each do |condition|
95
+ raise "Unknown condition: #{condition}" unless self.conditions.has_key?(condition)
96
+ unsatified << condition unless (self.conditions[condition.to_sym].last.call() ? true : false)
97
+ end
98
+ unsatified
99
+ end
100
+
101
+ # Returns true if RUBY_PLATFORM matches one of the specfied
102
+ # platforms. Use the prefix 'non_' to specify any plaform
103
+ # except the specified platform (ex: 'non_mswin'). Returns
104
+ # true if no platforms are specified.
105
+ #
106
+ # Some common platforms:
107
+ # mswin Windows
108
+ # darwin Mac
109
+ def match_platform?(*platforms)
110
+ platforms.each do |platform|
111
+ platform.to_s =~ /^(non_)?(.*)/
112
+
113
+ non = true if $1
114
+ match_platform = !RUBY_PLATFORM.index($2).nil?
115
+ return false unless (non && !match_platform) || (!non && match_platform)
116
+ end
117
+
118
+ true
119
+ end
120
+
121
+ # Returns true if the subset type or 'ALL' is specified in ENV
122
+ def run_subset?(type)
123
+ env_true?(type) || env_true?("ALL") ? true : false
124
+ end
125
+ end
126
+
127
+ end
128
+ end
@@ -1,35 +1,3 @@
1
- require 'test/unit'
2
- require 'tap/test/file_methods'
3
- require 'tap/test/subset_methods'
4
-
5
- module Test # :nodoc:
6
- module Unit # :nodoc:
7
- class TestCase
8
- class << self
9
- # Causes a unit test to act as a tap test -- resulting in the following:
10
- # - setup using acts_as_file_test
11
- # - inclusion of Tap::Test::SubsetMethods
12
- # - inclusion of Tap::Test::InstanceMethods
13
- #
14
- # Note: Unless otherwise specified, <tt>acts_as_tap_test</tt> infers a root directory
15
- # based on the calling file. Be sure to specify the root directory explicitly
16
- # if you call acts_as_file_test from a file that is NOT meant to be test file.
17
- def acts_as_tap_test(options={})
18
- options = options.inject({:root => file_test_root}) do |hash, (key, value)|
19
- hash[key.to_sym || key] = value
20
- hash
21
- end
22
- acts_as_file_test(options)
23
-
24
- include Tap::Test::SubsetMethods
25
- include Tap::Test::TapMethods
26
- end
27
-
28
- end
29
- end
30
- end
31
- end
32
-
33
1
  module Tap
34
2
  module Test
35
3
 
@@ -97,7 +65,7 @@ module Tap
97
65
  # Asserts that an array of audits are all equal, basically feeding
98
66
  # each pair of audits to assert_audit_equal.
99
67
  def assert_audits_equal(expected, audits)
100
- each_pair_with_index(expected, audits) do |exp, audit, index|
68
+ Utils.each_pair_with_index(expected, audits) do |exp, audit, index|
101
69
  assert_audit_equal(exp, audit, [index])
102
70
  end
103
71
  end
@@ -0,0 +1,118 @@
1
+ require 'tap/root'
2
+ require 'fileutils'
3
+
4
+ module Tap
5
+ module Test
6
+ module Utils
7
+ module_function
8
+
9
+ # Generates an array of [source, reference] pairs mapping source
10
+ # files to reference files under the source_dir and reference_dir,
11
+ # respectively. Only files under source dir with the reference_extname
12
+ # will be mapped; mappings are either:
13
+ #
14
+ # - a direct translation from source_dir to reference_dir, minus
15
+ # the extname
16
+ # - a path under reference_dir with a matching basename, minus
17
+ # the extname, so long as the matched path is unique
18
+ #
19
+ # If a mapped path cannot be found, dereference raises an ArgumentError.
20
+ #
21
+ # === example
22
+ #
23
+ # root
24
+ # |- input
25
+ # | |- dir.ref
26
+ # | |- ignored.txt
27
+ # | |- one.txt.ref
28
+ # | `- two.txt.ref
29
+ # `- ref
30
+ # |- dir
31
+ # |- one.txt
32
+ # `- path
33
+ # `- to
34
+ # `- two.txt
35
+ #
36
+ # reference_map('/root/input', '/root/ref')
37
+ # # => [
38
+ # # ['/root/input/dir.ref', '/root/ref/dir'],
39
+ # # ['/root/input/one.txt.ref', '/root/ref/one.txt'],
40
+ # # ['/root/input/two.txt.ref', '/root/ref/path/to/two.txt']]
41
+ #
42
+ # reference_map(:input, :ref, ".txt") # !> ArgumentError
43
+ #
44
+ def reference_map(source_dir, reference_dir, reference_extname='.ref')
45
+ Dir.glob(File.join(source_dir, "**/*#{reference_extname}")).collect do |path|
46
+ relative_path = Tap::Root.relative_filepath(source_dir, path).chomp(reference_extname)
47
+ reference_path = File.join(reference_dir, relative_path)
48
+
49
+ unless File.exists?(reference_path)
50
+ matching_paths = Dir.glob(File.join(reference_dir, "**/#{File.basename(relative_path)}"))
51
+
52
+ reference_path = case matching_paths.length
53
+ when 0 then raise ArgumentError, "no reference found for: #{path}"
54
+ when 1 then matching_paths[0]
55
+ else raise ArgumentError, "multiple references found for: #{path} [#{matching_paths.join(', ')}]"
56
+ end
57
+ end
58
+
59
+ [path, reference_path]
60
+ end
61
+ end
62
+
63
+ def dereference(source_dirs, reference_dir, extname='.ref')
64
+ mapped_paths = []
65
+ begin
66
+ [*source_dirs].each do |source_dir|
67
+ reference_map(source_dir, reference_dir, extname).each do |path, source|
68
+ FileUtils.rm_r(path)
69
+ target = path.chomp(extname)
70
+ FileUtils.cp_r(source, target)
71
+ mapped_paths << target
72
+ end
73
+ end unless reference_dir == nil
74
+
75
+ yield
76
+
77
+ ensure
78
+ mapped_paths.each do |path|
79
+ FileUtils.rm_r(path) if File.exists?(path)
80
+ FileUtils.touch(path + extname)
81
+ end
82
+ end
83
+ end
84
+
85
+ # Yields to the input block for each pair of entries in the input
86
+ # arrays. An error is raised if the input arrays do not have equal
87
+ # numbers of entries.
88
+ def each_pair(a, b, &block) # :yields: entry_a, entry_b,
89
+ each_pair_with_index(a,b) do |entry_a, entry_b, index|
90
+ yield(entry_a, entry_b)
91
+ end
92
+ end
93
+
94
+ # Same as each_pair but yields the index of the entries as well.
95
+ def each_pair_with_index(a, b, &block) # :yields: entry_a, entry_b, index
96
+ a = [a] unless a.kind_of?(Array)
97
+ b = [b] unless b.kind_of?(Array)
98
+
99
+ raise ArgumentError, "The input arrays must have an equal number of entries." unless a.length == b.length
100
+ 0.upto(a.length-1) do |index|
101
+ yield(a[index], b[index], index)
102
+ end
103
+ end
104
+
105
+ # Attempts to remove the specified directory. The root
106
+ # will not be removed if the directory does not exist, or
107
+ # is not empty.
108
+ def try_remove_dir(dir)
109
+ # Remove the directory if possible
110
+ begin
111
+ FileUtils.rmdir(dir) if File.exists?(dir) && Dir.glob(File.join(dir, "*")).empty?
112
+ rescue
113
+ # rescue cases where there is a hidden file, for example .svn
114
+ end
115
+ end
116
+ end
117
+ end
118
+ end