root / lib / test / unit / collector / load.rb @ 16a276fdc77847a92cba21d060b9880eb1fe75bb

View | Annotate | Download (3.8 KB)

1
require 'pathname'
2
3
require 'test/unit/testsuite'
4
require 'test/unit/collector'
5
6
module Test
7
  module Unit
8
    module Collector
9
      class Load
10
        include Collector
11
12
        attr_reader :patterns, :excludes, :base
13
14
        def initialize
15
          super
16
          @system_excludes = [/~\z/, /\A\.\#/]
17
          @system_directory_excludes = [/\A(?:CVS|\.svn)\z/]
18
          @patterns = [/\Atest[_\-].+\.rb\z/m]
19
          @excludes = []
20
          @base = nil
21
        end
22
23
        def base=(base)
24
          base = Pathname(base) unless base.nil?
25
          @base = base
26
        end
27
28
        def collect(*froms)
29
          add_load_path(@base) do
30
            froms = ["."] if froms.empty?
31
            test_suites = froms.collect do |from|
32
              test_suite = collect_recursive(resolve_path(from), find_test_cases)
33
              test_suite = nil if test_suite.tests.empty?
34
              test_suite
35
            end.compact
36
37
            if test_suites.size > 1
38
              test_suite = TestSuite.new("[#{froms.join(', ')}]")
39
              sort(test_suites).each do |sub_test_suite|
40
                test_suite << sub_test_suite
41
              end
42
              test_suite
43
            else
44
              test_suites.first
45
            end
46
          end
47
        end
48
49
        def find_test_cases(ignore=[])
50
          test_cases = []
51
          TestCase::DESCENDANTS.each do |test_case|
52
            test_cases << test_case unless ignore.include?(test_case)
53
          end
54
          ignore.concat(test_cases)
55
          test_cases
56
        end
57
58
        private
59
        def collect_recursive(path, already_gathered)
60
          sub_test_suites = []
61
62
          if path.directory?
63
            directories, files = path.children.partition do |child|
64
              child.directory?
65
            end
66
67
            files.each do |child|
68
              next if excluded_file?(child.basename.to_s)
69
              collect_file(child, sub_test_suites, already_gathered)
70
            end
71
72
            directories.each do |child|
73
              next if excluded_directory?(child.basename.to_s)
74
              sub_test_suite = collect_recursive(child, already_gathered)
75
              sub_test_suites << sub_test_suite unless sub_test_suite.empty?
76
            end
77
          else
78
            unless excluded_file?(path.basename.to_s)
79
              collect_file(path, sub_test_suites, already_gathered)
80
            end
81
          end
82
83
          test_suite = TestSuite.new(path.basename.to_s)
84
          sort(sub_test_suites).each do |sub_test_suite|
85
            test_suite << sub_test_suite
86
          end
87
          test_suite
88
        end
89
90
        def collect_file(path, test_suites, already_gathered)
91
          add_load_path(path.expand_path.dirname) do
92
            require(path.to_s)
93
            find_test_cases(already_gathered).each do |test_case|
94
              add_suite(test_suites, test_case.suite)
95
            end
96
          end
97
        end
98
99
        def resolve_path(path)
100
          if @base
101
            @base + path
102
          else
103
            Pathname(path)
104
          end
105
        end
106
107
        def add_load_path(path)
108
          $LOAD_PATH.push(path.to_s) if path
109
          yield
110
        ensure
111
          $LOAD_PATH.delete_at($LOAD_PATH.rindex(path.to_s)) if path
112
        end
113
114
        def excluded_directory?(base)
115
          @system_directory_excludes.any? {|pattern| pattern =~ base}
116
        end
117
118
        def excluded_file?(base)
119
          return true if @system_excludes.any? {|pattern| pattern =~ base}
120
121
          patterns = @patterns || []
122
          unless patterns.empty?
123
            return true unless patterns.any? {|pattern| pattern =~ base}
124
          end
125
126
          excludes = @excludes || []
127
          unless excludes.empty?
128
            return true if excludes.any? {|pattern| pattern =~ base}
129
          end
130
131
          false
132
        end
133
      end
134
    end
135
  end
136
end