Add initial unit test codes using Catch.

Add Kuroga build script.
This commit is contained in:
Syoyo Fujita
2016-04-18 16:03:24 +09:00
parent 54bd46014c
commit 72ef6cbb76
15 changed files with 17897 additions and 11 deletions

13
tests/Makefile Normal file
View File

@@ -0,0 +1,13 @@
.PHONY: clean
tester: tester.cc
g++ -g -O0 -o tester tester.cc
all: tester
check: tester
./tester
clean:
rm -rf tester

25
tests/README.md Normal file
View File

@@ -0,0 +1,25 @@
# Build&Test
## Use makefile
$ make check
## Use ninja + kuroga
Assume
* ninja 1.4+
* python 2.6+
Are installed.
### Linux/MacOSX
$ python kuroga.py config-posix.py
$ ninja
### Windows
> python kuroga.py config-msvc.py
> vcbuild.bat

10445
tests/catch.hpp Normal file

File diff suppressed because it is too large Load Diff

52
tests/config-msvc.py Normal file
View File

@@ -0,0 +1,52 @@
exe = "tester.exe"
toolchain = "msvc"
# optional
link_pool_depth = 1
# optional
builddir = {
"gnu" : "build"
, "msvc" : "build"
, "clang" : "build"
}
includes = {
"gnu" : [ "-I." ]
, "msvc" : [ "/I." ]
, "clang" : [ "-I." ]
}
defines = {
"gnu" : [ "-DEXAMPLE=1" ]
, "msvc" : [ "/DEXAMPLE=1" ]
, "clang" : [ "-DEXAMPLE=1" ]
}
cflags = {
"gnu" : [ "-O2", "-g" ]
, "msvc" : [ "/O2" ]
, "clang" : [ "-O2", "-g" ]
}
cxxflags = {
"gnu" : [ "-O2", "-g" ]
, "msvc" : [ "/O2" ]
, "clang" : [ "-O2", "-g", "-fsanitize=address" ]
}
ldflags = {
"gnu" : [ ]
, "msvc" : [ ]
, "clang" : [ "-fsanitize=address" ]
}
# optionsl
cxx_files = [ "tester.cc" ]
c_files = [ ]
# You can register your own toolchain through register_toolchain function
def register_toolchain(ninja):
pass

53
tests/config-posix.py Normal file
View File

@@ -0,0 +1,53 @@
exe = "tester"
# "gnu" or "clang"
toolchain = "gnu"
# optional
link_pool_depth = 1
# optional
builddir = {
"gnu" : "build"
, "msvc" : "build"
, "clang" : "build"
}
includes = {
"gnu" : [ "-I." ]
, "msvc" : [ "/I." ]
, "clang" : [ "-I." ]
}
defines = {
"gnu" : [ ]
, "msvc" : [ ]
, "clang" : [ ]
}
cflags = {
"gnu" : [ "-O2", "-g" ]
, "msvc" : [ "/O2" ]
, "clang" : [ "-O2", "-g" ]
}
# Warn as much as possible: http://qiita.com/MitsutakaTakeda/items/6b9966f890cc9b944d75
cxxflags = {
"gnu" : [ "-O2", "-g", "-pedantic -Wall -Wextra -Wcast-align -Wcast-qual -Wctor-dtor-privacy -Wdisabled-optimization -Wformat=2 -Winit-self -Wmissing-declarations -Wmissing-include-dirs -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-conversion -Wsign-promo -Wstrict-overflow=5 -Wswitch-default -Wundef -Werror -Wno-unused", "-fsanitize=address" ]
, "msvc" : [ "/O2", "/W4" ]
, "clang" : [ "-O2", "-g", "-Werror -Weverything -Wno-c++98-compat -Wno-c++98-compat-pedantic", "-fsanitize=address" ]
}
ldflags = {
"gnu" : [ "-fsanitize=address" ]
, "msvc" : [ ]
, "clang" : [ "-fsanitize=address" ]
}
cxx_files = [ "tester.cc" ]
c_files = [ ]
# You can register your own toolchain through register_toolchain function
def register_toolchain(ninja):
pass

312
tests/kuroga.py Executable file
View File

@@ -0,0 +1,312 @@
#!/usr/bin/env python
#
# Kuroga, single python file meta-build system for ninja
# https://github.com/lighttransport/kuroga
#
# Requirements: python 2.6 or 2.7
#
# Usage: $ python kuroga.py input.py
#
import imp
import re
import textwrap
import glob
import os
import sys
# gcc preset
def add_gnu_rule(ninja):
ninja.rule('gnucxx', description='CXX $out',
command='$gnucxx -MMD -MF $out.d $gnudefines $gnuincludes $gnucxxflags -c $in -o $out',
depfile='$out.d', deps='gcc')
ninja.rule('gnucc', description='CC $out',
command='$gnucc -MMD -MF $out.d $gnudefines $gnuincludes $gnucflags -c $in -o $out',
depfile='$out.d', deps='gcc')
ninja.rule('gnulink', description='LINK $out', pool='link_pool',
command='$gnuld -o $out $in $libs $gnuldflags')
ninja.rule('gnuar', description='AR $out', pool='link_pool',
command='$gnuar rsc $out $in')
ninja.rule('gnustamp', description='STAMP $out', command='touch $out')
ninja.newline()
ninja.variable('gnucxx', 'g++')
ninja.variable('gnucc', 'gcc')
ninja.variable('gnuld', '$gnucxx')
ninja.variable('gnuar', 'ar')
ninja.newline()
# clang preset
def add_clang_rule(ninja):
ninja.rule('clangcxx', description='CXX $out',
command='$clangcxx -MMD -MF $out.d $clangdefines $clangincludes $clangcxxflags -c $in -o $out',
depfile='$out.d', deps='gcc')
ninja.rule('clangcc', description='CC $out',
command='$clangcc -MMD -MF $out.d $clangdefines $clangincludes $clangcflags -c $in -o $out',
depfile='$out.d', deps='gcc')
ninja.rule('clanglink', description='LINK $out', pool='link_pool',
command='$clangld -o $out $in $libs $clangldflags')
ninja.rule('clangar', description='AR $out', pool='link_pool',
command='$clangar rsc $out $in')
ninja.rule('clangstamp', description='STAMP $out', command='touch $out')
ninja.newline()
ninja.variable('clangcxx', 'clang++')
ninja.variable('clangcc', 'clang')
ninja.variable('clangld', '$clangcxx')
ninja.variable('clangar', 'ar')
ninja.newline()
# msvc preset
def add_msvc_rule(ninja):
ninja.rule('msvccxx', description='CXX $out',
command='$msvccxx /TP /showIncludes $msvcdefines $msvcincludes $msvccxxflags -c $in /Fo$out',
depfile='$out.d', deps='msvc')
ninja.rule('msvccc', description='CC $out',
command='$msvccc /TC /showIncludes $msvcdefines $msvcincludes $msvccflags -c $in /Fo$out',
depfile='$out.d', deps='msvc')
ninja.rule('msvclink', description='LINK $out', pool='link_pool',
command='$msvcld $msvcldflags $in $libs /OUT:$out')
ninja.rule('msvcar', description='AR $out', pool='link_pool',
command='$msvcar $in /OUT:$out')
#ninja.rule('msvcstamp', description='STAMP $out', command='touch $out')
ninja.newline()
ninja.variable('msvccxx', 'cl.exe')
ninja.variable('msvccc', 'cl.exe')
ninja.variable('msvcld', 'link.exe')
ninja.variable('msvcar', 'lib.exe')
ninja.newline()
# -- from ninja_syntax.py --
def escape_path(word):
return word.replace('$ ', '$$ ').replace(' ', '$ ').replace(':', '$:')
class Writer(object):
def __init__(self, output, width=78):
self.output = output
self.width = width
def newline(self):
self.output.write('\n')
def comment(self, text, has_path=False):
for line in textwrap.wrap(text, self.width - 2, break_long_words=False,
break_on_hyphens=False):
self.output.write('# ' + line + '\n')
def variable(self, key, value, indent=0):
if value is None:
return
if isinstance(value, list):
value = ' '.join(filter(None, value)) # Filter out empty strings.
self._line('%s = %s' % (key, value), indent)
def pool(self, name, depth):
self._line('pool %s' % name)
self.variable('depth', depth, indent=1)
def rule(self, name, command, description=None, depfile=None,
generator=False, pool=None, restat=False, rspfile=None,
rspfile_content=None, deps=None):
self._line('rule %s' % name)
self.variable('command', command, indent=1)
if description:
self.variable('description', description, indent=1)
if depfile:
self.variable('depfile', depfile, indent=1)
if generator:
self.variable('generator', '1', indent=1)
if pool:
self.variable('pool', pool, indent=1)
if restat:
self.variable('restat', '1', indent=1)
if rspfile:
self.variable('rspfile', rspfile, indent=1)
if rspfile_content:
self.variable('rspfile_content', rspfile_content, indent=1)
if deps:
self.variable('deps', deps, indent=1)
def build(self, outputs, rule, inputs=None, implicit=None, order_only=None,
variables=None):
outputs = as_list(outputs)
out_outputs = [escape_path(x) for x in outputs]
all_inputs = [escape_path(x) for x in as_list(inputs)]
if implicit:
implicit = [escape_path(x) for x in as_list(implicit)]
all_inputs.append('|')
all_inputs.extend(implicit)
if order_only:
order_only = [escape_path(x) for x in as_list(order_only)]
all_inputs.append('||')
all_inputs.extend(order_only)
self._line('build %s: %s' % (' '.join(out_outputs),
' '.join([rule] + all_inputs)))
if variables:
if isinstance(variables, dict):
iterator = iter(variables.items())
else:
iterator = iter(variables)
for key, val in iterator:
self.variable(key, val, indent=1)
return outputs
def include(self, path):
self._line('include %s' % path)
def subninja(self, path):
self._line('subninja %s' % path)
def default(self, paths):
self._line('default %s' % ' '.join(as_list(paths)))
def _count_dollars_before_index(self, s, i):
"""Returns the number of '$' characters right in front of s[i]."""
dollar_count = 0
dollar_index = i - 1
while dollar_index > 0 and s[dollar_index] == '$':
dollar_count += 1
dollar_index -= 1
return dollar_count
def _line(self, text, indent=0):
"""Write 'text' word-wrapped at self.width characters."""
leading_space = ' ' * indent
while len(leading_space) + len(text) > self.width:
# The text is too wide; wrap if possible.
# Find the rightmost space that would obey our width constraint and
# that's not an escaped space.
available_space = self.width - len(leading_space) - len(' $')
space = available_space
while True:
space = text.rfind(' ', 0, space)
if (space < 0 or
self._count_dollars_before_index(text, space) % 2 == 0):
break
if space < 0:
# No such space; just use the first unescaped space we can find.
space = available_space - 1
while True:
space = text.find(' ', space + 1)
if (space < 0 or
self._count_dollars_before_index(text, space) % 2 == 0):
break
if space < 0:
# Give up on breaking.
break
self.output.write(leading_space + text[0:space] + ' $\n')
text = text[space+1:]
# Subsequent lines are continuations, so indent them.
leading_space = ' ' * (indent+2)
self.output.write(leading_space + text + '\n')
def close(self):
self.output.close()
def as_list(input):
if input is None:
return []
if isinstance(input, list):
return input
return [input]
# -- end from ninja_syntax.py --
def gen(ninja, toolchain, config):
ninja.variable('ninja_required_version', '1.4')
ninja.newline()
if hasattr(config, "builddir"):
builddir = config.builddir[toolchain]
ninja.variable(toolchain + 'builddir', builddir)
else:
builddir = ''
ninja.variable(toolchain + 'defines', config.defines[toolchain] or [])
ninja.variable(toolchain + 'includes', config.includes[toolchain] or [])
ninja.variable(toolchain + 'cflags', config.cflags[toolchain] or [])
ninja.variable(toolchain + 'cxxflags', config.cxxflags[toolchain] or [])
ninja.variable(toolchain + 'ldflags', config.ldflags[toolchain] or [])
ninja.newline()
if hasattr(config, "link_pool_depth"):
ninja.pool('link_pool', depth=config.link_pool_depth)
else:
ninja.pool('link_pool', depth=4)
ninja.newline()
# Add default toolchain(gnu, clang and msvc)
add_gnu_rule(ninja)
add_clang_rule(ninja)
add_msvc_rule(ninja)
obj_files = []
cc = toolchain + 'cc'
cxx = toolchain + 'cxx'
link = toolchain + 'link'
ar = toolchain + 'ar'
if hasattr(config, "cxx_files"):
for src in config.cxx_files:
srcfile = src
obj = os.path.splitext(srcfile)[0] + '.o'
obj = os.path.join(builddir, obj);
obj_files.append(obj)
ninja.build(obj, cxx, srcfile)
ninja.newline()
if hasattr(config, "c_files"):
for src in config.c_files:
srcfile = src
obj = os.path.splitext(srcfile)[0] + '.o'
obj = os.path.join(builddir, obj);
obj_files.append(obj)
ninja.build(obj, cc, srcfile)
ninja.newline()
targetlist = []
if hasattr(config, "exe"):
ninja.build(config.exe, link, obj_files)
targetlist.append(config.exe)
if hasattr(config, "staticlib"):
ninja.build(config.staticlib, ar, obj_files)
targetlist.append(config.staticlib)
ninja.build('all', 'phony', targetlist)
ninja.newline()
ninja.default('all')
def main():
if len(sys.argv) < 2:
print("Usage: python kuroga.py config.py")
sys.exit(1)
config = imp.load_source("config", sys.argv[1])
f = open('build.ninja', 'w')
ninja = Writer(f)
if hasattr(config, "register_toolchain"):
config.register_toolchain(ninja)
gen(ninja, config.toolchain, config)
f.close()
main()

324
tests/tester.cc Normal file
View File

@@ -0,0 +1,324 @@
#define TINYOBJLOADER_IMPLEMENTATION
#include "../tiny_obj_loader.h"
#define CATCH_CONFIG_MAIN // This tells Catch to provide a main() - only do this in one cpp file
#include "catch.hpp"
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <iostream>
#include <sstream>
#include <fstream>
static void PrintInfo(const tinyobj::attrib_t &attrib, const std::vector<tinyobj::shape_t>& shapes, const std::vector<tinyobj::material_t>& materials, bool triangulate = true)
{
std::cout << "# of vertices : " << (attrib.vertices.size() / 3) << std::endl;
std::cout << "# of normals : " << (attrib.normals.size() / 3) << std::endl;
std::cout << "# of texcoords : " << (attrib.texcoords.size() / 2) << std::endl;
std::cout << "# of shapes : " << shapes.size() << std::endl;
std::cout << "# of materials : " << materials.size() << std::endl;
for (size_t v = 0; v < attrib.vertices.size() / 3; v++) {
printf(" v[%ld] = (%f, %f, %f)\n", v,
static_cast<const double>(attrib.vertices[3*v+0]),
static_cast<const double>(attrib.vertices[3*v+1]),
static_cast<const double>(attrib.vertices[3*v+2]));
}
for (size_t v = 0; v < attrib.normals.size() / 3; v++) {
printf(" n[%ld] = (%f, %f, %f)\n", v,
static_cast<const double>(attrib.normals[3*v+0]),
static_cast<const double>(attrib.normals[3*v+1]),
static_cast<const double>(attrib.normals[3*v+2]));
}
for (size_t v = 0; v < attrib.texcoords.size() / 2; v++) {
printf(" uv[%ld] = (%f, %f)\n", v,
static_cast<const double>(attrib.texcoords[2*v+0]),
static_cast<const double>(attrib.texcoords[2*v+1]));
}
for (size_t i = 0; i < shapes.size(); i++) {
printf("shape[%ld].name = %s\n", i, shapes[i].name.c_str());
printf("Size of shape[%ld].indices: %ld\n", i, shapes[i].mesh.indices.size());
if (triangulate)
{
printf("Size of shape[%ld].material_ids: %ld\n", i, shapes[i].mesh.material_ids.size());
assert((shapes[i].mesh.indices.size() % 3) == 0);
for (size_t f = 0; f < shapes[i].mesh.indices.size() / 3; f++) {
tinyobj::index_t i0 = shapes[i].mesh.indices[3*f+0];
tinyobj::index_t i1 = shapes[i].mesh.indices[3*f+1];
tinyobj::index_t i2 = shapes[i].mesh.indices[3*f+2];
printf(" idx[%ld] = %d/%d/%d, %d/%d/%d, %d/%d/%d. mat_id = %d\n", f,
i0.vertex_index, i0.normal_index, i0.texcoord_index,
i1.vertex_index, i1.normal_index, i1.texcoord_index,
i2.vertex_index, i2.normal_index, i2.texcoord_index,
shapes[i].mesh.material_ids[f]);
}
} else {
for (size_t f = 0; f < shapes[i].mesh.indices.size(); f++) {
tinyobj::index_t idx = shapes[i].mesh.indices[f];
printf(" idx[%ld] = %d/%d/%d\n", f, idx.vertex_index, idx.normal_index, idx.texcoord_index);
}
printf("Size of shape[%ld].material_ids: %ld\n", i, shapes[i].mesh.material_ids.size());
assert(shapes[i].mesh.material_ids.size() == shapes[i].mesh.num_vertices.size());
for (size_t m = 0; m < shapes[i].mesh.material_ids.size(); m++) {
printf(" material_id[%ld] = %d\n", m,
shapes[i].mesh.material_ids[m]);
}
}
printf("shape[%ld].num_faces: %ld\n", i, shapes[i].mesh.num_vertices.size());
for (size_t v = 0; v < shapes[i].mesh.num_vertices.size(); v++) {
printf(" num_vertices[%ld] = %ld\n", v,
static_cast<long>(shapes[i].mesh.num_vertices[v]));
}
//printf("shape[%ld].vertices: %ld\n", i, shapes[i].mesh.positions.size());
//assert((shapes[i].mesh.positions.size() % 3) == 0);
//for (size_t v = 0; v < shapes[i].mesh.positions.size() / 3; v++) {
// printf(" v[%ld] = (%f, %f, %f)\n", v,
// static_cast<const double>(shapes[i].mesh.positions[3*v+0]),
// static_cast<const double>(shapes[i].mesh.positions[3*v+1]),
// static_cast<const double>(shapes[i].mesh.positions[3*v+2]));
//}
printf("shape[%ld].num_tags: %ld\n", i, shapes[i].mesh.tags.size());
for (size_t t = 0; t < shapes[i].mesh.tags.size(); t++) {
printf(" tag[%ld] = %s ", t, shapes[i].mesh.tags[t].name.c_str());
printf(" ints: [");
for (size_t j = 0; j < shapes[i].mesh.tags[t].intValues.size(); ++j)
{
printf("%ld", static_cast<long>(shapes[i].mesh.tags[t].intValues[j]));
if (j < (shapes[i].mesh.tags[t].intValues.size()-1))
{
printf(", ");
}
}
printf("]");
printf(" floats: [");
for (size_t j = 0; j < shapes[i].mesh.tags[t].floatValues.size(); ++j)
{
printf("%f", static_cast<const double>(shapes[i].mesh.tags[t].floatValues[j]));
if (j < (shapes[i].mesh.tags[t].floatValues.size()-1))
{
printf(", ");
}
}
printf("]");
printf(" strings: [");
for (size_t j = 0; j < shapes[i].mesh.tags[t].stringValues.size(); ++j)
{
printf("%s", shapes[i].mesh.tags[t].stringValues[j].c_str());
if (j < (shapes[i].mesh.tags[t].stringValues.size()-1))
{
printf(", ");
}
}
printf("]");
printf("\n");
}
}
for (size_t i = 0; i < materials.size(); i++) {
printf("material[%ld].name = %s\n", i, materials[i].name.c_str());
printf(" material.Ka = (%f, %f ,%f)\n", static_cast<const double>(materials[i].ambient[0]), static_cast<const double>(materials[i].ambient[1]), static_cast<const double>(materials[i].ambient[2]));
printf(" material.Kd = (%f, %f ,%f)\n", static_cast<const double>(materials[i].diffuse[0]), static_cast<const double>(materials[i].diffuse[1]), static_cast<const double>(materials[i].diffuse[2]));
printf(" material.Ks = (%f, %f ,%f)\n", static_cast<const double>(materials[i].specular[0]), static_cast<const double>(materials[i].specular[1]), static_cast<const double>(materials[i].specular[2]));
printf(" material.Tr = (%f, %f ,%f)\n", static_cast<const double>(materials[i].transmittance[0]), static_cast<const double>(materials[i].transmittance[1]), static_cast<const double>(materials[i].transmittance[2]));
printf(" material.Ke = (%f, %f ,%f)\n", static_cast<const double>(materials[i].emission[0]), static_cast<const double>(materials[i].emission[1]), static_cast<const double>(materials[i].emission[2]));
printf(" material.Ns = %f\n", static_cast<const double>(materials[i].shininess));
printf(" material.Ni = %f\n", static_cast<const double>(materials[i].ior));
printf(" material.dissolve = %f\n", static_cast<const double>(materials[i].dissolve));
printf(" material.illum = %d\n", materials[i].illum);
printf(" material.map_Ka = %s\n", materials[i].ambient_texname.c_str());
printf(" material.map_Kd = %s\n", materials[i].diffuse_texname.c_str());
printf(" material.map_Ks = %s\n", materials[i].specular_texname.c_str());
printf(" material.map_Ns = %s\n", materials[i].specular_highlight_texname.c_str());
printf(" material.map_bump = %s\n", materials[i].bump_texname.c_str());
printf(" material.map_d = %s\n", materials[i].alpha_texname.c_str());
printf(" material.disp = %s\n", materials[i].displacement_texname.c_str());
std::map<std::string, std::string>::const_iterator it(materials[i].unknown_parameter.begin());
std::map<std::string, std::string>::const_iterator itEnd(materials[i].unknown_parameter.end());
for (; it != itEnd; it++) {
printf(" material.%s = %s\n", it->first.c_str(), it->second.c_str());
}
printf("\n");
}
}
static bool
TestLoadObj(
const char* filename,
const char* basepath = NULL,
bool triangulate = true)
{
std::cout << "Loading " << filename << std::endl;
tinyobj::attrib_t attrib;
std::vector<tinyobj::shape_t> shapes;
std::vector<tinyobj::material_t> materials;
std::string err;
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &err, filename, basepath, triangulate);
if (!err.empty()) {
std::cerr << err << std::endl;
}
if (!ret) {
printf("Failed to load/parse .obj.\n");
return false;
}
PrintInfo(attrib, shapes, materials, triangulate);
return true;
}
static bool
TestStreamLoadObj()
{
std::cout << "Stream Loading " << std::endl;
std::stringstream objStream;
objStream
<< "mtllib cube.mtl\n"
"\n"
"v 0.000000 2.000000 2.000000\n"
"v 0.000000 0.000000 2.000000\n"
"v 2.000000 0.000000 2.000000\n"
"v 2.000000 2.000000 2.000000\n"
"v 0.000000 2.000000 0.000000\n"
"v 0.000000 0.000000 0.000000\n"
"v 2.000000 0.000000 0.000000\n"
"v 2.000000 2.000000 0.000000\n"
"# 8 vertices\n"
"\n"
"g front cube\n"
"usemtl white\n"
"f 1 2 3 4\n"
"g back cube\n"
"# expects white material\n"
"f 8 7 6 5\n"
"g right cube\n"
"usemtl red\n"
"f 4 3 7 8\n"
"g top cube\n"
"usemtl white\n"
"f 5 1 4 8\n"
"g left cube\n"
"usemtl green\n"
"f 5 6 2 1\n"
"g bottom cube\n"
"usemtl white\n"
"f 2 6 7 3\n"
"# 6 elements";
std::string matStream(
"newmtl white\n"
"Ka 0 0 0\n"
"Kd 1 1 1\n"
"Ks 0 0 0\n"
"\n"
"newmtl red\n"
"Ka 0 0 0\n"
"Kd 1 0 0\n"
"Ks 0 0 0\n"
"\n"
"newmtl green\n"
"Ka 0 0 0\n"
"Kd 0 1 0\n"
"Ks 0 0 0\n"
"\n"
"newmtl blue\n"
"Ka 0 0 0\n"
"Kd 0 0 1\n"
"Ks 0 0 0\n"
"\n"
"newmtl light\n"
"Ka 20 20 20\n"
"Kd 1 1 1\n"
"Ks 0 0 0");
using namespace tinyobj;
class MaterialStringStreamReader:
public MaterialReader
{
public:
MaterialStringStreamReader(const std::string& matSStream): m_matSStream(matSStream) {}
virtual ~MaterialStringStreamReader() {}
virtual bool operator() (
const std::string& matId,
std::vector<material_t>* materials,
std::map<std::string, int>* matMap,
std::string* err)
{
(void)matId;
(void)err;
LoadMtl(matMap, materials, &m_matSStream);
return true;
}
private:
std::stringstream m_matSStream;
};
MaterialStringStreamReader matSSReader(matStream);
tinyobj::attrib_t attrib;
std::vector<tinyobj::shape_t> shapes;
std::vector<tinyobj::material_t> materials;
std::string err;
bool ret = tinyobj::LoadObj(&attrib, &shapes, &materials, &err, &objStream, &matSSReader);
if (!err.empty()) {
std::cerr << err << std::endl;
}
if (!ret) {
return false;
}
PrintInfo(attrib, shapes, materials);
return true;
}
const char* gMtlBasePath = "../models";
TEST_CASE("cornell_box", "[Loader]") {
REQUIRE(true == TestLoadObj("../models/cornell_box.obj", gMtlBasePath));
}
#if 0
int
main(
int argc,
char **argv)
{
if (argc > 1) {
const char* basepath = NULL;
if (argc > 2) {
basepath = argv[2];
}
assert(true == TestLoadObj(argv[1], basepath));
} else {
//assert(true == TestLoadObj("cornell_box.obj"));
//assert(true == TestLoadObj("cube.obj"));
assert(true == TestStreamLoadObj());
assert(true == TestLoadObj("catmark_torus_creases0.obj", NULL, false));
}
return 0;
}
#endif

3
tests/vcbuild.bat Normal file
View File

@@ -0,0 +1,3 @@
chcp 437
call "C:\Program Files (x86)\Microsoft Visual Studio 12.0\VC\vcvarsall.bat" x86_amd64
ninja