Add some basic tests
This commit is contained in:
parent
810ac5ab28
commit
5adde3ad7c
8
.gitignore
vendored
8
.gitignore
vendored
@ -1,6 +1,6 @@
|
||||
.DS_Store
|
||||
*.jl.cov
|
||||
*.jl.*.cov
|
||||
*.jl.mem
|
||||
/docs/build/
|
||||
/docs/site/
|
||||
.DS_Store
|
||||
*.jl.*.cov
|
||||
*.jl.cov
|
||||
*.jl.mem
|
||||
|
@ -11,6 +11,9 @@ julia:
|
||||
- 1.2
|
||||
- 1.3
|
||||
- nightly
|
||||
before_script:
|
||||
- git config --global user.name Tester
|
||||
- git config --global user.email te@st.er
|
||||
matrix:
|
||||
fast_finish: true
|
||||
allow_failures:
|
||||
|
@ -106,12 +106,6 @@ version = "0.2.11"
|
||||
deps = ["Distributed", "InteractiveUtils", "Logging", "Random"]
|
||||
uuid = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
||||
|
||||
[[URIParser]]
|
||||
deps = ["Test", "Unicode"]
|
||||
git-tree-sha1 = "6ddf8244220dfda2f17539fa8c9de20d6c575b69"
|
||||
uuid = "30578b45-9adc-5946-b283-645ec420af67"
|
||||
version = "0.4.0"
|
||||
|
||||
[[UUIDs]]
|
||||
deps = ["Random", "SHA"]
|
||||
uuid = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
|
||||
|
@ -1,7 +1,7 @@
|
||||
name = "PkgTemplates"
|
||||
uuid = "14b8a8f1-9102-5b29-a752-f990bacb7fe1"
|
||||
authors = ["Chris de Graaf <chrisadegraaf@gmail.com>"]
|
||||
version = "0.6.2"
|
||||
version = "0.7.0"
|
||||
|
||||
[deps]
|
||||
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
|
||||
@ -11,14 +11,14 @@ Mustache = "ffc61752-8dc7-55ee-8c37-f3e9cdd09e70"
|
||||
Parameters = "d96e819e-fc66-5662-9728-84c9c7592b0a"
|
||||
Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"
|
||||
REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb"
|
||||
URIParser = "30578b45-9adc-5946-b283-645ec420af67"
|
||||
|
||||
[compat]
|
||||
julia = "1"
|
||||
|
||||
[extras]
|
||||
Suppressor = "fd094767-a336-5f1f-9728-57cf17d0bbfb"
|
||||
Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
|
||||
ReferenceTests = "324d217c-45ce-50fc-942e-d289b448e8cf"
|
||||
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
||||
|
||||
[targets]
|
||||
test = ["Suppressor", "Test"]
|
||||
test = ["Random", "ReferenceTests", "Test"]
|
||||
|
@ -11,7 +11,6 @@ using REPL.TerminalMenus: MultiSelectMenu, RadioMenu, request
|
||||
|
||||
using Mustache: entityMap, render
|
||||
using Parameters: @with_kw
|
||||
using URIParser: URI
|
||||
|
||||
export
|
||||
Template,
|
||||
@ -36,5 +35,6 @@ abstract type Plugin end
|
||||
include("template.jl")
|
||||
include("generate.jl")
|
||||
include("plugin.jl")
|
||||
# include("interactive.jl")
|
||||
|
||||
end
|
||||
|
@ -6,7 +6,6 @@ Generate a package named `pkg` from a [`Template`](@ref).
|
||||
function (t::Template)(pkg::AbstractString)
|
||||
endswith(pkg, ".jl") && (pkg = pkg[1:end-3])
|
||||
pkg_dir = joinpath(t.dir, pkg)
|
||||
ispath(pkg_dir) && throw(ArgumentError("$pkg_dir already exists"))
|
||||
|
||||
try
|
||||
# Create the directory with some boilerplate inside.
|
||||
|
@ -1,14 +1,13 @@
|
||||
# TODO: Update the allowed failures as new versions come out.
|
||||
const VersionsOrStrings = Vector{Union{VersionNumber, String}}
|
||||
const ALLOWED_FAILURES = ["1.3", "nightly"]
|
||||
const DEFAULT_CI_VERSIONS = VersionsOrStrings([VERSION, "1.0", "nightly"])
|
||||
const ALLOWED_FAILURES = ["1.3", "nightly"] # TODO: Update this list with new RCs.
|
||||
const DEFAULT_CI_VERSIONS = VersionsOrStrings([VERSION, default_version(), "nightly"])
|
||||
|
||||
format_version(v::VersionNumber) = "$(v.major).$(v.minor)"
|
||||
format_version(v::AbstractString) = string(v)
|
||||
|
||||
function collect_versions(t::Template, versions::Vector)
|
||||
vs = [format_version(t.julia_version); map(format_version, versions)]
|
||||
return unique!(sort!(vs))
|
||||
vs = map(format_version, [t.julia_version, versions...])
|
||||
return unique(sort(vs))
|
||||
end
|
||||
|
||||
@with_kw struct TravisCI <: BasicPlugin
|
||||
@ -43,8 +42,8 @@ function view(p::TravisCI, t::Template, pkg::AbstractString)
|
||||
x86 = Dict{String, String}[]
|
||||
if p.x86
|
||||
foreach(versions) do v
|
||||
p.linux && push!(x86, Dict("JULIA" => v, "OS" => "linux", "ARCH" => "x86"))
|
||||
p.windows && push!(x86, Dict("JULIA" => v, "OS" => "windows", "ARCH" => "x86"))
|
||||
p.linux && push!(x86, Dict("JULIA" => v, "OS" => "linux"))
|
||||
p.windows && push!(x86, Dict("JULIA" => v, "OS" => "windows"))
|
||||
end
|
||||
end
|
||||
|
||||
@ -128,10 +127,10 @@ function view(p::CirrusCI, t::Template, ::AbstractString)
|
||||
end
|
||||
|
||||
@with_kw struct GitLabCI <: BasicPlugin
|
||||
file::String
|
||||
file::String = default_file("gitlab-ci.yml")
|
||||
documentation::Bool = true
|
||||
coverage::Bool = true
|
||||
extra_versions::Vector{VersionNumber} = [v"1.0"]
|
||||
extra_versions::VersionsOrStrings = ["1.0"] # Nightly has no Docker image.
|
||||
end
|
||||
|
||||
gitignore(p::GitLabCI) = p.coverage ? COVERAGE_GITIGNORE : String[]
|
||||
|
@ -93,7 +93,7 @@ function render_plugin(p::Gitignore, t::Template)
|
||||
end
|
||||
|
||||
function gen_plugin(p::Gitignore, t::Template, pkg_dir::AbstractString)
|
||||
gen_file(joinpath(pkg_dir, ".gitignore"), render_plugin(p, t))
|
||||
t.git && gen_file(joinpath(pkg_dir, ".gitignore"), render_plugin(p, t))
|
||||
end
|
||||
|
||||
@with_kw struct Tests <: BasicPlugin
|
||||
@ -121,7 +121,7 @@ function gen_plugin(p::Tests, t::Template, pkg_dir::AbstractString)
|
||||
proj = current_project()
|
||||
try
|
||||
Pkg.activate(pkg_dir)
|
||||
Pkg.update() # Clean up both Manifest.toml and Project.toml.
|
||||
Pkg.update()
|
||||
finally
|
||||
proj === nothing ? Pkg.activate() : Pkg.activate(proj)
|
||||
end
|
||||
|
@ -1,13 +1,12 @@
|
||||
const DEFAULT_USER = LibGit2.getconfig("github.user", "")
|
||||
const DEFAULT_VERSION = VersionNumber(VERSION.major)
|
||||
const DEFAULT_AUTHORS = let
|
||||
default_plugins() = [Gitignore(), License(), Readme(), Tests()]
|
||||
default_user() = LibGit2.getconfig("github.user", "")
|
||||
default_version() = VersionNumber(VERSION.major)
|
||||
|
||||
function default_authors()
|
||||
name = LibGit2.getconfig("user.name", "")
|
||||
isempty(name) && return ""
|
||||
email = LibGit2.getconfig("user.email", "")
|
||||
if isempty(name)
|
||||
""
|
||||
else
|
||||
isempty(email) ? name : "$name <$email>"
|
||||
end
|
||||
return isempty(email) ? name : "$name <$email>"
|
||||
end
|
||||
|
||||
"""
|
||||
@ -18,17 +17,17 @@ Records common information used to generate a package.
|
||||
## Keyword Arguments
|
||||
|
||||
### User Options
|
||||
- `user::AbstractString="$DEFAULT_USER"`: GitHub (or other code hosting service) username.
|
||||
- `user::AbstractString="$(default_user())"`: GitHub (or other code hosting service) username.
|
||||
The default value comes from the global Git config (`github.user`).
|
||||
If no value is obtained, an `ArgumentError` is thrown.
|
||||
- `authors::Union{AbstractString, Vector{<:AbstractString}}="$DEFAULT_AUTHORS"`: Package authors.
|
||||
- `authors::Union{AbstractString, Vector{<:AbstractString}}="$(default_authors())"`: Package authors.
|
||||
Supply a string for one author or an array for multiple.
|
||||
Like `user`, it takes its default value from the global Git config (`user.name` and `user.email`).
|
||||
|
||||
### Package Options
|
||||
- `host::AbstractString="github.com"`: URL to the code hosting service where packages will reside.
|
||||
- `dir::AbstractString="$(contractuser(Pkg.devdir()))"`: Directory to place packages in.
|
||||
- `julia_version::VersionNumber=$(repr(DEFAULT_VERSION))`: Minimum allowed Julia version.
|
||||
- `julia_version::VersionNumber=$(repr(default_version()))`: Minimum allowed Julia version.
|
||||
- `develop::Bool=true`: Whether or not to `develop` new packages in the active environment.
|
||||
|
||||
### Git Options
|
||||
@ -39,13 +38,12 @@ Records common information used to generate a package.
|
||||
|
||||
### Template Plugins
|
||||
- `plugins::Vector{<:Plugin}=Plugin[]`: A list of [`Plugin`](@ref)s used by the template.
|
||||
- `disabled_defaults::Vector{DataType}=DataType[]`: Default plugins to disable.
|
||||
- `disable_defaults::Vector{DataType}=DataType[]`: Default plugins to disable.
|
||||
The default plugins are [`Readme`](@ref), [`License`](@ref), [`Tests`](@ref), and [`Gitignore`](@ref).
|
||||
To override a default plugin instead of disabling it altogether, supply it via `plugins`.
|
||||
|
||||
### Interactive Usage
|
||||
- `interactive::Bool=false`: When set, the template is created interactively, filling unset keywords with user input.
|
||||
- `fast::Bool=false`: Skips prompts for any unsupplied keywords except `user` and `plugins`, accepting default values.
|
||||
"""
|
||||
struct Template
|
||||
authors::Vector{String}
|
||||
@ -67,21 +65,19 @@ function Template(::Val{false}; kwargs...)
|
||||
user = getkw(kwargs, :user)
|
||||
isempty(user) && throw(ArgumentError("No user set, please pass user=username"))
|
||||
|
||||
host = getkw(kwargs, :host)
|
||||
host = URI(occursin("://", host) ? host : "https://$host").host
|
||||
|
||||
authors = getkw(kwargs, :authors)
|
||||
authors isa Vector || (authors = map(strip, split(authors, ",")))
|
||||
|
||||
host = replace(getkw(kwargs, :host), r".*://" => "")
|
||||
|
||||
dir = abspath(expanduser(getkw(kwargs, :dir)))
|
||||
|
||||
disabled = getkw(kwargs, :disabled_defaults)
|
||||
defaults = [Readme, License, Tests, Gitignore]
|
||||
plugins = map(T -> T(), filter(T -> !(T in disabled), defaults))
|
||||
append!(plugins, getkw(kwargs, :plugins))
|
||||
disabled = getkw(kwargs, :disable_defaults)
|
||||
enabled = filter(p -> !(typeof(p) in disabled), default_plugins())
|
||||
append!(enabled, getkw(kwargs, :plugins))
|
||||
# This comprehension resolves duplicate plugin types by overwriting,
|
||||
# which means that default plugins get replaced by user values.
|
||||
plugin_dict = Dict(typeof(p) => p for p in plugins)
|
||||
plugins = Dict(typeof(p) => p for p in enabled)
|
||||
|
||||
return Template(
|
||||
authors,
|
||||
@ -91,7 +87,7 @@ function Template(::Val{false}; kwargs...)
|
||||
host,
|
||||
getkw(kwargs, :julia_version),
|
||||
getkw(kwargs, :manifest),
|
||||
plugin_dict,
|
||||
plugins,
|
||||
getkw(kwargs, :ssh),
|
||||
user,
|
||||
)
|
||||
@ -106,14 +102,14 @@ getkw(kwargs, k) = get(() -> defaultkw(k), kwargs, k)
|
||||
|
||||
# Default Template keyword values.
|
||||
defaultkw(s::Symbol) = defaultkw(Val(s))
|
||||
defaultkw(::Val{:authors}) = DEFAULT_AUTHORS
|
||||
defaultkw(::Val{:authors}) = default_authors()
|
||||
defaultkw(::Val{:develop}) = true
|
||||
defaultkw(::Val{:dir}) = Pkg.devdir()
|
||||
defaultkw(::Val{:disabled_defaults}) = DataType[]
|
||||
defaultkw(::Val{:disable_defaults}) = DataType[]
|
||||
defaultkw(::Val{:git}) = true
|
||||
defaultkw(::Val{:host}) = "github.com"
|
||||
defaultkw(::Val{:julia_version}) = DEFAULT_VERSION
|
||||
defaultkw(::Val{:julia_version}) = default_version()
|
||||
defaultkw(::Val{:manifest}) = false
|
||||
defaultkw(::Val{:plugins}) = Plugin[]
|
||||
defaultkw(::Val{:ssh}) = false
|
||||
defaultkw(::Val{:user}) = DEFAULT_USER
|
||||
defaultkw(::Val{:user}) = default_user()
|
||||
|
3
test/fixtures/Basic/.gitignore.txt
vendored
Normal file
3
test/fixtures/Basic/.gitignore.txt
vendored
Normal file
@ -0,0 +1,3 @@
|
||||
.DS_Store
|
||||
/Manifest.toml
|
||||
/dev/
|
19
test/fixtures/Basic/LICENSE.txt
vendored
Normal file
19
test/fixtures/Basic/LICENSE.txt
vendored
Normal file
@ -0,0 +1,19 @@
|
||||
Copyright (c) 2019 tester
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
2
test/fixtures/Basic/Manifest.toml.txt
vendored
Normal file
2
test/fixtures/Basic/Manifest.toml.txt
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# This file is machine-generated - editing it directly is not advised
|
||||
|
13
test/fixtures/Basic/Project.toml.txt
vendored
Normal file
13
test/fixtures/Basic/Project.toml.txt
vendored
Normal file
@ -0,0 +1,13 @@
|
||||
name = "Basic"
|
||||
uuid = "5b7e9947-ddc0-4b3f-9b55-0d8042f74170"
|
||||
authors = ["tester"]
|
||||
version = "0.1.0"
|
||||
|
||||
[compat]
|
||||
julia = "1"
|
||||
|
||||
[extras]
|
||||
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
|
||||
|
||||
[targets]
|
||||
test = ["Test"]
|
1
test/fixtures/Basic/README.md.txt
vendored
Normal file
1
test/fixtures/Basic/README.md.txt
vendored
Normal file
@ -0,0 +1 @@
|
||||
# Basic
|
5
test/fixtures/Basic/src/Basic.jl.txt
vendored
Normal file
5
test/fixtures/Basic/src/Basic.jl.txt
vendored
Normal file
@ -0,0 +1,5 @@
|
||||
module Basic
|
||||
|
||||
greet() = print("Hello World!")
|
||||
|
||||
end # module
|
6
test/fixtures/Basic/test/runtests.jl.txt
vendored
Normal file
6
test/fixtures/Basic/test/runtests.jl.txt
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
using Basic
|
||||
using Test
|
||||
|
||||
@testset "Basic.jl" begin
|
||||
# Write your tests here.
|
||||
end
|
25
test/generate.jl
Normal file
25
test/generate.jl
Normal file
@ -0,0 +1,25 @@
|
||||
default_files(pkg::AbstractString) = [
|
||||
".gitignore",
|
||||
"LICENSE",
|
||||
"Manifest.toml",
|
||||
"Project.toml",
|
||||
"README.md",
|
||||
"src/$pkg.jl",
|
||||
"test/runtests.jl",
|
||||
]
|
||||
|
||||
function reference_test(pkg_dir::AbstractString, path::AbstractString)
|
||||
pkg = basename(pkg_dir)
|
||||
path = replace(path, "/" => path_separator)
|
||||
# All fixture files are .txt because otherwise ReferenceTests/FileIO can't handle them.
|
||||
reference = joinpath(@__DIR__, "fixtures", pkg, path * ".txt")
|
||||
observed = read(joinpath(pkg_dir, path), String)
|
||||
@test_reference reference observed
|
||||
end
|
||||
|
||||
@testset "Default package" begin
|
||||
pkg = "Basic"
|
||||
t = tpl(; develop=false, authors=USER)
|
||||
t(pkg)
|
||||
foreach(f -> reference_test(joinpath(t.dir, pkg), f), default_files(pkg))
|
||||
end
|
@ -0,0 +1,32 @@
|
||||
using Base.Filesystem: path_separator
|
||||
|
||||
using Pkg: Pkg
|
||||
using Random: Random
|
||||
using Test: @test, @testset, @test_throws
|
||||
|
||||
using ReferenceTests: @test_reference
|
||||
|
||||
using PkgTemplates
|
||||
const PT = PkgTemplates
|
||||
|
||||
const PKG = "TestPkg"
|
||||
const USER = "tester"
|
||||
|
||||
Random.seed!(1)
|
||||
|
||||
tpl(; kwargs...) = Template(; user=USER, kwargs...)
|
||||
|
||||
@testset "PkgTemplates.jl" begin
|
||||
mktempdir() do dir
|
||||
Pkg.activate(dir)
|
||||
pushfirst!(DEPOT_PATH, dir)
|
||||
try
|
||||
include("template.jl")
|
||||
include("generate.jl")
|
||||
# include("plugin.jl")
|
||||
# include("interactive.jl")
|
||||
finally
|
||||
popfirst!(DEPOT_PATH)
|
||||
end
|
||||
end
|
||||
end
|
52
test/template.jl
Normal file
52
test/template.jl
Normal file
@ -0,0 +1,52 @@
|
||||
@testset "Template constructor" begin
|
||||
@testset "user" begin
|
||||
if isempty(PT.default_user())
|
||||
@test_throws ArgumentError Template()
|
||||
haskey(ENV, "CI") && run(`git config --global github.user $USER`)
|
||||
end
|
||||
@test Template().user == PT.default_user()
|
||||
end
|
||||
|
||||
@testset "authors" begin
|
||||
@test tpl(; authors=["a"]).authors == ["a"]
|
||||
@test tpl(; authors="a").authors == ["a"]
|
||||
@test tpl(; authors="a,b").authors == ["a", "b"]
|
||||
@test tpl(; authors="a, b").authors == ["a", "b"]
|
||||
end
|
||||
|
||||
@testset "host" begin
|
||||
@test tpl(; host="https://foo.com").host == "foo.com"
|
||||
end
|
||||
|
||||
@testset "dir" begin
|
||||
@test tpl(; dir="/foo/bar").dir == "/foo/bar"
|
||||
@test tpl(; dir="foo").dir == abspath("foo")
|
||||
@test tpl(; dir="~/foo").dir == abspath(expanduser("~/foo"))
|
||||
end
|
||||
|
||||
@testset "plugins / disabled_defaults" begin
|
||||
function test_plugins(plugins, expected, disabled=DataType[])
|
||||
t = tpl(; plugins=plugins, disable_defaults=disabled)
|
||||
@test issetequal(values(t.plugins), expected)
|
||||
end
|
||||
|
||||
defaults = PT.default_plugins()
|
||||
test_plugins([], defaults)
|
||||
test_plugins([Citation()], union(defaults, [Citation()]))
|
||||
# Overriding a default plugin.
|
||||
gi = Gitignore(; dev=false)
|
||||
test_plugins([gi], union(setdiff(defaults, [Gitignore()]), [gi]))
|
||||
# Disabling a default plugin.
|
||||
test_plugins([], setdiff(defaults, [Gitignore()]), [Gitignore])
|
||||
end
|
||||
end
|
||||
|
||||
@testset "hasplugin" begin
|
||||
t = tpl(; plugins=[Documenter{TravisCI}()])
|
||||
@test PT.hasplugin(t, typeof(first(PT.default_plugins())))
|
||||
@test PT.hasplugin(t, Documenter)
|
||||
@test PT.hasplugin(t, _ -> true)
|
||||
@test !PT.hasplugin(t, _ -> false)
|
||||
@test !PT.hasplugin(t, Citation)
|
||||
@test !PT.hasplugin(t, PT.is_ci)
|
||||
end
|
Loading…
Reference in New Issue
Block a user