Skip to content

Commit 962733b

Browse files
committed
Add tests and corresponding continuous integration
Many tests are still marked as broken. The test/testtags file contains the desired tags to obtain. Some need only a little work, some need a more complete parser than the current argument-regex-based approach. We could possibly use the master of Universal Ctags for MacOS but that would introduce another error surface.
1 parent faddf5b commit 962733b

File tree

7 files changed

+199
-0
lines changed

7 files changed

+199
-0
lines changed

.travis.yml

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
# Documentation: http://docs.travis-ci.com/user/languages/julia/
2+
language: julia
3+
os:
4+
- linux
5+
- osx
6+
julia:
7+
- 1.0
8+
- 1.1
9+
- 1.2
10+
- nightly
11+
before_install:
12+
- if [ $TRAVIS_OS_NAME = linux ]; then sudo apt-get install -y universal-ctags || sudo apt-get install -y exuberant-ctags || sudo apt-get install -y ctags; fi
13+
# If we want the Universal Ctags master. No tagged releases yet.
14+
# - if [ $TRAVIS_OS_NAME = osx ]; then brew tap universal-ctags/universal-ctags && brew install --HEAD universal-ctags; fi
15+
- if [ $TRAVIS_OS_NAME = osx ]; then brew install ctags; fi
16+
matrix:
17+
allow_failures:
18+
- julia: nightly
19+
notifications:
20+
email: false

Project.toml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
name = "julia-ctags"
2+
uuid = "106e64ca-b22d-11e9-257b-81adddf2616c"
3+
4+
[extras]
5+
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
6+
7+
[targets]
8+
test = ["Test"]

src/julia-ctags.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# We need this file so this is recognized as a testable project...
2+

test/runtests.jl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using Test
2+
3+
include("test_tags.jl")
4+
5+
function main()
6+
outputs = trygeneratetags(testfilepath)
7+
targets = gettargettags(testtagspath)
8+
# println("targets: ", targets)
9+
# println("outputs: ", outputs)
10+
testtags(targets, outputs)
11+
end
12+
13+
main()
14+

test/test_tags.jl

Lines changed: 129 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
"Tags starting with this identifier are broken. Remove upon fix."
2+
const brokenidentifiers = (
3+
"deprecated_returnsquarepower",
4+
"deprecated_squarepower",
5+
"DocTestSetup",
6+
"printgreeting",
7+
"returnsquarepower",
8+
)
9+
"Kinds that have not been added yet (and are therefore broken). Remove upon fix."
10+
const brokenkinds = ('m', 's')
11+
12+
"Path to Ctags configuration file (the parser)."
13+
const ctagsconfigpath = joinpath(@__DIR__, "..", "ctags")
14+
"Test file to generate the tags from."
15+
const testfilepath = joinpath(@__DIR__, "testfile.jl")
16+
"File containing test tags to compare against."
17+
const testtagspath = joinpath(@__DIR__, "testtags")
18+
19+
"Ctags binaries to sequentially try to call if one is not found."
20+
const ctagsbins = (
21+
"uctags",
22+
"ectags",
23+
"universal-ctags",
24+
"exuberant-ctags",
25+
"u-ctags",
26+
"e-ctags",
27+
)
28+
"Arguments to pass to a Ctags binary."
29+
const ctagsargs = (
30+
"--options=$ctagsconfigpath", # Include our tags file.
31+
"-f -" # Write to stdout.
32+
)
33+
34+
35+
"Utility function to convert an `AbstractVector` of tags to a common format."
36+
function converttags(tags::AbstractVector)
37+
tags = filter(s -> !isempty(s) && s[1] != '!', tags)
38+
Set(tags)
39+
end
40+
41+
"Return tags generatad from the given file and convert them using [`converttags`](@ref)."
42+
function generatetags(testfile::AbstractString, ctagsbin::AbstractString="ctags")
43+
ctagscmd = `$ctagsbin $ctagsargs $testfile`
44+
tags = open(ctagscmd, "r", stdout) do io
45+
readlines(io)
46+
end
47+
return converttags(tags)
48+
end
49+
50+
function trygeneratetags(testfile::AbstractString)
51+
local tags
52+
try
53+
tags = generatetags(testfile, ctagsbins[1])
54+
catch LoadError
55+
success = false
56+
ctagsbinindex = 2
57+
58+
while !success
59+
try
60+
tags = generatetags(testfile, ctagsbins[ctagsbinindex])
61+
success = true
62+
catch LoadError
63+
ctagsbinindex += 1
64+
end
65+
end
66+
end
67+
return tags
68+
end
69+
70+
"""
71+
Return tags to compare against.
72+
The desired output of the Ctags program applied to [`testfilepath`](@ref).
73+
"""
74+
function gettargettags(testtags::AbstractString)
75+
tags = readlines(testtags)
76+
converttags(tags)
77+
end
78+
79+
80+
"Return the path listed in the output tags."
81+
function getpath(outputs)
82+
refoutput = pop!(outputs)
83+
push!(outputs, refoutput)
84+
path = split(refoutput, '\t')[2]
85+
end
86+
87+
"Return whether the given tag should be evaluated using [`test_broken`](@ref)."
88+
function isbroken(target)
89+
columns = split(target, '\t')
90+
return columns[1] in brokenidentifiers || columns[4][1] in brokenkinds
91+
end
92+
93+
"Replace the path listed in the given tag with the given path."
94+
function replacepath(tag, path)
95+
arraytag = split(tag, '\t')
96+
arraytag[2] = path
97+
return join(arraytag, '\t')
98+
end
99+
100+
101+
"""
102+
Test whether the given target is in the given outputs.
103+
The target's listed path is replaced with `outputpath` to ensure static tests.
104+
"""
105+
function test_target_in_outputs(target, outputs, outputpath)
106+
target = replacepath(target, outputpath)
107+
target_in_outputs = target in outputs
108+
109+
if isbroken(target)
110+
println("testing broken tag: ", target)
111+
result = @test_broken target_in_outputs
112+
else
113+
println("testing tag: ", target)
114+
result = @test target_in_outputs
115+
end
116+
target_in_outputs && delete!(outputs, target)
117+
end
118+
119+
"Test the two given tags against each other."
120+
function testtags(targets, outputs)
121+
outputpath = getpath(outputs)
122+
@testset "Tags" begin
123+
for target in targets
124+
test_target_in_outputs(target, outputs, outputpath)
125+
end
126+
@test_broken isempty(outputs)
127+
end
128+
end
129+
File renamed without changes.

test/testtags

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
! A test file for ctags support. Manually written, do not overwrite.
2+
! For the kinds (fourth column), see the ctags file.
3+
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
4+
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
5+
!_TAG_OUTPUT_MODE u-ctags /u-ctags or e-ctags/
6+
!_TAG_PROGRAM_AUTHOR Universal Ctags Team //
7+
!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/
8+
!_TAG_PROGRAM_URL https://ctags.io/ /official site/
9+
!_TAG_PROGRAM_VERSION 0.0.0 /1a94658c/
10+
CtagsTest test/testfile.jl /^module CtagsTest$/;" m
11+
ImmutablePoint test/testfile.jl /^struct ImmutablePoint{T}$/;" s
12+
MutablePoint test/testfile.jl /^mutable struct MutablePoint{T}$/;" s
13+
Names test/testfile.jl /^Base.@kwdef struct Names$/;" s
14+
VariableNames test/testfile.jl /^Base.@kwdef mutable struct VariableNames$/;" s
15+
addcoment test/testfile.jl /^addcoment(string::AbstractString, comment, spaces=1) = begin # Maybe write without `begin`?$/;" f
16+
addone! test/testfile.jl /^function addone!(x::T) where {T <: Number}$/;" f
17+
addtwo! test/testfile.jl /^addtwo!(x::T) where {T <: Number} = (x += one(T) + one(T))$/;" f
18+
greet test/testfile.jl /^@generated function greet(x)$/;" f
19+
greeting test/testfile.jl /^const greeting = "Hello"$/;" v
20+
multiply test/testfile.jl /^multiply(x, y) = x * y$/;" f
21+
multiply test/testfile.jl /^multiply(x, y...) = begin$/;" f
22+
myconstsquarepower test/testfile.jl /^const myconstsquarepower = returnsquarepower()$/;" v
23+
mysquarepower test/testfile.jl /^mysquarepower = returnsquarepower()$/;" v
24+
returnsquarepower test/testfile.jl /^returnsquarepower = () -> 2$/;" f
25+
square test/testfile.jl /^function square(x)$/;" f
26+
squarepower test/testfile.jl /^squarepower = returnsquarepower$/;" v

0 commit comments

Comments
 (0)