-- test/test-gall.tree.lua
--
-- Git Abstraction layer for Lua - Tree object tests
--
-- Copyright 2012 Daniel Silverstone <dsilvers@digital-scurf.org>
--
-- For Licence terms, see COPYING
--

-- This test includes tree wibbling
dofile "test/withrepo.lua"

-- Step one, start coverage

pcall(require, 'luacov')

local gall = require 'gall'

local testnames = {}

local real_assert = assert
local total_asserts = 0
local function assert(...)
   local retval = real_assert(...)
   total_asserts = total_asserts + 1
   return retval
end

local function add_test(suite, name, value)
   rawset(suite, name, value)
   testnames[#testnames+1] = name
end

local suite = setmetatable({}, {__newindex = add_test})

function suite.get_tree_ok()
   local repo = test_repo()
   local commit = repo:get("HEAD").content
   local tree = commit.tree.content
   assert(tree)
end

function suite.tree_str()
   local repo = test_repo()
   local commit = repo:get("HEAD").content
   local treeobj = commit.tree
   local tree = treeobj.content
   local treestr = tostring(tree)
   assert(treestr:find("GitTree"))
   assert(treestr:find(treeobj.sha))
end

function suite.flatten_tree()
   local repo = test_repo()
   local commit = repo:get("refs/heads/heirarchy").content
   local tree = commit.tree.content
   local flat = gall.tree.flatten(tree)
   assert(flat)
   assert(flat.testblob)
   assert(flat["blobs/second"])
end

function suite.bad_diff()
   local repo = test_repo()
   local commit = repo:get("refs/heads/heirarchy").content
   local tree = commit.tree.content
   local ok, msg = tree:diff_to()
   assert(not ok)
   assert(msg:find("DOES_NOT_EXIST"))
end

function suite.diff_trees()
   local repo = test_repo()
   local heir_tree = repo:get("refs/heads/heirarchy").content.tree.content
   local master_tree = repo:get("refs/heads/master").content.tree.content
   local diff = assert(master_tree:diff_to(heir_tree))
end

function suite.flatten_then_create_tree()
   local repo = test_repo()
   local commit = repo:get("refs/heads/heirarchy").content
   local tree = commit.tree.content
   local flat = gall.tree.flatten(tree)
   assert(flat)
   assert(flat.testblob)
   assert(flat["blobs/second"])
   local newtree = gall.tree.create(repo, flat)
   assert(newtree == commit.tree)
end

function suite.create_bad_tree_type()
   local repo = test_repo()
   local bad_tree = {
      thingy = { obj = repo:get("HEAD") }
   }
   local ok, msg = gall.tree.create(repo, bad_tree)
   assert(not ok)
   assert(msg:find("commit"))
end

function suite.create_bad_tree_type_flat()
   local repo = test_repo()
   local bad_tree = {
      thingy = { type = "FISH" }
   }
   local ok, msg = gall.tree.create(repo, bad_tree)
   assert(not ok)
   assert(msg:find("FISH"))
end

function suite.create_bad_tree_type_flat_deep()
   local repo = test_repo()
   local bad_tree = {
      ["thingy/wotsit"] = { type = "FISH" }
   }
   local ok, msg = gall.tree.create(repo, bad_tree)
   assert(not ok)
   assert(msg:find("FISH"))
end

function suite.create_bad_sha()
   local repo = test_repo()
   local bad_tree = {
      ["thingy/wotsit"] = { type = "blob", sha = "FISHFISH" }
   }
   local ok, msg = gall.tree.create(repo, bad_tree)
   assert(not ok)
   assert(msg:find("mktree returned"))
end


local count_ok = 0
for _, testname in ipairs(testnames) do
--   print("Run: " .. testname)
   local ok, err = xpcall(suite[testname], debug.traceback)
   if not ok then
      print(err)
      print()
   else
      count_ok = count_ok + 1
   end
end

print(tostring(count_ok) .. "/" .. tostring(#testnames) .. " [" .. tostring(total_asserts) .. "] OK")

os.exit(count_ok == #testnames and 0 or 1)
