• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

rdf-elixir / jsonld-ex / de3ca9b1dae3a8dffda3dec6d69d62a58ee3622e

10 Apr 2025 03:31PM UTC coverage: 91.542%. Remained the same
de3ca9b1dae3a8dffda3dec6d69d62a58ee3622e

push

github

marcelotto
Remove unused HTML versions of test manifests

1775 of 1939 relevant lines covered (91.54%)

4387.12 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

75.93
/lib/json/ld/utils.ex
1
defmodule JSON.LD.Utils do
2
  @moduledoc false
3

4
  alias RDF.IRI
5
  require Logger
6

7
  def valid_uri?(uri) do
8
    RDF.IRI.Validation.valid?(uri)
19,468✔
9
  end
10

11
  def valid_language?(string) do
12
    String.match?(string, ~r/^[a-zA-Z]+(-[a-zA-Z0-9]+)*$/)
2,784✔
13
  end
14

15
  def validate_language(language, processor_options) do
16
    if not valid_language?(language),
2,556✔
17
      do: warn("@language must be valid BCP47: #{language}", processor_options)
4✔
18

19
    language
2,556✔
20
  end
21

22
  def normalize_language(language, %{lowercase_language: true}), do: String.downcase(language)
2,556✔
23
  def normalize_language(language, _), do: language
×
24

25
  def validate_and_normalize_language(language, processor_options) do
26
    language
27
    |> validate_language(processor_options)
28
    |> normalize_language(processor_options)
2,556✔
29
  end
30

31
  @doc """
32
  Resolves a relative IRI against a base IRI.
33

34
  as specified in [section 5.1 Establishing a Base URI of RFC3986](http://tools.ietf.org/html/rfc3986#section-5.1).
35
  Only the basic algorithm in [section 5.2 of RFC3986](http://tools.ietf.org/html/rfc3986#section-5.2)
36
  is used; neither Syntax-Based Normalization nor Scheme-Based Normalization are performed.
37

38
  Characters additionally allowed in IRI references are treated in the same way that unreserved
39
  characters are treated in URI references, per [section 6.5 of RFC3987](http://tools.ietf.org/html/rfc3987#section-6.5)
40
  """
41
  @spec absolute_iri(String.t(), String.t() | nil) :: IRI.coercible() | nil
42
  def absolute_iri(value, base_iri)
43
  def absolute_iri(value, nil), do: value
100✔
44
  def absolute_iri(value, base_iri), do: value |> IRI.absolute(base_iri) |> to_string()
3,152✔
45

46
  @spec relative_iri?(String.t()) :: boolean
47
  def relative_iri?(value),
48
    do: not (JSON.LD.keyword?(value) or IRI.absolute?(value) or blank_node_id?(value))
508✔
49

50
  @spec compact_iri_parts(String.t(), boolean) :: [String.t()] | nil
51
  def compact_iri_parts(compact_iri, exclude_bnode \\ true) do
52
    case String.split(compact_iri, ":", parts: 2) do
53,272✔
53
      [prefix, suffix] ->
54
        if not String.starts_with?(suffix, "//") and not (exclude_bnode and prefix == "_"),
53,272✔
55
          do: [prefix, suffix]
56

57
      _ ->
×
58
        nil
59
    end
60
  end
61

62
  def keyword_form?(value), do: String.match?(value, ~r/^@[a-zA-Z]+$/)
139,072✔
63

64
  @doc """
65
  Checks if the given value is a blank node identifier.
66

67
  A blank node identifier is a string that can be used as an identifier for a
68
  blank node within the scope of a JSON-LD document.
69

70
  Blank node identifiers begin with `_:`
71

72
  see <https://www.w3.org/TR/json-ld-api/#dfn-blank-node-identifier>
73
  """
74
  @spec blank_node_id?(any) :: boolean
75
  def blank_node_id?("_:" <> _), do: true
4,964✔
76
  def blank_node_id?(_), do: false
31,448✔
77

78
  @spec scalar?(any) :: boolean
79
  def scalar?(value) when is_binary(value) or is_number(value) or is_boolean(value), do: true
8,124✔
80
  def scalar?(_), do: false
2,700✔
81

82
  @spec list?(map | nil) :: boolean
83
  def list?(%{"@list" => _}), do: true
1,744✔
84
  def list?(_), do: false
25,692✔
85

86
  @spec set?(map | nil) :: boolean
87
  def set?(%{"@set" => _}), do: true
×
88
  def set?(_), do: false
348✔
89

90
  @spec index?(map | nil) :: boolean
91
  def index?(%{"@index" => _}), do: true
1,296✔
92
  def index?(_), do: false
16,396✔
93

94
  @spec value?(map | nil) :: boolean
95
  def value?(%{"@value" => _}), do: true
4,688✔
96
  def value?(_), do: false
8,208✔
97

98
  # https://www.w3.org/TR/json-ld11/#dfn-node-object
99
  @spec id_node?(map | nil) :: boolean
100
  def id_node?(%{"@id" => _}), do: true
×
101
  def id_node?(_), do: false
×
102

103
  # https://www.w3.org/TR/json-ld11/#dfn-node-object
104
  @spec node?(map | nil) :: boolean
105
  def node?(value) when is_map(value) do
106
    not (value?(value) or list?(value) or set?(value))
348✔
107
  end
108

109
  def node?(_), do: false
36✔
110

111
  @spec graph?(map | any) :: boolean
112
  def graph?(value) when is_map(value) do
113
    Map.keys(value) -- ~w[@context @id @index] == ["@graph"]
16,912✔
114
  end
115

116
  def graph?(_), do: false
1,800✔
117

118
  @spec simple_graph?(map | any) :: boolean
119
  def simple_graph?(value) do
120
    graph?(value) and not Map.has_key?(value, "@id")
216✔
121
  end
122

123
  def deep_merge(map1, map2) do
124
    Map.merge(map1, map2, fn
672✔
125
      _key, value1, value2 when is_map(value1) and is_map(value2) -> deep_merge(value1, value2)
×
126
      _key, value1, value2 -> List.wrap(value1) ++ List.wrap(value2)
116✔
127
    end)
128
  end
129

130
  def to_list(value) when is_list(value), do: value
220✔
131
  def to_list(value), do: [value]
456✔
132

133
  def maybe_sort(enum, true), do: Enum.sort(enum)
2,548✔
134
  def maybe_sort(enum, false), do: enum
19,092✔
135

136
  def maybe_sort(enum, true, fun), do: Enum.sort(enum, fun)
×
137
  def maybe_sort(enum, false, _fun), do: enum
×
138

139
  def maybe_sort_by(enum, true, fun), do: Enum.sort_by(enum, fun)
852✔
140
  def maybe_sort_by(enum, false, _fun), do: enum
1,860✔
141

142
  def warn(message, %JSON.LD.Options{warn: method}), do: warn(message, method)
124✔
143
  def warn(message, :default), do: warn(message, JSON.LD.Options.warn_default())
124✔
144
  def warn(message, :log), do: warn(message, &Logger.warning/1)
124✔
145
  def warn(message, :raise), do: raise(message)
×
146
  def warn(_message, :ignore), do: :ok
×
147
  def warn(message, nil), do: warn(message, :default)
×
148
  def warn(message, true), do: warn(message, :default)
×
149
  def warn(message, false), do: warn(message, :ignore)
×
150
  def warn(message, fun) when is_function(fun), do: fun.(message)
124✔
151
end
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc