buildr-iidea 0.0.2
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.
- data/LICENSE +176 -0
- data/NOTICE +16 -0
- data/README.rdoc +286 -0
- data/Rakefile +27 -0
- data/buildr-iidea.gemspec +23 -0
- data/lib/buildr/intellij_idea/idea_file.rb +86 -0
- data/lib/buildr/intellij_idea/idea_module.rb +217 -0
- data/lib/buildr/intellij_idea/idea_project.rb +98 -0
- data/lib/buildr/intellij_idea/project_extension.rb +92 -0
- data/lib/buildr_iidea.rb +5 -0
- data/spec/buildr/intellij_idea/clean_spec.rb +38 -0
- data/spec/buildr/intellij_idea/dependency_spec.rb +85 -0
- data/spec/buildr/intellij_idea/extra_modules_spec.rb +24 -0
- data/spec/buildr/intellij_idea/facet_generation_spec.rb +36 -0
- data/spec/buildr/intellij_idea/group_spec.rb +33 -0
- data/spec/buildr/intellij_idea/idea_file_generation_spec.rb +177 -0
- data/spec/buildr/intellij_idea/inform_spec.rb +28 -0
- data/spec/buildr/intellij_idea/initial_components_spec.rb +33 -0
- data/spec/buildr/intellij_idea/module_property_inheritance_spec.rb +27 -0
- data/spec/buildr/intellij_idea/project_extension_spec.rb +19 -0
- data/spec/buildr/intellij_idea/template_spec.rb +234 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +75 -0
- data/spec/xpath_matchers.rb +109 -0
- metadata +97 -0
@@ -0,0 +1,28 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "iidea:generate" do
|
4
|
+
describe "with a single project definition" do
|
5
|
+
before do
|
6
|
+
@foo = define "foo"
|
7
|
+
end
|
8
|
+
|
9
|
+
it "informs the user about generating IPR" do
|
10
|
+
lambda { invoke_generate_task }.should show_info(/Writing (.+)\/foo\.ipr/)
|
11
|
+
end
|
12
|
+
|
13
|
+
it "informs the user about generating IML" do
|
14
|
+
lambda { invoke_generate_task }.should show_info(/Writing (.+)\/foo\.iml/)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
describe "with a subproject" do
|
18
|
+
before do
|
19
|
+
@foo = define "foo" do
|
20
|
+
define 'bar'
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
it "informs the user about generating subporoject IML" do
|
25
|
+
lambda { invoke_generate_task }.should show_info(/Writing (.+)\/bar\/bar\.iml/)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "iidea:generate" do
|
4
|
+
describe "with compile.options.source = '1.6'" do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@foo = define "foo" do
|
8
|
+
compile.options.source = '1.5'
|
9
|
+
end
|
10
|
+
invoke_generate_task
|
11
|
+
end
|
12
|
+
|
13
|
+
it "generate an ProjectRootManager with 1.5 jdk specified" do
|
14
|
+
#raise File.read(@foo._("foo.ipr"))
|
15
|
+
xml_document(@foo._("foo.ipr")).
|
16
|
+
should have_xpath("/project/component[@name='ProjectRootManager' and @project-jdk-name = '1.5' and @languageLevel = 'JDK_1_5']")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe "with compile.options.source = '1.6'" do
|
21
|
+
before do
|
22
|
+
@foo = define "foo" do
|
23
|
+
compile.options.source = '1.6'
|
24
|
+
end
|
25
|
+
invoke_generate_task
|
26
|
+
end
|
27
|
+
|
28
|
+
it "generate an ProjectRootManager with 1.6 jdk specified" do
|
29
|
+
xml_document(@foo._("foo.ipr")).
|
30
|
+
should have_xpath("/project/component[@name='ProjectRootManager' and @project-jdk-name = '1.6' and @languageLevel = 'JDK_1_6']")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "Buildr::IntellijIdea::IdeaModule" do
|
4
|
+
describe "settings inherited in subprojects" do
|
5
|
+
before do
|
6
|
+
mkdir_p 'bar'
|
7
|
+
@foo = define "foo" do
|
8
|
+
iml.type = "FOO_MODULE_TYPE"
|
9
|
+
define 'bar'
|
10
|
+
end
|
11
|
+
invoke_generate_task
|
12
|
+
end
|
13
|
+
|
14
|
+
it "generates root IML with specified type" do
|
15
|
+
module_file = root_module_filename(@foo)
|
16
|
+
File.should be_exist(module_file)
|
17
|
+
File.read(module_file).should =~ /FOO_MODULE_TYPE/
|
18
|
+
end
|
19
|
+
|
20
|
+
it "generates subproject IML with inherited type" do
|
21
|
+
module_file = subproject_module_filename(@foo, "bar")
|
22
|
+
File.should be_exist(module_file)
|
23
|
+
File.read(module_file).should =~ /FOO_MODULE_TYPE/
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
describe "project extension" do
|
4
|
+
it "provides an 'iidea:generate' task" do
|
5
|
+
Rake::Task.tasks.detect{|task| task.to_s == "iidea:generate"}.should_not be_nil
|
6
|
+
end
|
7
|
+
|
8
|
+
it "documents the 'iidea:generate' task" do
|
9
|
+
Rake::Task.tasks.detect{|task| task.to_s == "iidea:generate"}.comment.should_not be_nil
|
10
|
+
end
|
11
|
+
|
12
|
+
it "provides an 'iidea:clean' task" do
|
13
|
+
Rake::Task.tasks.detect{|task| task.to_s == "iidea:clean"}.should_not be_nil
|
14
|
+
end
|
15
|
+
|
16
|
+
it "documents the 'iidea:clean' task" do
|
17
|
+
Rake::Task.tasks.detect{|task| task.to_s == "iidea:clean"}.comment.should_not be_nil
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,234 @@
|
|
1
|
+
require File.expand_path('../../../spec_helper', __FILE__)
|
2
|
+
|
3
|
+
IPR_TEMPLATE_NAME = "project.template.iml"
|
4
|
+
|
5
|
+
IPR_TEMPLATE = <<PROJECT_XML
|
6
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
7
|
+
<project version="4">
|
8
|
+
<component name="SvnBranchConfigurationManager">
|
9
|
+
<option name="mySupportsUserInfoFilter" value="false" />
|
10
|
+
</component>
|
11
|
+
</project>
|
12
|
+
PROJECT_XML
|
13
|
+
|
14
|
+
IPR_EXISTING = <<PROJECT_XML
|
15
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
16
|
+
<project version="4">
|
17
|
+
<component name="AntConfiguration">
|
18
|
+
<defaultAnt bundledAnt="true" />
|
19
|
+
</component>
|
20
|
+
<component name="SvnBranchConfigurationManager">
|
21
|
+
<option name="mySupportsUserInfoFilter" value="true" />
|
22
|
+
</component>
|
23
|
+
<component name="ProjectModuleManager">
|
24
|
+
<modules>
|
25
|
+
<module fileurl="file://$PROJECT_DIR$/existing.iml" filepath="$PROJECT_DIR$/existing.iml" />
|
26
|
+
</modules>
|
27
|
+
</component>
|
28
|
+
</project>
|
29
|
+
PROJECT_XML
|
30
|
+
|
31
|
+
IPR_FROM_TEMPLATE_XPATH = <<XPATH
|
32
|
+
/project/component[@name='SvnBranchConfigurationManager']/option[@name = 'mySupportsUserInfoFilter' and @value = 'false']
|
33
|
+
XPATH
|
34
|
+
|
35
|
+
IPR_FROM_EXISTING_XPATH = <<XPATH
|
36
|
+
/project/component[@name='AntConfiguration']
|
37
|
+
XPATH
|
38
|
+
|
39
|
+
IPR_FROM_EXISTING_SHADOWING_TEMPLATE_XPATH = <<XPATH
|
40
|
+
/project/component[@name='SvnBranchConfigurationManager']/option[@name = 'mySupportsUserInfoFilter' and @value = 'true']
|
41
|
+
XPATH
|
42
|
+
|
43
|
+
IPR_FROM_EXISTING_SHADOWING_GENERATED_XPATH = <<XPATH
|
44
|
+
/project/component[@name='ProjectModuleManager']/modules/module[@fileurl = 'file://$PROJECT_DIR$/existing.iml']
|
45
|
+
XPATH
|
46
|
+
|
47
|
+
IPR_FROM_GENERATED_XPATH = <<XPATH
|
48
|
+
/project/component[@name='ProjectModuleManager']/modules/module[@fileurl = 'file://$PROJECT_DIR$/foo.iml']
|
49
|
+
XPATH
|
50
|
+
|
51
|
+
IML_TEMPLATE_NAME = "module.template.iml"
|
52
|
+
|
53
|
+
IML_TEMPLATE = <<PROJECT_XML
|
54
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
55
|
+
<module type="JAVA_MODULE" version="4">
|
56
|
+
<component name="FacetManager">
|
57
|
+
<facet type="JRUBY" name="JRuby">
|
58
|
+
<configuration number="0">
|
59
|
+
<JRUBY_FACET_CONFIG_ID NAME="JRUBY_SDK_NAME" VALUE="JRuby SDK 1.4.0RC1" />
|
60
|
+
</configuration>
|
61
|
+
</facet>
|
62
|
+
</component>
|
63
|
+
</module>
|
64
|
+
PROJECT_XML
|
65
|
+
|
66
|
+
IML_EXISTING = <<PROJECT_XML
|
67
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
68
|
+
<module type="JAVA_MODULE" version="4">
|
69
|
+
<component name="FunkyPlugin"/>
|
70
|
+
<component name="FacetManager">
|
71
|
+
<facet type="SCALA" name="Scala"/>
|
72
|
+
</component>
|
73
|
+
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
74
|
+
<exclude-output />
|
75
|
+
<content url="file://$MODULE_DIR$"/>
|
76
|
+
<orderEntry type="inheritedJdk" />
|
77
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
78
|
+
<orderEntry type="module" module-name="buildr-bnd" exported="" />
|
79
|
+
</component>
|
80
|
+
</module>
|
81
|
+
PROJECT_XML
|
82
|
+
|
83
|
+
IML_FROM_TEMPLATE_XPATH = <<XPATH
|
84
|
+
/module/component[@name='FacetManager']/facet[@type = 'JRUBY']
|
85
|
+
XPATH
|
86
|
+
|
87
|
+
IML_FROM_EXISTING_XPATH = <<XPATH
|
88
|
+
/module/component[@name='FunkyPlugin']
|
89
|
+
XPATH
|
90
|
+
|
91
|
+
IML_FROM_EXISTING_SHADOWING_TEMPLATE_XPATH = <<XPATH
|
92
|
+
/module/component[@name='FacetManager']/facet[@type = 'SCALA']
|
93
|
+
XPATH
|
94
|
+
|
95
|
+
IML_FROM_EXISTING_SHADOWING_GENERATED_XPATH = <<XPATH
|
96
|
+
/module/component[@name='NewModuleRootManager']/orderEntry[@module-name = 'buildr-bnd']
|
97
|
+
XPATH
|
98
|
+
|
99
|
+
IML_FROM_GENERATED_XPATH = <<XPATH
|
100
|
+
/module/component[@name='NewModuleRootManager']/orderEntry[@type = 'module-library']
|
101
|
+
XPATH
|
102
|
+
|
103
|
+
describe "iidea:generate" do
|
104
|
+
|
105
|
+
describe "with existing project files" do
|
106
|
+
before do
|
107
|
+
write "foo.ipr", IPR_EXISTING
|
108
|
+
write "foo.iml", IML_EXISTING
|
109
|
+
artifact('group:id:jar:1.0') { |t| write t.to_s }
|
110
|
+
@foo = define "foo" do
|
111
|
+
ipr.template = nil
|
112
|
+
iml.template = nil
|
113
|
+
compile.with 'group:id:jar:1.0'
|
114
|
+
end
|
115
|
+
invoke_generate_task
|
116
|
+
end
|
117
|
+
|
118
|
+
it "replaces ProjectModuleManager component in existing ipr file" do
|
119
|
+
xml_document(@foo._("foo.ipr")).should have_xpath(IPR_FROM_GENERATED_XPATH)
|
120
|
+
xml_document(@foo._("foo.ipr")).should_not have_xpath(IPR_FROM_EXISTING_SHADOWING_GENERATED_XPATH)
|
121
|
+
end
|
122
|
+
|
123
|
+
it "merges component in existing ipr file" do
|
124
|
+
xml_document(@foo._("foo.ipr")).should have_xpath(IPR_FROM_EXISTING_XPATH)
|
125
|
+
end
|
126
|
+
|
127
|
+
it "replaces NewModuleRootManager component in existing iml file" do
|
128
|
+
xml_document(@foo._("foo.iml")).should have_xpath(IML_FROM_GENERATED_XPATH)
|
129
|
+
xml_document(@foo._("foo.iml")).should_not have_xpath(IML_FROM_EXISTING_SHADOWING_GENERATED_XPATH)
|
130
|
+
end
|
131
|
+
|
132
|
+
it "merges component in existing iml file" do
|
133
|
+
xml_document(@foo._("foo.iml")).should have_xpath(IML_FROM_EXISTING_XPATH)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
describe "with an iml template" do
|
138
|
+
before do
|
139
|
+
write IML_TEMPLATE_NAME, IML_TEMPLATE
|
140
|
+
artifact('group:id:jar:1.0') { |t| write t.to_s }
|
141
|
+
@foo = define "foo" do
|
142
|
+
ipr.template = nil
|
143
|
+
iml.template = IML_TEMPLATE_NAME
|
144
|
+
compile.with 'group:id:jar:1.0'
|
145
|
+
end
|
146
|
+
invoke_generate_task
|
147
|
+
end
|
148
|
+
|
149
|
+
it "replaces generated components" do
|
150
|
+
xml_document(@foo._("foo.iml")).should have_xpath(IML_FROM_GENERATED_XPATH)
|
151
|
+
end
|
152
|
+
|
153
|
+
it "merges component in iml template" do
|
154
|
+
xml_document(@foo._("foo.iml")).should have_xpath(IML_FROM_TEMPLATE_XPATH)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
describe "with an iml template and existing iml" do
|
159
|
+
before do
|
160
|
+
write IML_TEMPLATE_NAME, IML_TEMPLATE
|
161
|
+
write "foo.iml", IML_EXISTING
|
162
|
+
artifact('group:id:jar:1.0') { |t| write t.to_s }
|
163
|
+
@foo = define "foo" do
|
164
|
+
ipr.template = nil
|
165
|
+
iml.template = IML_TEMPLATE_NAME
|
166
|
+
compile.with 'group:id:jar:1.0'
|
167
|
+
end
|
168
|
+
invoke_generate_task
|
169
|
+
end
|
170
|
+
|
171
|
+
it "replaces generated components" do
|
172
|
+
xml_document(@foo._("foo.iml")).should have_xpath(IML_FROM_GENERATED_XPATH)
|
173
|
+
end
|
174
|
+
|
175
|
+
it "merges component in iml template" do
|
176
|
+
xml_document(@foo._("foo.iml")).should have_xpath(IML_FROM_TEMPLATE_XPATH)
|
177
|
+
end
|
178
|
+
|
179
|
+
it "merges components not in iml template and not generated by task" do
|
180
|
+
xml_document(@foo._("foo.iml")).should have_xpath(IML_FROM_EXISTING_XPATH)
|
181
|
+
xml_document(@foo._("foo.iml")).should_not have_xpath(IML_FROM_EXISTING_SHADOWING_TEMPLATE_XPATH)
|
182
|
+
xml_document(@foo._("foo.iml")).should_not have_xpath(IML_FROM_EXISTING_SHADOWING_GENERATED_XPATH)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
describe "with an ipr template" do
|
187
|
+
before do
|
188
|
+
write IPR_TEMPLATE_NAME, IPR_TEMPLATE
|
189
|
+
artifact('group:id:jar:1.0') { |t| write t.to_s }
|
190
|
+
@foo = define "foo" do
|
191
|
+
ipr.template = IPR_TEMPLATE_NAME
|
192
|
+
iml.template = nil
|
193
|
+
compile.with 'group:id:jar:1.0'
|
194
|
+
end
|
195
|
+
invoke_generate_task
|
196
|
+
end
|
197
|
+
|
198
|
+
it "replaces generated component in ipr template" do
|
199
|
+
xml_document(@foo._("foo.ipr")).should have_xpath(IPR_FROM_GENERATED_XPATH)
|
200
|
+
end
|
201
|
+
|
202
|
+
it "merges component in ipr template" do
|
203
|
+
xml_document(@foo._("foo.ipr")).should have_xpath(IPR_FROM_TEMPLATE_XPATH)
|
204
|
+
end
|
205
|
+
end
|
206
|
+
|
207
|
+
describe "with an ipr template and existing ipr" do
|
208
|
+
before do
|
209
|
+
write IPR_TEMPLATE_NAME, IPR_TEMPLATE
|
210
|
+
write "foo.ipr", IPR_EXISTING
|
211
|
+
artifact('group:id:jar:1.0') { |t| write t.to_s }
|
212
|
+
@foo = define "foo" do
|
213
|
+
ipr.template = IPR_TEMPLATE_NAME
|
214
|
+
iml.template = nil
|
215
|
+
compile.with 'group:id:jar:1.0'
|
216
|
+
end
|
217
|
+
invoke_generate_task
|
218
|
+
end
|
219
|
+
|
220
|
+
it "replaces generated component in ipr template" do
|
221
|
+
xml_document(@foo._("foo.ipr")).should have_xpath(IPR_FROM_GENERATED_XPATH)
|
222
|
+
end
|
223
|
+
|
224
|
+
it "merges component in ipr template" do
|
225
|
+
xml_document(@foo._("foo.ipr")).should have_xpath(IPR_FROM_TEMPLATE_XPATH)
|
226
|
+
end
|
227
|
+
|
228
|
+
it "merges components not in ipr template and not generated by task" do
|
229
|
+
xml_document(@foo._("foo.ipr")).should have_xpath(IPR_FROM_EXISTING_XPATH)
|
230
|
+
xml_document(@foo._("foo.ipr")).should_not have_xpath(IPR_FROM_EXISTING_SHADOWING_GENERATED_XPATH)
|
231
|
+
xml_document(@foo._("foo.ipr")).should_not have_xpath(IPR_FROM_EXISTING_SHADOWING_TEMPLATE_XPATH)
|
232
|
+
end
|
233
|
+
end
|
234
|
+
end
|
data/spec/spec.opts
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require 'spec'
|
2
|
+
require File.expand_path(File.dirname(__FILE__) + '/xpath_matchers.rb')
|
3
|
+
|
4
|
+
DEFAULT_BUILDR_DIR=File.expand_path(File.dirname(__FILE__) + '/../../buildr')
|
5
|
+
BUILDR_DIR=ENV['BUILDR_DIR'] || DEFAULT_BUILDR_DIR
|
6
|
+
|
7
|
+
unless File.exist?("#{BUILDR_DIR}/buildr.gemspec")
|
8
|
+
raise "Unable to find buildr.gemspec in #{BUILDR_DIR == DEFAULT_BUILDR_DIR ? 'guessed' : 'specified'} $BUILD_DIR (#{BUILDR_DIR})"
|
9
|
+
end
|
10
|
+
|
11
|
+
require 'rubygems'
|
12
|
+
|
13
|
+
# For testing we use the gem requirements specified on the buildr.gemspec
|
14
|
+
Gem::Specification.load(File.expand_path("#{BUILDR_DIR}/buildr.gemspec", File.dirname(__FILE__))).
|
15
|
+
dependencies.each { |dep| gem dep.name, dep.requirement.to_s }
|
16
|
+
|
17
|
+
|
18
|
+
# hook into buildr's spec_helpers load process
|
19
|
+
unless defined?(SpecHelpers)
|
20
|
+
module SandboxHook
|
21
|
+
def SandboxHook.included(spec_helpers)
|
22
|
+
$LOAD_PATH.unshift(File.dirname(__FILE__))
|
23
|
+
$LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
|
24
|
+
require 'buildr_iidea'
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
require "#{BUILDR_DIR}/spec/spec_helpers.rb"
|
29
|
+
|
30
|
+
module SpecHelpers
|
31
|
+
|
32
|
+
def invoke_generate_task
|
33
|
+
task('iidea:generate').invoke
|
34
|
+
end
|
35
|
+
|
36
|
+
def invoke_clean_task
|
37
|
+
task('iidea:clean').invoke
|
38
|
+
end
|
39
|
+
|
40
|
+
def root_project_filename(project)
|
41
|
+
project._("#{project.name}#{Buildr::IntellijIdea::IdeaFile::DEFAULT_SUFFIX}.ipr")
|
42
|
+
end
|
43
|
+
|
44
|
+
def root_project_xml(project)
|
45
|
+
xml_document(root_project_filename(project))
|
46
|
+
end
|
47
|
+
|
48
|
+
def root_module_filename(project)
|
49
|
+
project._("#{project.name}#{Buildr::IntellijIdea::IdeaFile::DEFAULT_SUFFIX}.iml")
|
50
|
+
end
|
51
|
+
|
52
|
+
def root_module_xml(project)
|
53
|
+
xml_document(root_module_filename(project))
|
54
|
+
end
|
55
|
+
|
56
|
+
def subproject_module_filename(project, sub_project_name)
|
57
|
+
project._("#{sub_project_name}/#{sub_project_name}#{Buildr::IntellijIdea::IdeaFile::DEFAULT_SUFFIX}.iml")
|
58
|
+
end
|
59
|
+
|
60
|
+
def subproject_module_xml(project, sub_project_name)
|
61
|
+
xml_document(subproject_module_filename(project, sub_project_name))
|
62
|
+
end
|
63
|
+
|
64
|
+
def xml_document(filename)
|
65
|
+
File.should be_exist(filename)
|
66
|
+
REXML::Document.new(File.read(filename))
|
67
|
+
end
|
68
|
+
|
69
|
+
def xpath_to_module
|
70
|
+
"/project/component[@name='ProjectModuleManager']/modules/module"
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|
@@ -0,0 +1,109 @@
|
|
1
|
+
# Note: That this helper has been derived from examples on the web and in particular
|
2
|
+
# the example at http://blog.wolfman.com/articles/2008/1/2/xpath-matchers-for-rspec
|
3
|
+
|
4
|
+
require 'rexml/document'
|
5
|
+
require 'rexml/element'
|
6
|
+
|
7
|
+
module Spec
|
8
|
+
module Matchers
|
9
|
+
|
10
|
+
# check if the xpath exists one or more times
|
11
|
+
class HaveXpath
|
12
|
+
def initialize(xpath)
|
13
|
+
@xpath = xpath
|
14
|
+
end
|
15
|
+
|
16
|
+
def matches?(response)
|
17
|
+
@response = response
|
18
|
+
doc = response.is_a?(REXML::Document) ? response : REXML::Document.new(@response)
|
19
|
+
match = REXML::XPath.match(doc, @xpath)
|
20
|
+
not match.empty?
|
21
|
+
end
|
22
|
+
|
23
|
+
def failure_message
|
24
|
+
"Did not find expected xpath #{@xpath}"
|
25
|
+
end
|
26
|
+
|
27
|
+
def negative_failure_message
|
28
|
+
"Did find unexpected xpath #{@xpath}"
|
29
|
+
end
|
30
|
+
|
31
|
+
def description
|
32
|
+
"match the xpath expression #{@xpath}"
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
def have_xpath(xpath)
|
37
|
+
HaveXpath.new(xpath)
|
38
|
+
end
|
39
|
+
|
40
|
+
# check if the xpath has the specified value
|
41
|
+
# value is a string and there must be a single result to match its
|
42
|
+
# equality against
|
43
|
+
class MatchXpath
|
44
|
+
def initialize(xpath, val)
|
45
|
+
@xpath = xpath
|
46
|
+
@val= val
|
47
|
+
end
|
48
|
+
|
49
|
+
def matches?(response)
|
50
|
+
@response = response
|
51
|
+
doc = response.is_a?(REXML::Document) ? response : REXML::Document.new(@response)
|
52
|
+
ok = true
|
53
|
+
REXML::XPath.each(doc, @xpath) do |e|
|
54
|
+
@actual_val = case e
|
55
|
+
when REXML::Attribute
|
56
|
+
e.to_s
|
57
|
+
when REXML::Element
|
58
|
+
e.text
|
59
|
+
else
|
60
|
+
e.to_s
|
61
|
+
end
|
62
|
+
return false unless @val == @actual_val
|
63
|
+
end
|
64
|
+
return ok
|
65
|
+
end
|
66
|
+
|
67
|
+
def failure_message
|
68
|
+
"The xpath #{@xpath} did not have the value '#{@val}' It was '#{@actual_val}'"
|
69
|
+
end
|
70
|
+
|
71
|
+
def description
|
72
|
+
"match the xpath expression #{@xpath} with #{@val}"
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
def match_xpath(xpath, val)
|
77
|
+
MatchXpath.new(xpath, val)
|
78
|
+
end
|
79
|
+
|
80
|
+
# checks if the given xpath occurs num times
|
81
|
+
class HaveNodes #:nodoc:
|
82
|
+
def initialize(xpath, num)
|
83
|
+
@xpath= xpath
|
84
|
+
@num = num
|
85
|
+
end
|
86
|
+
|
87
|
+
def matches?(response)
|
88
|
+
@response = response
|
89
|
+
doc = response.is_a?(REXML::Document) ? response : REXML::Document.new(@response)
|
90
|
+
match = REXML::XPath.match(doc, @xpath)
|
91
|
+
@num_found= match.size
|
92
|
+
@num_found == @num
|
93
|
+
end
|
94
|
+
|
95
|
+
def failure_message
|
96
|
+
"Did not find expected number of nodes #{@num} in xpath #{@xpath} Found #{@num_found}"
|
97
|
+
end
|
98
|
+
|
99
|
+
def description
|
100
|
+
"match the number of nodes #{@num}"
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def have_nodes(xpath, num)
|
105
|
+
HaveNodes.new(xpath, num)
|
106
|
+
end
|
107
|
+
|
108
|
+
end
|
109
|
+
end
|