Skip to content

Commit 7772fe9

Browse files
committed
Merge pull request #132 from kevincon/feature-coverage
Added test coverage for coveralls.
2 parents 4c26b7f + 4926cf6 commit 7772fe9

File tree

7 files changed

+163
-1
lines changed

7 files changed

+163
-1
lines changed

.coveralls.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
service_name: travis-ci

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,4 @@ crashlytics-build.properties
7070
### Tesseract and Leptonica ###
7171
leptonica-*
7272
tesseract-*
73+

.travis.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,10 @@ xcode_sdk:
44
- iphonesimulator7.0
55
- iphonesimulator8.1
66
xcode_scheme:
7-
- TestsProject
87
- Template Framework Project
8+
- TestsProject
9+
before_install:
10+
sudo pip install PyYAML; sudo pip install cpp-coveralls
11+
after_success:
12+
./scripts/coveralls.rb --extension m --extension mm --exclude-folder include --exclude-folder TestsProject
13+

Tesseract OCR iOS.xcodeproj/project.pbxproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -581,6 +581,8 @@
581581
COPY_PHASE_STRIP = NO;
582582
GCC_C_LANGUAGE_STANDARD = gnu99;
583583
GCC_DYNAMIC_NO_PIC = NO;
584+
GCC_GENERATE_TEST_COVERAGE_FILES = YES;
585+
GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES;
584586
GCC_OPTIMIZATION_LEVEL = 0;
585587
GCC_PREPROCESSOR_DEFINITIONS = (
586588
"DEBUG=1",

TestsProject/TestsProject.xcodeproj/project.pbxproj

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -416,6 +416,8 @@
416416
ENABLE_STRICT_OBJC_MSGSEND = YES;
417417
GCC_C_LANGUAGE_STANDARD = gnu99;
418418
GCC_DYNAMIC_NO_PIC = NO;
419+
GCC_GENERATE_TEST_COVERAGE_FILES = YES;
420+
GCC_INSTRUMENT_PROGRAM_FLOW_ARCS = YES;
419421
GCC_OPTIMIZATION_LEVEL = 0;
420422
GCC_PREPROCESSOR_DEFINITIONS = (
421423
"DEBUG=1",
@@ -458,6 +460,7 @@
458460
ENABLE_NS_ASSERTIONS = NO;
459461
ENABLE_STRICT_OBJC_MSGSEND = YES;
460462
GCC_C_LANGUAGE_STANDARD = gnu99;
463+
GCC_GENERATE_TEST_COVERAGE_FILES = NO;
461464
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
462465
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
463466
GCC_WARN_UNDECLARED_SELECTOR = YES;

TestsProject/TestsProject/AppDelegate.m

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,12 @@
1212

1313
@implementation AppDelegate
1414

15+
#ifdef DEBUG
16+
+ (void)load {
17+
[[NSUserDefaults standardUserDefaults] setValue:@"XCTestLog"
18+
forKey:@"XCTestObserverClass"];
19+
}
20+
#endif
1521

1622
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
1723
{
@@ -24,4 +30,12 @@ - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(
2430
return YES;
2531
}
2632

33+
- (void)applicationWillTerminate:(UIApplication *)application
34+
{
35+
#ifdef DEBUG
36+
extern void __gcov_flush(void);
37+
__gcov_flush();
38+
#endif
39+
}
40+
2741
@end

scripts/coveralls.rb

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
#!/usr/bin/env ruby
2+
3+
require 'etc'
4+
require 'fileutils'
5+
require 'find'
6+
require 'optparse'
7+
8+
# arraw of source subfolders to exclude
9+
excludedFolders = []
10+
extensionsToProcess = []
11+
coveralls_cmd = "cpp-coveralls"
12+
13+
excludeHeaders = false
14+
15+
# create option parser
16+
opts = OptionParser.new
17+
opts.banner = "Usage: coveralls.rb [options]"
18+
19+
opts.on('-e', '--exclude-folder FOLDER', 'Folder to exclude') do |v|
20+
excludedFolders << v
21+
coveralls_cmd.concat(" -e #{v}")
22+
end
23+
24+
opts.on('-h', '--exclude-headers', 'Ignores headers') do |v|
25+
excludeHeaders = true
26+
end
27+
28+
opts.on('-x', '--extension EXT', 'Source file extension to process') do |v|
29+
extensionsToProcess << v
30+
coveralls_cmd.concat(" -x #{v}")
31+
end
32+
33+
opts.on_tail("-?", "--help", "Show this message") do
34+
puts opts
35+
exit
36+
end
37+
38+
# parse the options
39+
begin
40+
opts.parse!(ARGV)
41+
rescue OptionParser::InvalidOption => e
42+
puts e
43+
puts opts
44+
exit(1)
45+
end
46+
47+
# the folders
48+
workingDir = Dir.getwd
49+
derivedDataDir = "#{Etc.getpwuid.dir}/Library/Developer/Xcode/DerivedData/"
50+
outputDir = workingDir + "/gcov"
51+
52+
# create gcov output folder
53+
FileUtils.mkdir outputDir
54+
55+
# pattern to get source file from first line of gcov file
56+
GCOV_SOURCE_PATTERN = Regexp.new(/Source:(.*)/)
57+
58+
# enumerate all gcda files underneath derivedData
59+
Find.find(derivedDataDir) do |gcda_file|
60+
61+
if gcda_file.match(/\.gcda\Z/)
62+
63+
#get just the folder name
64+
gcov_dir = File.dirname(gcda_file)
65+
66+
# cut off absolute working dir to get relative source path
67+
relative_input_path = gcda_file.slice(derivedDataDir.length, gcda_file.length)
68+
puts "\nINPUT: #{relative_input_path}"
69+
70+
#process the file
71+
result = %x( gcov '#{gcda_file}' -o '#{gcov_dir}' )
72+
73+
# filter the resulting output
74+
Dir.glob("*.gcov") do |gcov_file|
75+
76+
firstLine = File.open(gcov_file).readline
77+
match = GCOV_SOURCE_PATTERN.match(firstLine)
78+
79+
if (match)
80+
81+
source_path = match[1]
82+
83+
puts "source: #{source_path} - #{workingDir}"
84+
85+
if (source_path.start_with? workingDir)
86+
87+
# cut off absolute working dir to get relative source path
88+
relative_path = source_path.slice(workingDir.length+1, source_path.length)
89+
90+
extension = File.extname(relative_path)
91+
extension = extension.slice(1, extension.length-1)
92+
93+
puts "#{extension}"
94+
95+
# get the path components
96+
path_comps = relative_path.split(File::SEPARATOR)
97+
98+
shouldProcess = false
99+
exclusionMsg =""
100+
101+
if (excludedFolders.include?(path_comps[0]))
102+
exclusionMsg = "excluded via option"
103+
else
104+
if (excludeHeaders == true && extension == 'h')
105+
exclusionMsg = "excluded header"
106+
else
107+
if (extensionsToProcess.count == 0 || extensionsToProcess.include?(extension))
108+
shouldProcess = true
109+
else
110+
exclusionMsg = "excluded extension"
111+
shouldProcess = false
112+
end
113+
end
114+
end
115+
116+
if (shouldProcess)
117+
puts " - process: #{relative_path}"
118+
FileUtils.mv(gcov_file, outputDir)
119+
else
120+
puts " - ignore: #{relative_path} (#{exclusionMsg})"
121+
FileUtils.rm gcov_file
122+
end
123+
else
124+
puts " - ignore: #{gcov_file} (outside source folder)"
125+
FileUtils.rm gcov_file
126+
end
127+
end
128+
end
129+
end
130+
end
131+
132+
#call the coveralls, exclude some files
133+
system coveralls_cmd
134+
135+
#clean up
136+
FileUtils.rm_rf outputDir

0 commit comments

Comments
 (0)