Skip to content

Commit

Permalink
Release for new Julia LTS. Extended tests: Aqua, Jet, ExplicitImports…
Browse files Browse the repository at this point in the history
…, TestRunner
  • Loading branch information
Azzaare committed Nov 1, 2024
1 parent ffe46fe commit c8ac7d1
Show file tree
Hide file tree
Showing 15 changed files with 207 additions and 140 deletions.
1 change: 1 addition & 0 deletions .JuliaFormatter.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
style = "sciml"
18 changes: 16 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,21 @@
name = "BibInternal"
uuid = "2027ae74-3657-4b95-ae00-e2f7d55c3e64"
authors = ["azzaare"]
version = "0.3.6"
version = "0.3.7"

[deps]
TestItems = "1c621080-faea-4a02-84b6-bbd5e436b8fe"

[compat]
julia = "1.6"
TestItems = "1"
julia = "1.10"

[extras]
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
ExplicitImports = "7d51a73a-1435-4ff3-83d9-f097790105c7"
JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
TestItemRunner = "f8b46487-2199-4994-9208-9a1283c18c0a"

[targets]
test = ["Aqua", "ExplicitImports", "JET", "Test", "TestItemRunner"]
2 changes: 1 addition & 1 deletion docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ using Documenter, BibInternal
makedocs(
sitename = "BibInternal.jl",
authors = "Jean-François BAFFIER",
repo="https://github.com/Humans-of-Julia/BibInternal.jl/blob/{commit}{path}#L{line}",
repo = "https://github.com/Humans-of-Julia/BibInternal.jl/blob/{commit}{path}#L{line}",
format = Documenter.HTML(
prettyurls = get(ENV, "CI", nothing) == "true"
),
Expand Down
31 changes: 17 additions & 14 deletions src/BibInternal.jl
Original file line number Diff line number Diff line change
@@ -1,14 +1,17 @@
module BibInternal

"""
Abstract entry supertype.
"""
abstract type AbstractEntry end

# Includes
include("constant.jl")
include("utilities.jl")
include("bibtex.jl")
include("entry.jl")

end # module
module BibInternal

"""
Abstract entry supertype.
"""
abstract type AbstractEntry end

# Imports
import TestItems: @testitem

# Includes
include("constant.jl")
include("utilities.jl")
include("bibtex.jl")
include("entry.jl")

end # module
48 changes: 22 additions & 26 deletions src/bibtex.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const Required = Union{String,Tuple{String,String}}
const Required = Union{String, Tuple{String, String}}

"""
const rules = Dict([
Expand All @@ -19,24 +19,21 @@ const Required = Union{String,Tuple{String,String}}
])
List of BibTeX rules bases on the entry type. A field value as a singleton represents a required field. A pair of values represents mutually exclusive required fields.
"""
const rules = Dict{String,Vector{Required}}(
[
"article" => ["author", "journal", "title", "year"]
"book" => [("author", "editor"), "publisher", "title", "year"]
"booklet" => ["title"]
"eprint" => ["author", "eprint", "title", "year"]
"inbook" =>
[("author", "editor"), ("chapter", "pages"), "publisher", "title", "year"]
"incollection" => ["author", "booktitle", "publisher", "title", "year"]
"inproceedings" => ["author", "booktitle", "title", "year"]
"manual" => ["title"]
"mastersthesis" => ["author", "school", "title", "year"]
"misc" => []
"phdthesis" => ["author", "school", "title", "year"]
"proceedings" => ["title", "year"]
"techreport" => ["author", "institution", "title", "year"]
"unpublished" => ["author", "note", "title"]
],
const rules = Dict{String, Vector{Required}}(
["article" => ["author", "journal", "title", "year"]
"book" => [("author", "editor"), "publisher", "title", "year"]
"booklet" => ["title"]
"eprint" => ["author", "eprint", "title", "year"]
"inbook" => [("author", "editor"), ("chapter", "pages"), "publisher", "title", "year"]
"incollection" => ["author", "booktitle", "publisher", "title", "year"]
"inproceedings" => ["author", "booktitle", "title", "year"]
"manual" => ["title"]
"mastersthesis" => ["author", "school", "title", "year"]
"misc" => []
"phdthesis" => ["author", "school", "title", "year"]
"proceedings" => ["title", "year"]
"techreport" => ["author", "institution", "title", "year"]
"unpublished" => ["author", "note", "title"]],
)

"""
Expand All @@ -56,15 +53,15 @@ function check_entry(fields, check, id)

for t_field in get(rules, entry_type, Vector{Required}())
at_least_one = false
if typeof(t_field) == Tuple{String,String}
if typeof(t_field) == Tuple{String, String}
for field in t_field
if get(fields, field, "") != ""
at_least_one = true
break
end
end
if !at_least_one
s = foldl((x, y) -> "$x$y", t_field; init="")
s = foldl((x, y) -> "$x$y", t_field; init = "")
# To remove the starting `≡`, we need `nextind` as it is a
# multibyte character
push!(errors, "{" * s[nextind(s, 1):end] * "}")
Expand All @@ -81,15 +78,14 @@ end
make_bibtex_entry(id::String, fields::Fields)
Make an entry if the entry follows the BibTeX guidelines. Throw an error otherwise.
"""
function make_bibtex_entry(id, fields; check=:error)
function make_bibtex_entry(id, fields; check = :error)
# @info id fields
fields = Dict(lowercase(k) => v for (k, v) in fields) # lowercase tag names
errors = check_entry(fields, check, id)
if length(errors) > 0 && check [:error, :warn]
message =
"Entry $id is missing the " *
foldl(((x, y) -> x * ", " * y), errors) *
" field(s)."
message = "Entry $id is missing the " *
foldl(((x, y) -> x * ", " * y), errors) *
" field(s)."
check == :error ? (@error message) : (@warn message)
end
return Entry(id, fields)
Expand Down
14 changes: 11 additions & 3 deletions src/constant.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"""
`Fields = Dict{String, String}`. Stores the fields `name => value` of an entry.
"""
const Fields = Dict{String,String}
const Fields = Dict{String, String}

"""
const entries = [
Expand Down Expand Up @@ -34,7 +34,7 @@ const entries = [
:phdthesis,
:proceedings,
:techreport,
:unpublished,
:unpublished
]

"""
Expand Down Expand Up @@ -96,11 +96,19 @@ const fields = [
:title,
:type,
:volume,
:year,
:year
]

"""
const maxfieldlength
For output formatting purpose, for instance, export to BibTeX format.
"""
const maxfieldlength = maximum(map(s -> length(string(s)), fields))

@testitem "Constants" tags=[:constants] begin
import BibInternal

@test BibInternal.maxfieldlength == 13
@info "Collections: " BibInternal.fields BibInternal.entries
@test BibInternal.Fields == Dict{String, String}
end
100 changes: 92 additions & 8 deletions src/entry.jl
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ function Name(str)
else

# split along commas, then along spaces
subnames = map(split(str, ","; keepempty=false)) do aux
return split(aux, r"[\n\r ]+"; keepempty=false)
subnames = map(split(str, ","; keepempty = false)) do aux
return split(aux, r"[\n\r ]+"; keepempty = false)
end

# mark for string parsing
Expand All @@ -54,7 +54,7 @@ function Name(str)
if length(aux) > 1 && isuppercase(aux[1][1])
first = aux[1]
mark_in += 1
for s in aux[2:(end-1)]
for s in aux[2:(end - 1)]
mark_in += 1
islowercase(s[1]) && break
middle *= " $s"
Expand Down Expand Up @@ -94,7 +94,7 @@ function Name(str)
end
particle = join(aux[1:mark_out], " ")
aux = subnames[2]
@assert length(aux) == 1 "malformed junior subname"
@assert length(aux)==1 "malformed junior subname"
junior = aux[1]
aux = subnames[end] # First Second
first = aux[1]
Expand All @@ -105,7 +105,6 @@ function Name(str)
# now this function sometimes gets called with an empty string
#error("too many commas in name '$(str)'")
end

end

return Name(particle, last, junior, first, middle)
Expand All @@ -115,7 +114,7 @@ end
names(str::String)
Decompose into parts a list of names in BibTeX compatible format. That is names separated by `and`.
"""
names(str) = map(Name, split(strip(str), r"\s+and\s+"; keepempty=false))
names(str) = map(Name, split(strip(str), r"\s+and\s+"; keepempty = false))

"""
struct Access
Expand Down Expand Up @@ -253,7 +252,7 @@ function In(fields)
publisher,
school,
series,
volume,
volume
)
end

Expand Down Expand Up @@ -282,7 +281,7 @@ struct Entry <: AbstractEntry
eprint::Eprint
id::String
in::In
fields::Dict{String,String}
fields::Dict{String, String}
title::String
type::String
end
Expand Down Expand Up @@ -386,3 +385,88 @@ function Base.isless(a::BibInternal.Name, b::BibInternal.Name)

return a.last < b.last
end

@testitem "Sorting" tags=[:sorting] begin
import BibInternal
@testset "isless() for BibInternal.Date" begin
@test BibInternal.Date("", "", "2000") < BibInternal.Date("", "", "2001")
@test BibInternal.Date("", "10", "2000") < BibInternal.Date("", "11", "2000")
@test BibInternal.Date("5", "01", "2000") < BibInternal.Date("15", "01", "2000")

@test BibInternal.Date("", "", "1970") > BibInternal.Date("", "", "1969")
@test BibInternal.Date("", "7", "1970") > BibInternal.Date("", "6", "1970")
@test BibInternal.Date("7", "7", "1970") > BibInternal.Date("6", "7", "1970")

@test BibInternal.Date("", "", "1805") == BibInternal.Date("", "", "1805")
@test BibInternal.Date("", "4", "1805") == BibInternal.Date("", "4", "1805")
@test BibInternal.Date("3", "4", "1805") == BibInternal.Date("3", "4", "1805")

@test BibInternal.Date("", "", "1805") !== BibInternal.Date("", "", "1905")
@test BibInternal.Date("", "4", "1805") !== BibInternal.Date("", "5", "1805")
@test BibInternal.Date("3", "4", "1805") !== BibInternal.Date("4", "4", "1805")

@test_skip BibInternal.Date("", "May", "1805") == BibInternal.Date("", "5", "1805")
@test_skip BibInternal.Date("1th", "5", "1805") !==
BibInternal.Date("1", "5", "1805")

@test_throws ArgumentError BibInternal.Date(
"", "", "1")<
BibInternal.Date("", "", "2000a")
@test_throws ArgumentError BibInternal.Date(
"", "", "1")<BibInternal.Date("", "", "")
@test_throws ArgumentError BibInternal.Date(
"", "", "1")<
BibInternal.Date("", "", "90ies")
@test_throws ArgumentError BibInternal.Date(
"", "", "40k")<
BibInternal.Date("", "", "40000")
end

@testset "isless() for BibInternal.Name" begin
# TODO: consider testing for alphabetizing rules

@test BibInternal.Name("", "Cow", "", "John", "") <
BibInternal.Name("", "Doe", "", "John", "")
@test BibInternal.Name("", "Doe", "", "John", "A.") <
BibInternal.Name("", "Doe", "", "John", "B.")
@test BibInternal.Name("", "Doe", "", "Bronn", "") <
BibInternal.Name("", "Doe", "", "John", "")
@test BibInternal.Name("", "Bronn", "", "Would", "") <
BibInternal.Name("", "Bronn", "", "Would", "Not")

@test BibInternal.Name("", "Doe", "", "John", "") ==
BibInternal.Name("", "Doe", "", "John", "")
@test BibInternal.Name("", "Doe", "jun.", "John", "") ==
BibInternal.Name("", "Doe", "jun.", "John", "")
@test BibInternal.Name("", "Doe", "", "John", "E.") ==
BibInternal.Name("", "Doe", "", "John", "E.")

@test BibInternal.Name("", "Doe", "", "Bronn", "") !==
BibInternal.Name("", "Doe", "", "John", "")
@test BibInternal.Name("", "Doe", "jun.", "John", "") !==
BibInternal.Name("", "Doe", "sen.", "John", "")
@test BibInternal.Name("", "Doe", "", "John", "E.") !==
BibInternal.Name("", "Doe", "", "John", "A.")
end
end

@testitem "Parsing" tags=[:parsing] begin
import BibInternal

@testset "junior parsing for BibInternal.Name" begin
name = BibInternal.Name("Doe, Jr, Abe Brian")
name_expected = BibInternal.Name("", "Doe", "Jr", "Abe", "Brian")
@test name == name_expected

name = BibInternal.Name("Doe, Jr., A. B.")
name_expected = BibInternal.Name("", "Doe", "Jr.", "A.", "B.")
@test name == name_expected

# If no comma is used between the last name and junior, the junior should be
# combined with the last name
# (https://nwalsh.com/tex/texhelp/bibtx-23.html).
name = BibInternal.Name("Doe Jr., A. B.")
name_expected = BibInternal.Name("", "Doe Jr.", "", "A.", "B.")
@test name == name_expected
end
end
24 changes: 24 additions & 0 deletions test/Aqua.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
@testset "Aqua.jl" begin
# TODO: Fix the broken tests and remove the `broken = true` flag
Aqua.test_all(
BibInternal;
ambiguities = (broken = false,),
deps_compat = false,
piracies = (broken = false,)
)

@testset "Ambiguities: BibInternal" begin
Aqua.test_ambiguities(BibInternal;)
end

@testset "Piracies: BibInternal" begin
Aqua.test_piracies(BibInternal;)
end

@testset "Dependencies compatibility (no extras)" begin
Aqua.test_deps_compat(
BibInternal;
check_extras = false # ignore = [:Random]
)
end
end
3 changes: 3 additions & 0 deletions test/ExplicitImports.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@testset "Look for Explicit Imports" begin
@test check_no_implicit_imports(BibInternal) === nothing
end
3 changes: 3 additions & 0 deletions test/JET.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@testset "Code linting (JET.jl)" begin
JET.test_package(BibInternal; target_defined_modules = true)
end
2 changes: 0 additions & 2 deletions test/Project.toml

This file was deleted.

3 changes: 3 additions & 0 deletions test/TestItemRunner.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@testset "TestItemRunner" begin
@run_package_tests
end
5 changes: 0 additions & 5 deletions test/constants.jl

This file was deleted.

Loading

0 comments on commit c8ac7d1

Please sign in to comment.