Skip to content

Commit fab2c45

Browse files
kylefdnkoutso
authored andcommitted
Introduce test_specification DSL
1 parent a4e2164 commit fab2c45

File tree

6 files changed

+138
-11
lines changed

6 files changed

+138
-11
lines changed

CHANGELOG.md

+4-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@
44

55
##### Enhancements
66

7-
* None.
7+
* Introduce `test_specification` DSL
8+
[Dimitris Koutsogiorgas](https://github.com/dnkoutso)
9+
[Kyle Fuller](https://github.com/kylef)
10+
[#369](https://github.com/CocoaPods/Core/pull/369)
811

912
##### Bug Fixes
1013

lib/cocoapods-core/specification.rb

+31-9
Original file line numberDiff line numberDiff line change
@@ -34,13 +34,18 @@ class Specification
3434
# @param [String] name
3535
# the name of the specification.
3636
#
37-
def initialize(parent = nil, name = nil)
37+
# @param [Bool] test_specification
38+
# Whether the specification is a test specification
39+
#
40+
def initialize(parent = nil, name = nil, test_specification = false)
3841
@attributes_hash = {}
3942
@subspecs = []
4043
@consumers = {}
4144
@parent = parent
4245
@hash_value = nil
46+
@test_specification = test_specification
4347
attributes_hash['name'] = name
48+
attributes_hash['test_type'] = :unit if test_specification
4449

4550
yield self if block_given?
4651
end
@@ -203,14 +208,32 @@ def subspec?
203208

204209
# @!group Dependencies & Subspecs
205210

206-
# @return [Array<Specifications>] the recursive list of all the subspecs of
211+
# @return [Bool] if the specification is a test specification
212+
def test_specification?
213+
@test_specification
214+
end
215+
216+
# @return [Symbol] the test type supported if this is a test specification
217+
def test_type
218+
attributes_hash['test_type']
219+
end
220+
221+
# @return [Array<Specification>] the list of all the test subspecs of
207222
# a specification.
208223
#
209-
def recursive_subspecs
224+
def test_specs
225+
subspecs.select(&:test_specification?)
226+
end
227+
228+
# @return [Array<Specification>] the recursive list of all the subspecs of
229+
# a specification.
230+
#
231+
def recursive_subspecs(include_test_specifications = false)
210232
mapper = lambda do |spec|
211233
spec.subspecs.map do |subspec|
234+
next if !include_test_specifications && subspec.test_specification?
212235
[subspec, *mapper.call(subspec)]
213-
end.flatten
236+
end.flatten.compact
214237
end
215238
mapper.call(self)
216239
end
@@ -241,7 +264,7 @@ def subspec_by_name(relative_name, raise_if_missing = true)
241264
else
242265
remainder = relative_name[base_name.size + 1..-1]
243266
subspec_name = remainder.split('/').shift
244-
subspec = subspecs.find { |s| s.base_name == subspec_name }
267+
subspec = subspecs.find { |s| s.base_name == subspec_name && !s.test_specification? }
245268
unless subspec
246269
if raise_if_missing
247270
raise Informative, 'Unable to find a specification named ' \
@@ -274,7 +297,7 @@ def default_subspecs
274297
#
275298
def subspec_dependencies(platform = nil)
276299
specs = if default_subspecs.empty?
277-
subspecs.compact
300+
subspecs.compact.reject(&:test_specification?)
278301
else
279302
default_subspecs.map do |subspec_name|
280303
root.subspec_by_name("#{name}/#{subspec_name}")
@@ -288,9 +311,8 @@ def subspec_dependencies(platform = nil)
288311

289312
# Returns the dependencies on other Pods or subspecs of other Pods.
290313
#
291-
# @param [Bool] all_platforms
292-
# whether the dependencies should be returned for all platforms
293-
# instead of the active one.
314+
# @param [Platform] platform
315+
# return only dependencies supported on the given platform.
294316
#
295317
# @note External dependencies are inherited by subspecs
296318
#

lib/cocoapods-core/specification/dsl.rb

+40
Original file line numberDiff line numberDiff line change
@@ -1324,6 +1324,46 @@ def subspec(name, &block)
13241324
subspec
13251325
end
13261326

1327+
# The names of the test types currently supported.
1328+
#
1329+
TEST_TYPES = [:unit].freeze
1330+
1331+
# The test type this specification supports. This only applies to test specifications.
1332+
#
1333+
# ---
1334+
#
1335+
# @example
1336+
#
1337+
# test_spec.test_type = :unit
1338+
#
1339+
# @param [Symbol] type
1340+
# The test type to use.
1341+
attribute :test_type,
1342+
:keys => TEST_TYPES,
1343+
:multi_platform => false
1344+
1345+
# Represents a test specification for the library. Here you can place all
1346+
# your tests for your podspec along with the test dependencies.
1347+
#
1348+
# ---
1349+
#
1350+
# @example
1351+
#
1352+
# Pod::Spec.new do |spec|
1353+
# spec.name = 'NSAttributedString+CCLFormat'
1354+
#
1355+
# spec.test_spec do |test_spec|
1356+
# test_spec.source_files = 'NSAttributedString+CCLFormatTests.m'
1357+
# test_spec.dependency 'Expecta'
1358+
# end
1359+
# end
1360+
#
1361+
def test_spec(name = 'Tests', &block)
1362+
subspec = Specification.new(self, name, true, &block)
1363+
@subspecs << subspec
1364+
subspec
1365+
end
1366+
13271367
#------------------#
13281368

13291369
# @!method default_subspecs=(subspec_array)

lib/cocoapods-core/specification/linter.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ def run_root_validation_hooks
128128
run_validation_hooks(attributes, spec)
129129
end
130130

131-
# Run validations for multi-platform attributes activating .
131+
# Run validations for multi-platform attributes activating.
132132
#
133133
# @return [void]
134134
#

spec/specification/dsl_spec.rb

+21
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,27 @@ module Pod
368368

369369
#-----------------------------------------------------------------------------#
370370

371+
describe 'Test specs' do
372+
before do
373+
@spec = Spec.new do |spec|
374+
spec.name = 'Spec'
375+
spec.test_spec do |test_spec|
376+
test_spec.test_type = :unit
377+
end
378+
end
379+
end
380+
381+
it 'allows you to specify a test spec' do
382+
test_spec = @spec.subspecs.first
383+
test_spec.class.should == Specification
384+
test_spec.name.should == 'Spec/Tests'
385+
test_spec.test_specification?.should == true
386+
test_spec.test_type.should == :unit
387+
end
388+
end
389+
390+
#-----------------------------------------------------------------------------#
391+
371392
describe 'Multi-Platform' do
372393
before do
373394
@spec = Spec.new do |s|

spec/specification_spec.rb

+41
Original file line numberDiff line numberDiff line change
@@ -217,23 +217,30 @@ module Pod
217217
s.name = 'Pod'
218218
s.subspec 'Subspec' do |_sp|
219219
end
220+
s.test_spec do |_tsp|
221+
end
220222
end
221223
@subspec = @spec.subspecs.first
224+
@test_subspec = @spec.test_specs.first
222225
end
223226

224227
it 'returns the root spec' do
225228
@spec.root.should == @spec
226229
@subspec.root.should == @spec
230+
@test_subspec.root.should == @spec
227231
end
228232

229233
it 'returns whether it is a root spec' do
230234
@spec.root?.should.be.true
231235
@subspec.root?.should.be.false
236+
@test_subspec.root?.should.be.false
232237
end
233238

234239
it 'returns whether it is a subspec' do
235240
@spec.subspec?.should.be.false
236241
@subspec.subspec?.should.be.true
242+
@test_subspec.subspec?.should.be.true
243+
@test_subspec.test_specification?.should.be.true
237244
end
238245
end
239246

@@ -268,11 +275,28 @@ module Pod
268275
@spec.recursive_subspecs.sort_by(&:name).should == [@subspec, @subsubspec, @subspec_osx, @subspec_ios]
269276
end
270277

278+
it 'returns the recursive subspecs including test subspecs' do
279+
@spec.test_spec {}
280+
test_spec = @spec.test_specs[0]
281+
@spec.recursive_subspecs(true).sort_by(&:name).should == [@subspec, @subsubspec, @subspec_osx, @subspec_ios, test_spec]
282+
end
283+
271284
it 'returns a subspec given the absolute name' do
272285
@spec.subspec_by_name('Pod/Subspec').should == @subspec
273286
@spec.subspec_by_name('Pod/Subspec/Subsubspec').should == @subsubspec
274287
end
275288

289+
it "doesn't return the test subspec given the Tests name" do
290+
@spec = Spec.new do |s|
291+
s.name = 'Pod'
292+
s.version = '1.0'
293+
s.dependency 'AFNetworking'
294+
s.osx.dependency 'MagicalRecord'
295+
s.test_spec {}
296+
end
297+
@spec.subspec_by_name('Pod/Tests', false).should. nil?
298+
end
299+
276300
it 'returns a subspec given the relative name' do
277301
@subspec.subspec_by_name('Subspec/Subsubspec').should == @subsubspec
278302
end
@@ -327,12 +351,29 @@ module Pod
327351
]
328352
end
329353

354+
it 'excludes the test subspec from the subspec dependencies' do
355+
@spec.test_spec {}
356+
@spec.subspec_dependencies.sort.should == [
357+
Dependency.new('Pod/Subspec', '1.0'),
358+
Dependency.new('Pod/SubspecOSX', '1.0'),
359+
Dependency.new('Pod/SubspeciOS', '1.0')]
360+
end
361+
330362
it 'returns all the dependencies' do
331363
@spec.dependencies.sort.should == [
332364
Dependency.new('AFNetworking'),
333365
Dependency.new('MagicalRecord')]
334366
end
335367

368+
it 'returns the test spec dependencies' do
369+
test_spec = @spec.test_spec { |s| s.dependency 'OCMock' }
370+
test_spec.dependencies.sort.should == [
371+
Dependency.new('AFNetworking'),
372+
Dependency.new('MagicalRecord'),
373+
Dependency.new('OCMock'),
374+
]
375+
end
376+
336377
it 'returns the dependencies given the platform' do
337378
@spec.dependencies(:ios).sort.should == [Dependency.new('AFNetworking')]
338379
end

0 commit comments

Comments
 (0)