Skip to content
This repository has been archived by the owner on Oct 8, 2020. It is now read-only.

Commit

Permalink
Define Xgit.Tag, which describes a tag object in memory. (#267)
Browse files Browse the repository at this point in the history
* Define Xgit.Tag, which describes a `tag` object in memory.

* Add link to TO DO issue for extensible tags and commits.
  • Loading branch information
scouten committed Dec 30, 2019
1 parent cc5d1e1 commit 1b41ae1
Show file tree
Hide file tree
Showing 2 changed files with 172 additions and 0 deletions.
59 changes: 59 additions & 0 deletions lib/xgit/tag.ex
@@ -0,0 +1,59 @@
defmodule Xgit.Tag do
@moduledoc ~S"""
Represents a git `tag` object in memory.
"""
alias Xgit.ObjectId
alias Xgit.PersonIdent

use Xgit.ObjectType

import Xgit.Util.ForceCoverage

@typedoc ~S"""
This struct describes a single `tag` object so it can be manipulated in memory.
## Struct Members
* `:object`: (`Xgit.ObjectId`) object referenced by this tag
* `:type`: ('Xgit.ObjectType`) type of the target object
* `:name`: (bytelist) name of the tag
* `:tagger`: (`Xgit.PersonIdent`) person who created the tag
* `:message`: (bytelist) user-entered tag message (encoding unspecified)
**TO DO:** Support signatures and other extensions.
https://github.com/elixir-git/xgit/issues/202
"""
@type t :: %__MODULE__{
object: ObjectId.t(),
type: ObjectType.t(),
name: [byte],
tagger: PersonIdent.t(),
message: [byte]
}

@enforce_keys [:object, :type, :name, :tagger, :message]
defstruct [:object, :type, :name, :tagger, :message]

@doc ~S"""
Return `true` if the value is a tag struct that is valid.
"""
@spec valid?(tag :: any) :: boolean
def valid?(tag)

def valid?(%__MODULE__{
object: object_id,
type: object_type,
name: name,
tagger: tagger,
message: message
})
when is_binary(object_id) and is_object_type(object_type) and is_list(name) and
is_list(message) do
ObjectId.valid?(object_id) &&
not Enum.empty?(name) &&
PersonIdent.valid?(tagger) &&
not Enum.empty?(message)
end

def valid?(_), do: cover(false)
end
113 changes: 113 additions & 0 deletions test/xgit/tag_test.exs
@@ -0,0 +1,113 @@
defmodule Xgit.TagTest do
use ExUnit.Case, async: true

# alias Xgit.GitInitTestCase
# alias Xgit.Object
alias Xgit.PersonIdent
alias Xgit.Tag

@invalid_pi %PersonIdent{
name: :bogus,
email: "author@example.com",
when: 1_142_878_501_000,
tz_offset: 150
}

describe "valid?/1" do
test "valid" do
assert Tag.valid?(%Tag{
object: "be9bfa841874ccc9f2ef7c48d0c76226f89b7189",
type: :commit,
name: 'test',
tagger: pi("A. U. Thor <author@localhost> 1 +0000"),
message: 'x'
})
end

test "invalid: corrupt object ID" do
refute Tag.valid?(%Tag{
object: "be9bfa841874ccc9f2ef7c48d0c76226f89b718",
type: :commit,
name: 'test',
tagger: pi("A. U. Thor <author@localhost> 1 +0000"),
message: 'x'
})
end

test "invalid: corrupt type 1" do
refute Tag.valid?(%Tag{
object: "be9bfa841874ccc9f2ef7c48d0c76226f89b7189",
type: "commit",
name: 'test',
tagger: pi("A. U. Thor <author@localhost> 1 +0000"),
message: 'x'
})
end

test "invalid: corrupt type 2" do
refute Tag.valid?(%Tag{
object: "be9bfa841874ccc9f2ef7c48d0c76226f89b7189",
type: :commit?,
name: 'test',
tagger: pi("A. U. Thor <author@localhost> 1 +0000"),
message: 'x'
})
end

test "invalid: empty name" do
refute Tag.valid?(%Tag{
object: "be9bfa841874ccc9f2ef7c48d0c76226f89b7189",
type: :commit,
name: '',
tagger: pi("A. U. Thor <author@localhost> 1 +0000"),
message: 'x'
})
end

test "valid: blank tagger" do
assert Tag.valid?(%Tag{
object: "be9bfa841874ccc9f2ef7c48d0c76226f89b7189",
type: :commit,
name: 'test',
tagger: pi("<> 0 +0000"),
message: 'x'
})
end

test "invalid: corrupt tagger 1" do
refute Tag.valid?(%Tag{
object: "be9bfa841874ccc9f2ef7c48d0c76226f89b7189",
type: :commit,
name: 'test',
tagger: @invalid_pi,
message: 'x'
})
end

test "invalid: corrupt tagger 2" do
refute Tag.valid?(%Tag{
object: "be9bfa841874ccc9f2ef7c48d0c76226f89b7189",
type: :commit,
name: 'test',
tagger: "A. U. Thor <author@localhost> 1 +0000",
message: 'x'
})
end

test "invalid: empty message" do
refute Tag.valid?(%Tag{
object: "be9bfa841874ccc9f2ef7c48d0c76226f89b7189",
type: :commit,
name: 'test',
tagger: pi("A. U. Thor <author@localhost> 1 +0000"),
message: ''
})
end

defp pi(s) do
s
|> String.to_charlist()
|> PersonIdent.from_byte_list()
end
end
end

0 comments on commit 1b41ae1

Please sign in to comment.