rsutphin-cf_case_check 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,50 @@
1
+ module CaseCheck
2
+
3
+ # Reference as cf_name (or CF_name)
4
+ class CustomTag < Reference
5
+ attr_reader :expected_path, :resolved_to
6
+
7
+ class << self
8
+ attr_writer :directories
9
+
10
+ def directories
11
+ @directories ||= []
12
+ end
13
+
14
+ def search(source)
15
+ source.scan(/<(CF_(\w+))/i) do |match_data, line_number|
16
+ self.new(source, match_data[1], line_number)
17
+ end
18
+ end
19
+
20
+ def recursive_directories
21
+ directories + directories.collect do |dir|
22
+ collect_subdirs(dir)
23
+ end.flatten
24
+ end
25
+
26
+ private
27
+
28
+ def collect_subdirs(start)
29
+ [start] + Dir[File.join(start, '*')].select { |f| File.directory?(f) }.collect do |dir|
30
+ collect_subdirs(dir)
31
+ end.flatten
32
+ end
33
+ end
34
+
35
+ def initialize(source, text, line)
36
+ super
37
+ @expected_path = text[3, text.size] + ".cfm"
38
+ @resolved_to = resolve
39
+ end
40
+
41
+ private
42
+
43
+ def resolve
44
+ [File.dirname(source.filename), self.class.recursive_directories].flatten.inject(nil) do |resolved, dir|
45
+ resolved || resolve_in(dir)
46
+ end
47
+ end
48
+ end
49
+
50
+ end
data/lib/case_check.rb ADDED
@@ -0,0 +1,60 @@
1
+
2
+ module CaseCheck
3
+ # :stopdoc:
4
+ VERSION = '0.0.0'.freeze
5
+ LIBPATH = ::File.expand_path(::File.dirname(__FILE__)) + ::File::SEPARATOR
6
+ PATH = ::File.dirname(LIBPATH) + ::File::SEPARATOR
7
+ # :startdoc:
8
+
9
+ # Returns the version string for the library.
10
+ #
11
+ def self.version
12
+ VERSION
13
+ end
14
+
15
+ def self.status_stream
16
+ @stderr ||= $stderr
17
+ end
18
+
19
+ def self.status_stream=(err)
20
+ @stderr = err
21
+ end
22
+
23
+ # Returns the library path for the module. If any arguments are given,
24
+ # they will be joined to the end of the libray path using
25
+ # <tt>File.join</tt>.
26
+ #
27
+ def self.libpath( *args )
28
+ args.empty? ? LIBPATH : ::File.join(LIBPATH, args.flatten)
29
+ end
30
+
31
+ # Returns the lpath for the module. If any arguments are given,
32
+ # they will be joined to the end of the path using
33
+ # <tt>File.join</tt>.
34
+ #
35
+ def self.path( *args )
36
+ args.empty? ? PATH : ::File.join(PATH, args.flatten)
37
+ end
38
+
39
+ # Utility method used to rquire all files ending in .rb that lie in the
40
+ # directory below this file that has the same name as the filename passed
41
+ # in. Optionally, a specific _directory_ name can be passed in such that
42
+ # the _filename_ does not have to be equivalent to the directory.
43
+ #
44
+ def self.require_all_libs_relative_to( fname, dir = nil )
45
+ dir ||= ::File.basename(fname, '.*')
46
+ search_me = ::File.expand_path(
47
+ ::File.join(::File.dirname(fname), dir, '*.rb'))
48
+
49
+ Dir.glob(search_me).sort.each {|rb| require rb}
50
+ end
51
+
52
+ def self.exit
53
+ exit
54
+ end
55
+
56
+ end # module CaseCheck
57
+
58
+ CaseCheck.require_all_libs_relative_to(__FILE__)
59
+
60
+ # EOF
@@ -0,0 +1,161 @@
1
+ require File.join(File.dirname(__FILE__), %w[spec_helper])
2
+
3
+ module CaseCheck
4
+
5
+ describe ColdfusionSource do
6
+ describe "line_of" do
7
+ def actual_line_of(content, i)
8
+ ColdfusionSource.new("dc", content).line_of(i)
9
+ end
10
+
11
+ it "is always line 1 for a single line file" do
12
+ actual_line_of("some text", 3).should == 1
13
+ end
14
+
15
+ it "can find something on the last line" do
16
+ actual_line_of("some\ntext\nhere", 13).should == 3
17
+ end
18
+
19
+ it "is 1 for character 0" do
20
+ actual_line_of("some text", 0).should == 1
21
+ end
22
+ end
23
+
24
+ describe "scan" do
25
+ def perform_scan(content, re)
26
+ ColdfusionSource.new("dc", content).scan(re) do |md, l|
27
+ [md[0], l]
28
+ end
29
+ end
30
+
31
+ it "finds one instance" do
32
+ actual = perform_scan("123 abc", /[a-z]+/)
33
+ actual.should have(1).match
34
+ actual.first.should == ['abc', 1]
35
+ end
36
+
37
+ it "finds multiple instances" do
38
+ actual = perform_scan("abc def 123 four", /[a-z]+/)
39
+ actual.should have(3).matches
40
+ actual[0].should == ['abc', 1]
41
+ actual[1].should == ['def', 1]
42
+ actual[2].should == ['four', 1]
43
+ end
44
+
45
+ it "finds instances on multiple lines" do
46
+ actual = perform_scan(<<-TEXT, /[a-z]+/)
47
+ for
48
+ 23
49
+ answers
50
+ TEXT
51
+ actual.should have(2).matches
52
+ actual[0].should == ['for', 1]
53
+ actual[1].should == ['answers', 3]
54
+ end
55
+ end
56
+
57
+ describe "scan for tag" do
58
+ def perform_scan(content, tag)
59
+ ColdfusionSource.new("dc", content).scan_for_tag(tag) do |text, attributes, l|
60
+ { :text => text, :attributes => attributes, :line_number => l }
61
+ end
62
+ end
63
+
64
+ it "finds a tag with no attributes" do
65
+ actual = perform_scan("text <cfabort>more text", "cfabort")
66
+ actual.should have(1).match
67
+ actual.first[:text].should == "<cfabort>"
68
+ actual.first[:attributes].should == { }
69
+ actual.first[:line_number].should == 1
70
+ end
71
+
72
+ it "finds an XML-style self-closing tag with no attributes" do
73
+ actual = perform_scan("text <cfabort/>more text", "cfabort")
74
+ actual.should have(1).match
75
+ actual.first[:text].should == "<cfabort/>"
76
+ actual.first[:attributes].should == { }
77
+ actual.first[:line_number].should == 1
78
+ end
79
+
80
+ it "finds a single-line tag with attributes" do
81
+ actual = perform_scan("and then <cflog text='in the middle'> something happens", 'cflog')
82
+ actual.should have(1).match
83
+ actual.first[:text].should == "<cflog text='in the middle'>"
84
+ actual.first[:attributes].should have(1).attribute
85
+ actual.first[:attributes][:text].should == 'in the middle'
86
+ actual.first[:line_number].should == 1
87
+ end
88
+
89
+ it "finds a single-line self-closing tag with attributes" do
90
+ actual = perform_scan("and then <cflog text='in the middle'/> something happens", 'cflog')
91
+ actual.should have(1).match
92
+ actual.first[:text].should == "<cflog text='in the middle'/>"
93
+ actual.first[:attributes].should have(1).attribute
94
+ actual.first[:attributes][:text].should == 'in the middle'
95
+ actual.first[:line_number].should == 1
96
+ end
97
+
98
+ it "finds attributes which are surrounded by single quotes" do
99
+ actual = perform_scan("and then <cflog text='in the middle'/> something happens", 'cflog')
100
+ actual.should have(1).match
101
+ actual.first[:attributes].should have(1).attribute
102
+ actual.first[:attributes][:text].should == 'in the middle'
103
+ end
104
+
105
+ it "finds attributes which are surrounded by double quotes" do
106
+ actual = perform_scan(%q(and then <cflog text="in the middle"/> something happens), 'cflog')
107
+ actual.should have(1).match
108
+ actual.first[:attributes].should have(1).attribute
109
+ actual.first[:attributes][:text].should == 'in the middle'
110
+ end
111
+
112
+ it "finds multiple tags" do
113
+ actual = perform_scan(<<-CFM, "cfparam")
114
+ <cfparam name="foo" default="42">
115
+ <cfparam name="bar" default="11">
116
+ CFM
117
+ actual.should have(2).matches
118
+ actual[0][:attributes].should == { :name => 'foo', :default => '42' }
119
+ actual[1][:attributes].should == { :name => 'bar', :default => '11' }
120
+ actual[1][:line_number].should == 2
121
+ end
122
+
123
+ it "finds tags that are spread over multiple lines" do
124
+ actual = perform_scan(<<-CFM, "cfmodule")
125
+ <html>
126
+ <title>
127
+ <cfmodule
128
+ name="whatever"
129
+ >
130
+ </title></html>
131
+ CFM
132
+ actual.should have(1).match
133
+ actual.first[:attributes].should == { :name => 'whatever' }
134
+ end
135
+
136
+ it "is flexible about whitespace around '='" do
137
+ actual = perform_scan(<<-CFM, "cfparam")
138
+ <cfparam name ="foo" default= "42">
139
+ <cfparam name="bar" default = "11">
140
+ CFM
141
+ actual.should have(2).matches
142
+ actual[0][:attributes].should == { :name => 'foo', :default => '42' }
143
+ actual[1][:attributes].should == { :name => 'bar', :default => '11' }
144
+ actual[1][:line_number].should == 2
145
+ end
146
+
147
+ it "downcases attribute keys" do
148
+ actual = perform_scan(%q(<cfabort NOW='later'>), 'cfabort')
149
+ actual.first[:attributes].keys.should include(:now)
150
+ end
151
+
152
+ it "matches tags without regard to case" do
153
+ actual = perform_scan(%q(Time to go <CFABORT/>), 'cfAbort')
154
+ actual.should have(1).matches
155
+ actual.first[:text].should == '<CFABORT/>'
156
+ end
157
+ end
158
+ end
159
+
160
+ end # module
161
+
@@ -0,0 +1,103 @@
1
+ require File.join(File.dirname(__FILE__), %w[spec_helper])
2
+
3
+ describe CaseCheck::Params do
4
+ def config_file(filename, contents)
5
+ FileUtils.mkdir_p File.dirname(filename)
6
+ File.open(filename, 'w') { |f| f.write contents }
7
+ end
8
+
9
+ def actual_params(*argv)
10
+ CaseCheck::Params.new(argv.flatten)
11
+ end
12
+
13
+ describe "--dir directory" do
14
+ before do
15
+ @dirname = "/tmp/cftest"
16
+ FileUtils.mkdir_p @dirname
17
+ end
18
+
19
+ after do
20
+ FileUtils.rm_rf @dirname
21
+ end
22
+
23
+ it "makes the directory available" do
24
+ actual = actual_params('--dir', @dirname)
25
+ actual.directory.should == @dirname
26
+ end
27
+
28
+ it "defaults the directory to the current" do
29
+ actual_params.directory.should == '.'
30
+ end
31
+
32
+ it "reads the configuration directory/cf_case_check.yml" do
33
+ config_file File.join(@dirname, "cf_case_check.yml"), <<-YAML
34
+ cfc_directories:
35
+ - /tmp/baz
36
+ YAML
37
+ actual_params('--dir', @dirname)
38
+ CaseCheck::Cfc.directories.should == %w(/tmp/baz)
39
+ end
40
+
41
+ it "prefers an explicitly named configuration file if both are available" do
42
+ config_file File.join(@dirname, "cf_case_check.yml"), <<-YAML
43
+ cfc_directories:
44
+ - /tmp/quux
45
+ YAML
46
+ config_file File.join(@dirname, "another.yml"), <<-YAML
47
+ cfc_directories:
48
+ - /tmp/qurt
49
+ YAML
50
+ actual_params('--dir', @dirname, '--config', File.join(@dirname, 'another.yml'))
51
+ CaseCheck::Cfc.directories.should == %w(/tmp/qurt)
52
+ end
53
+ end
54
+
55
+ describe "--config filename" do
56
+ before do
57
+ @filename = "/tmp/foo.yml"
58
+ config_file @filename, <<-YAML
59
+ cfc_directories:
60
+ - /tmp/bar
61
+ YAML
62
+ CaseCheck::Cfc.directories = nil
63
+ end
64
+
65
+ after do
66
+ FileUtils.rm_rf @filename
67
+ end
68
+
69
+ it "loads the configuration" do
70
+ actual_params('--config', @filename)
71
+ CaseCheck::Cfc.directories.should == %w(/tmp/bar)
72
+ end
73
+ end
74
+
75
+ describe "--version" do
76
+ it "prints to configured stderr" do
77
+ CaseCheck.should_receive(:exit)
78
+ actual_params('--version')
79
+ CaseCheck.status_stream.string.should == "cf_case_check #{CaseCheck.version}\n"
80
+ end
81
+ end
82
+
83
+ describe "--help" do
84
+ it "prints to configured stderr" do
85
+ CaseCheck.should_receive(:exit)
86
+ actual_params('--help')
87
+ CaseCheck.status_stream.string.should include("cf_case_check")
88
+ CaseCheck.status_stream.string.should include("config")
89
+ CaseCheck.status_stream.string.should include("dir")
90
+ end
91
+ end
92
+
93
+ describe "--verbose" do
94
+ it "sets the verbose flag" do
95
+ actual_params('--verbose').should be_verbose
96
+ actual_params('-v').should be_verbose
97
+ end
98
+
99
+ it "does not set the verbose flag when omitted" do
100
+ actual_params.should_not be_verbose
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,42 @@
1
+ require 'fileutils'
2
+ require File.join(File.dirname(__FILE__), %w[spec_helper])
3
+
4
+ describe CaseCheck::Configuration do
5
+ before do
6
+ @filename = "/tmp/cf_case_check/config.yml"
7
+ end
8
+
9
+ after do
10
+ if File.exist?(@filename)
11
+ FileUtils.rm_rf @filename
12
+ end
13
+ end
14
+
15
+ def config_file(contents)
16
+ FileUtils.mkdir_p File.dirname(@filename)
17
+ File.open(@filename, 'w') { |f| f.write contents }
18
+ end
19
+
20
+ def read_config
21
+ CaseCheck::Configuration.new(@filename)
22
+ end
23
+
24
+ it "reads custom tag directories" do
25
+ config_file <<-YAML
26
+ custom_tag_directories:
27
+ - /var/www/customtags
28
+ - /home/cf/customtags
29
+ YAML
30
+ read_config
31
+ CaseCheck::CustomTag.directories.should == %w(/var/www/customtags /home/cf/customtags)
32
+ end
33
+
34
+ it "resolves relative custom tag directories against the config file directory" do
35
+ config_file <<-YAML
36
+ custom_tag_directories:
37
+ - zappo/customtags
38
+ YAML
39
+ read_config
40
+ CaseCheck::CustomTag.directories.should == %w(/tmp/cf_case_check/zappo/customtags)
41
+ end
42
+ end
@@ -0,0 +1,72 @@
1
+ require 'fileutils'
2
+
3
+ require File.join(File.dirname(__FILE__), %w[spec_helper])
4
+
5
+ describe File, ' extensions ' do
6
+ before do
7
+ @tmpdir = "/tmp/case_check_spec"
8
+ FileUtils.mkdir_p(File.dirname(@tmpdir))
9
+ end
10
+
11
+ after do
12
+ FileUtils.rm_rf(@tmpdir)
13
+ end
14
+
15
+ def touch(filename)
16
+ full = testfile(filename)
17
+ FileUtils.mkdir_p(File.dirname(full))
18
+ File.open(full, 'w') { }
19
+ full
20
+ end
21
+
22
+ def testfile(filename)
23
+ File.join(@tmpdir, filename)
24
+ end
25
+
26
+ describe "#exists_exactly?" do
27
+ it "does not include insensitive file matches" do
28
+ touch("some_file")
29
+ File.exists_exactly?(testfile("some_File")).should be_false
30
+ end
31
+
32
+ it "does not include insensitive directory matches" do
33
+ touch("Bar/quUx")
34
+ File.exists_exactly?(testfile("bAr/quUx")).should be_false
35
+ end
36
+
37
+ it "does not have a problem with files that don't exist at all" do
38
+ File.exists_exactly?(testfile("nope")).should be_false
39
+ end
40
+
41
+ it "does match exact file paths" do
42
+ touch("qUuX/foo")
43
+ File.exists_exactly?(testfile("qUuX/foo")).should be_true
44
+ end
45
+ end
46
+
47
+ describe "#case_insensitive_canonical_name" do
48
+ it "finds exact matches" do
49
+ touch("baz/bar.foo")
50
+ File.case_insensitive_canonical_name(testfile("baz/bar.foo")).should == testfile("baz/bar.foo")
51
+ end
52
+
53
+ it "finds matches with case-insensitive matching directories" do
54
+ touch("baZ/baR/foo")
55
+ File.case_insensitive_canonical_name(testfile("baz/bar/foo")).should == testfile("baZ/baR/foo")
56
+ end
57
+
58
+ it "finds matches with case-insensitive matching filenames" do
59
+ touch("baz/bar/fOz")
60
+ File.case_insensitive_canonical_name(testfile("baz/bar/FOZ")).should == testfile("baz/bar/fOz")
61
+ end
62
+
63
+ it "finds no match for non-existent files" do
64
+ File.case_insensitive_canonical_name(testfile("quux")).should be_nil
65
+ end
66
+
67
+ it "handles path navigation" do
68
+ touch("baz/bar/foo/quux")
69
+ File.case_insensitive_canonical_name(testfile("baz/bar/quod/../fOO/quux")).should == testfile("baz/bar/foo/quux")
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,52 @@
1
+ require 'fileutils'
2
+
3
+ require File.join(File.dirname(__FILE__), %w[spec_helper])
4
+
5
+ describe CaseCheck::Reference do
6
+ class SampleReference < CaseCheck::Reference
7
+ attr_accessor :expected_path, :resolved_to
8
+
9
+ def initialize(expected_path, resolved_to, line=0, text=nil)
10
+ self.expected_path = expected_path
11
+ self.resolved_to = resolved_to
12
+ self.line = line
13
+ self.text = text
14
+ end
15
+ end
16
+
17
+ describe 'default resolution' do
18
+ it 'is exact when resolved_to ends with expected_path' do
19
+ SampleReference.new("/foo/patient.cfm", "/home/cfcode/apps/notis/foo/patient.cfm").resolution.should == :exact
20
+ end
21
+
22
+ it 'is exact when resolved_to ends with expected_path, disregarding ../.' do
23
+ SampleReference.new(".././foo/patient.cfm", "/home/cfcode/apps/notis/foo/patient.cfm").resolution.should == :exact
24
+ end
25
+
26
+ it 'is case sensitive when resolved_to ends with something else' do
27
+ SampleReference.new("/foo/Patient.cfm", "/home/cfcode/apps/notis/foo/patient.cfm").resolution.should == :case_insensitive
28
+ end
29
+
30
+ it 'is unresolved without resolved_to' do
31
+ SampleReference.new("/foo/patient.cfm", nil).resolution.should be_nil
32
+ end
33
+ end
34
+
35
+ describe 'default message' do
36
+ it "indicates when it is unresolved" do
37
+ SampleReference.new("/foo/patient.cfm", nil, 11, "FOO_Patient").message.should ==
38
+ "Unresolved sample reference on line 11: FOO_Patient"
39
+ end
40
+
41
+ it "indicates when it is exactly resolved" do
42
+ SampleReference.new("/foo/patient.cfm", "/home/cfcode/apps/notis/foo/patient.cfm", 11, "foo_patient").message.should ==
43
+ "Exactly resolved sample reference on line 11 from foo_patient to /home/cfcode/apps/notis/foo/patient.cfm"
44
+ end
45
+
46
+ it "indicates when it is only case-insensitively resolved" do
47
+ SampleReference.new("/foo/Patient.cfm", "/home/cfcode/apps/notis/foo/patient.cfm", 11, "foo_Patient").message.should ==
48
+ "Case-insensitively resolved sample reference on line 11 from foo_Patient to /home/cfcode/apps/notis/foo/patient.cfm"
49
+ end
50
+ end
51
+ end
52
+
@@ -0,0 +1,62 @@
1
+ require File.expand_path('../spec_helper', File.dirname(__FILE__))
2
+
3
+ describe CaseCheck::Cfc do
4
+ before(:each) do
5
+ CaseCheck::Cfc.directories = %w(/tmp/cfc_specs/components)
6
+ @source = create_test_source('/tmp/cfc_specs/theapp/quux.cfm', <<-CFM)
7
+ <cfparam name="url.summaryType">
8
+ <cfparam name="url.patient_id">
9
+ <cfparam name="url.summaryId" default="0">
10
+
11
+ <cfscript>
12
+ utilsObj = CreateObject("component","bspore.Utils").init(datasource=application.personnel_db,username=session.netid,userIP=cgi.remote_addr);
13
+ summaryObj = createObject("component","bspore.Summary").init(datasource=application.db,username=session.netid,userIP=cgi.remote_addr);
14
+ </cfscript>
15
+ CFM
16
+ end
17
+
18
+ after(:each) do
19
+ FileUtils.rm_r '/tmp/cfc_specs'
20
+ end
21
+
22
+ def actual_search
23
+ CaseCheck::Cfc.search(@source)
24
+ end
25
+
26
+ it "has a human-readable name" do
27
+ actual_search.first.type_name.should == 'cfc'
28
+ end
29
+
30
+ it "finds multiple invocations" do
31
+ actual_search.should have(2).references
32
+ end
33
+
34
+ it "finds lower case createObject style" do
35
+ actual_search.last.expected_path.should == "bspore/Summary.cfc"
36
+ end
37
+
38
+ it "finds upper case CreateObject style" do
39
+ actual_search.first.expected_path.should == "bspore/Utils.cfc"
40
+ end
41
+
42
+ it "resolves against an exact match" do
43
+ expected_file = CaseCheck::Cfc.directories.last + "/bspore/Utils.cfc"
44
+ touch expected_file
45
+ actual_search.first.resolved_to.should == expected_file
46
+ actual_search.first.resolution.should == :exact
47
+ end
48
+
49
+ it "resolves against an all-lowercase match as exact" do
50
+ expected_file = CaseCheck::Cfc.directories.last + "/bspore/utils.cfc"
51
+ touch expected_file
52
+ actual_search.first.resolved_to.should == expected_file
53
+ actual_search.first.resolution.should == :exact
54
+ end
55
+
56
+ it "resolves against an differently cased version as inexact" do
57
+ expected_file = CaseCheck::Cfc.directories.last + "/BSpore/Utils.cfc"
58
+ touch expected_file
59
+ actual_search.first.resolved_to.should == expected_file
60
+ actual_search.first.resolution.should == :case_insensitive
61
+ end
62
+ end
@@ -0,0 +1,66 @@
1
+ require File.expand_path('../spec_helper', File.dirname(__FILE__))
2
+
3
+ describe CaseCheck::Cfinclude do
4
+ before(:each) do
5
+ @source = create_test_source("/tmp/cfinc_specs/theapp/quux.cfm", <<-CFM)
6
+ <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"
7
+ "http://www.w3.org/TR/REC-html40/loose.dtd">
8
+ <HTML>
9
+ <HEAD>
10
+ <TITLE>Pick Permissions Report Options</TITLE>
11
+ <META NAME="generator" CONTENT="BBEdit 5.1.1">
12
+
13
+ <CFPARAM NAME="Session.Output_Type" DEFAULT="Browser">
14
+
15
+ <cfinclude template="../header_plain.html">
16
+ <h1>Pick Permissions Report Options</h1>
17
+
18
+ CFM
19
+ end
20
+
21
+ after(:each) do
22
+ FileUtils.rm_r '/tmp/cfinc_specs'
23
+ end
24
+
25
+ def actual_search
26
+ CaseCheck::Cfinclude.search(@source)
27
+ end
28
+
29
+ it "has a human-readable name" do
30
+ actual_search.first.type_name.should == 'cfinclude'
31
+ end
32
+
33
+ it "uses the template path as the path" do
34
+ actual_search.first.expected_path.should == "../header_plain.html"
35
+ end
36
+
37
+ it "resolves against file directory" do
38
+ expected_file = "/tmp/cfinc_specs/header_plain.html"
39
+ touch expected_file
40
+ actual_search.first.resolved_to.should == expected_file
41
+ actual_search.first.resolution.should == :exact
42
+ end
43
+
44
+ it "resolves against file directory case-insensitively" do
45
+ expected_file = "/tmp/cfinc_specs/headER_plain.html"
46
+ touch expected_file
47
+ actual_search.first.resolved_to.should == expected_file
48
+ actual_search.first.resolution.should == :case_insensitive
49
+ end
50
+
51
+ it "finds multiple cfincludes" do
52
+ @source.content = <<-CFM
53
+ <cfinclude template="etc"/>
54
+ And then something else happened.
55
+ <cfinclude template="etal">
56
+ CFM
57
+ actual_search.should have(2).references
58
+ end
59
+
60
+ it "finds the cfinclude tag without regard to case" do
61
+ @source.content = <<-CFM
62
+ <CFInclude template="whatever">
63
+ CFM
64
+ actual_search.should have(1).reference
65
+ end
66
+ end