First commit

This commit is contained in:
2021-03-07 05:58:59 +01:00
committed by Andreas Schaafsma
commit 6e1a5f9fe5
18475 changed files with 3309357 additions and 0 deletions

View File

@@ -0,0 +1,59 @@
import haxelib.client.Vcs.VcsID;
import haxe.unit.TestRunner;
import sys.*;
import sys.io.*;
import tests.*;
using StringTools;
class HaxelibTests {
public static function runCommand(cmd:String, args:Array<String>):Void
{
Sys.println('Command: $cmd $args');
var exitCode = Sys.command(cmd, args);
Sys.println('Command exited with $exitCode: $cmd $args');
if(exitCode != 0)
Sys.exit(exitCode);
}
static function cmdSucceed(cmd:String, ?args:Array<String>):Bool {
var p = try {
new Process(cmd, args);
} catch(e:Dynamic) {
return false;
}
var exitCode = p.exitCode();
p.close();
return exitCode == 0;
}
static function main():Void {
var r = new TestRunner();
r.add(new TestSemVer());
r.add(new TestData());
r.add(new TestRemoveSymlinks());
r.add(new TestRemoveSymlinksBroken());
var isCI = Sys.getEnv("CI") != null;
if (isCI || cmdSucceed("hg", ["version"])) {
// Hg impl. suports tags & revs. Here "78edb4b" is a first revision "initial import" at that repo:
r.add(new TestHg());
} else {
Sys.println("hg not found.");
}
if (isCI || cmdSucceed("git", ["version"])) {
// Git impl. suports only tags. Here "0.9.2" is a first revision too ("initial import"):
r.add(new TestGit());
} else {
Sys.println("git not found.");
}
r.add(new TestVcsNotFound());
var success = r.run();
Sys.exit(success ? 0 : 1);
}
}

View File

@@ -0,0 +1,174 @@
import haxe.unit.*;
import haxe.*;
import haxe.io.*;
import sys.*;
import sys.io.*;
import haxelib.*;
using StringTools;
using IntegrationTests;
class IntegrationTests extends TestBase {
var haxelibBin:String = Path.join([Sys.getCwd(), "run.n"]);
public var server(default, null):String = switch (Sys.getEnv("HAXELIB_SERVER")) {
case null:
"localhost";
case url:
url;
};
public var serverPort(default, null) = switch (Sys.getEnv("HAXELIB_SERVER_PORT")) {
case null:
2000;
case port:
Std.parseInt(port);
};
public var serverUrl(get, null):String;
function get_serverUrl() return serverUrl != null ? serverUrl : serverUrl = 'http://${server}:${serverPort}/';
static var originalRepo(default, never) = {
var p = new Process("haxelib", ["config"]);
var repo = Path.normalize(p.stdout.readLine());
p.close();
repo;
};
static public var repo(default, never) = "repo_integration_tests";
static public var bar(default, never) = {
user: "Bar",
email: "bar@haxe.org",
fullname: "Bar",
pw: "barpassword",
};
static public var foo(default, never) = {
user: "Foo",
email: "foo@haxe.org",
fullname: "Foo",
pw: "foopassword",
};
public var clientVer(get, null):SemVer;
var clientVer_inited = false;
function get_clientVer() {
return if (clientVer_inited)
clientVer;
else {
clientVer = {
var r = haxelib(["version"]).result();
if (r.code == 0)
SemVer.ofString(r.out.trim());
else if (r.out.indexOf("3.1.0-rc.4") >= 0)
SemVer.ofString("3.1.0-rc.4");
else
throw "unknown version";
};
clientVer_inited = true;
clientVer;
}
}
function haxelib(args:Array<String>, ?input:String):Process {
var p = #if system_haxelib
new Process("haxelib", ["-R", serverUrl].concat(args));
#else
new Process("neko", [haxelibBin, "-R", serverUrl].concat(args));
#end
if (input != null) {
p.stdin.writeString(input);
p.stdin.close();
}
return p;
}
function assertSuccess(r:{out:String, err:String, code:Int}, ?pos:haxe.PosInfos):Void {
if (r.code != 0) {
throw r;
}
assertEquals(0, r.code, pos);
}
function assertNoError(f:Void->Void):Void {
f();
assertTrue(true);
}
var dbConfig:Dynamic = Json.parse(File.getContent("www/dbconfig.json"));
var dbCnx:sys.db.Connection;
function resetDB():Void {
var db = dbConfig.database;
dbCnx.request('DROP DATABASE IF EXISTS ${db};');
dbCnx.request('CREATE DATABASE ${db};');
var filesPath = "www/files/3.0";
for (item in FileSystem.readDirectory(filesPath)) {
if (item.endsWith(".zip")) {
FileSystem.deleteFile(Path.join([filesPath, item]));
}
}
var tmpPath = "tmp";
for (item in FileSystem.readDirectory(filesPath)) {
if (item.endsWith(".tmp")) {
FileSystem.deleteFile(Path.join([tmpPath, item]));
}
}
}
override function setup():Void {
super.setup();
dbCnx = sys.db.Mysql.connect({
user: dbConfig.user,
pass: dbConfig.pass,
host: server,
port: dbConfig.port,
database: dbConfig.database,
});
resetDB();
deleteDirectory(repo);
haxelibSetup(repo);
}
override function tearDown():Void {
haxelibSetup(originalRepo);
deleteDirectory(repo);
resetDB();
dbCnx.close();
super.tearDown();
}
static public function result(p:Process):{out:String, err:String, code:Int} {
var out = p.stdout.readAll().toString();
var err = p.stderr.readAll().toString();
var code = p.exitCode();
p.close();
return {out:out, err:err, code:code};
}
static public function haxelibSetup(path:String):Void {
var p = new Process("haxelib", ["setup", path]);
if (p.exitCode() != 0)
throw "unable to set haxelib repo to " + path;
p.close();
}
static function main():Void {
var prevDir = Sys.getCwd();
var runner = new TestRunner();
runner.add(new tests.integration.TestEmpty());
runner.add(new tests.integration.TestSimple());
runner.add(new tests.integration.TestUpgrade());
runner.add(new tests.integration.TestUpdate());
runner.add(new tests.integration.TestList());
runner.add(new tests.integration.TestSet());
runner.add(new tests.integration.TestInfo());
runner.add(new tests.integration.TestUser());
runner.add(new tests.integration.TestDev());
var success = runner.run();
if (!success) {
Sys.exit(1);
}
}
}

View File

@@ -0,0 +1,52 @@
import sys.*;
import sys.io.*;
import haxe.io.*;
using StringTools;
class Prepare {
static function zipDir(dir:String, outPath:String):Void {
var entries = new List<haxe.zip.Entry>();
function add(path:String, target:String) {
if (!FileSystem.exists(path))
throw 'Invalid path: $path';
if (FileSystem.isDirectory(path)) {
for (item in FileSystem.readDirectory(path))
add(path + "/" + item, target == "" ? item : target + "/" + item);
} else {
var bytes = File.getBytes(path);
var entry:haxe.zip.Entry = {
fileName: target,
fileSize: bytes.length,
fileTime: FileSystem.stat(path).mtime,
compressed: false,
dataSize: 0,
data: bytes,
crc32: haxe.crypto.Crc32.make(bytes),
}
haxe.zip.Tools.compress(entry, 9);
entries.add(entry);
}
}
add(dir, "");
var out = File.write(outPath, true);
var writer = new haxe.zip.Writer(out);
writer.write(entries);
out.close();
}
static function main():Void {
/*
(re)package the dummy libraries
*/
var libsPath = "test/libraries";
for (item in FileSystem.readDirectory(libsPath)) {
var path = Path.join([libsPath, item]);
if (FileSystem.isDirectory(path)) {
zipDir(path, 'test/libraries/${item}.zip');
}
}
}
}

View File

@@ -0,0 +1,329 @@
import Sys.*;
import haxe.*;
import haxe.io.*;
import sys.FileSystem.*;
import sys.io.File.*;
class RunCi {
static function successMsg(msg:String):Void {
Sys.println('\x1b[32m' + msg + '\x1b[0m');
}
static function failMsg(msg:String):Void {
Sys.println('\x1b[31m' + msg + '\x1b[0m');
}
static function infoMsg(msg:String):Void {
Sys.println('\x1b[36m' + msg + '\x1b[0m');
}
/**
Run a command using `Sys.command()`.
If the command exits with non-zero code, exit the whole script with the same code.
If `useRetry` is `true`, the command will be re-run if it exits with non-zero code (3 trials).
It is useful for running network-dependent commands.
*/
static function runCommand(cmd:String, ?args:Array<String>, useRetry:Bool = false):Void {
var trials = useRetry ? 3 : 1;
var exitCode:Int = 1;
var cmdStr = cmd + (args != null ? ' $args' : '');
while (trials-->0) {
Sys.println("Command: " + cmdStr);
var t = Timer.stamp();
exitCode = Sys.command(cmd, args);
var dt = Math.round(Timer.stamp() - t);
if (exitCode == 0)
successMsg('Command exited with $exitCode in ${dt}s: $cmdStr');
else
failMsg('Command exited with $exitCode in ${dt}s: $cmdStr');
if (exitCode == 0) {
return;
} else if (trials > 0) {
Sys.println('Command will be re-run...');
}
}
Sys.exit(exitCode);
}
static function download(url:String, saveAs:String):Void {
infoMsg('download $url as $saveAs');
runCommand("curl", ["-fSLk", url, "-o", saveAs, "-A", "Mozilla/4.0"]);
}
static function compileServer():Void {
runCommand("haxe", ["server.hxml"]);
}
static function compileLegacyServer():Void {
runCommand("haxe", ["server_legacy.hxml"]);
}
static function compileClient():Void {
runCommand("haxe", ["client.hxml"]);
}
static function compileLegacyClient():Void {
runCommand("haxe", ["client_legacy.hxml"]);
}
static function testClient():Void {
runCommand("haxe", ["client_tests.hxml"]);
}
static function testServer():Void {
runCommand("haxe", ["server_tests.hxml"]);
}
static function setupLocalServer():Void {
var ndllPath = getEnv("NEKOPATH");
if (ndllPath == null) ndllPath = "/usr/lib/neko";
var DocumentRoot = Path.join([getCwd(), "www"]);
var dbConfigPath = Path.join(["www", "dbconfig.json"]);
var dbConfig = Json.parse(getContent(dbConfigPath));
// update dbConfig.host to be "localhost"
saveContent(dbConfigPath, Json.stringify({
user: dbConfig.user,
pass: dbConfig.pass,
host: "localhost",
database: dbConfig.database,
}));
function writeApacheConf(confPath:String):Void {
var hasModNeko = switch (systemName()) {
case "Windows":
false;
case _:
var p = new sys.io.Process("apachectl", ["-M"]);
var out = p.stdout.readAll().toString();
var has = out.indexOf("neko_module") >= 0;
p.close();
has;
}
var confContent =
(
if (systemName() == "Windows")
"LoadModule rewrite_module modules/mod_rewrite.so\n"
else
""
) +
(
if (hasModNeko)
""
else
'LoadModule neko_module ${Path.join([ndllPath, "mod_neko2.ndll"])}\n'
) +
'LoadModule tora_module ${Path.join([ndllPath, "mod_tora2.ndll"])}
AddHandler tora-handler .n
Listen 2000
<VirtualHost *:2000>
DocumentRoot "$DocumentRoot"
</VirtualHost>
<Directory "$DocumentRoot">
Options Indexes FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
</Directory>
';
var confOut = if (exists(confPath))
append(confPath);
else
write(confPath);
confOut.writeString(confContent);
confOut.flush();
confOut.close();
}
function configDb():Void {
var isAppVeyor = getEnv("APPVEYOR") != null;
var user = if (isAppVeyor)
// https://www.appveyor.com/docs/services-databases#mysql
{ user: "root", pass: "Password12!" };
else
{ user: "root", pass: "" };
var cnx = sys.db.Mysql.connect({
user: user.user,
pass: user.pass,
host: "localhost",
port: 3306,
database: "",
});
cnx.request('create user \'${dbConfig.user}\'@\'localhost\' identified by \'${dbConfig.pass}\';');
cnx.request('create database ${dbConfig.database};');
cnx.request('grant all on ${dbConfig.database}.* to \'${dbConfig.user}\'@\'localhost\';');
cnx.close();
}
switch (systemName()) {
case "Windows":
configDb();
download("https://www.apachelounge.com/download/win32/binaries/httpd-2.2.31-win32.zip", "bin/httpd.zip");
runCommand("7z", ["x", "bin\\httpd.zip", "-obin\\httpd"]);
writeApacheConf("bin\\httpd\\Apache2\\conf\\httpd.conf");
rename("bin\\httpd\\Apache2", "c:\\Apache2");
var serviceName = "HaxelibApache";
var httpd = "c:\\Apache2\\bin\\httpd.exe";
runCommand(httpd, ["-k", "install", "-n", serviceName]);
runCommand(httpd, ["-n", serviceName, "-t"]);
runCommand(httpd, ["-k", "start", "-n", serviceName]);
var toraPath = {
var p = new sys.io.Process("haxelib", ["path", "tora"]);
var path = p.stdout.readLine();
p.close();
path;
}
runCommand("nssm", ["install", "tora", Path.join([getEnv("NEKOPATH"), "neko.exe"]), Path.join([toraPath, "run.n"])]);
runCommand("nssm", ["start", "tora"]);
Sys.sleep(2.5);
case "Mac":
runCommand("brew", ["install", "homebrew/apache/httpd22", "mysql"]);
runCommand("mysql.server", ["start"]);
configDb();
runCommand("apachectl", ["start"]);
Sys.sleep(2.5);
writeApacheConf("/usr/local/etc/apache2/2.2/httpd.conf");
Sys.sleep(2.5);
runCommand("apachectl", ["restart"]);
Sys.sleep(2.5);
case "Linux":
configDb();
runCommand("sudo", ["apt-get", "install", "apache2"]);
writeApacheConf("haxelib.conf");
runCommand("sudo", ["ln", "-s", Path.join([Sys.getCwd(), "haxelib.conf"]), "/etc/apache2/conf.d/haxelib.conf"]);
runCommand("sudo", ["a2enmod", "rewrite"]);
runCommand("sudo", ["service", "apache2", "restart"]);
Sys.sleep(2.5);
case name:
throw "System not supported: " + name;
}
Sys.setCwd("www");
runCommand("bower", ["install"]);
Sys.setCwd("..");
Sys.putEnv("HAXELIB_SERVER", "localhost");
Sys.putEnv("HAXELIB_SERVER_PORT", "2000");
}
static function runWithDockerServer(test:Void->Void):Void {
var server = switch (systemName()) {
case "Linux":
"localhost";
case _:
var p = new sys.io.Process("docker-machine", ["ip"]);
var ip = p.stdout.readLine();
p.close();
ip;
}
var serverPort = 2000;
runCommand("docker-compose", ["-f", "test/docker-compose.yml", "up", "-d"]);
Sys.putEnv("HAXELIB_SERVER", server);
Sys.putEnv("HAXELIB_SERVER_PORT", Std.string(serverPort));
infoMsg("waiting for server to start...");
var url = 'http://${server}:${serverPort}/';
var t = Timer.stamp();
while (true) {
var isUp = try {
var response = haxe.Http.requestUrl(url);
!StringTools.startsWith(response, "Error");
} catch (e:Dynamic) {
false;
}
if (isUp) {
break;
}
if (Timer.stamp() - t > 120) {
throw "server is not reachable...";
}
Sys.sleep(10.0);
// Sys.command("curl", ["-s", "-o", "/dev/null", "-w", "%{http_code}", url]);
}
infoMsg("server started");
test();
runCommand("docker-compose", ["-f", "test/docker-compose.yml", "down"]);
}
static function integrationTests():Void {
function test():Void {
switch (Sys.getEnv("TRAVIS_HAXE_VERSION")) {
case null, "development":
runCommand("haxe", ["integration_tests.hxml"]);
case "3.1.3":
runCommand("haxe", ["integration_tests.hxml", "-D", "system_haxelib"]);
case _:
runCommand("haxe", ["integration_tests.hxml"]);
runCommand("haxe", ["integration_tests.hxml", "-D", "system_haxelib"]);
}
}
if (Sys.getEnv("CI") != null && Sys.getEnv("USE_DOCKER") == null) {
setupLocalServer();
test();
} else {
runWithDockerServer(test);
}
}
static function installDotNet11():Void {
// This is a msvcr71.dll in my own dropbox. If you want to obtain one, you probably shouldn't use my file.
// Instead, install .Net Framework 1.1 from the link as follows
// https://www.microsoft.com/en-us/download/details.aspx?id=26
download("https://dl.dropboxusercontent.com/u/2661116/msvcr71.dll", Path.join([getEnv("NEKOPATH"), "msvcr71.dll"]));
}
static function main():Void {
// Note that package.zip output is also used by client tests, so it has to be run before that.
runCommand("haxe", ["package.hxml"]);
runCommand("haxe", ["prepare_tests.hxml"]);
compileLegacyClient();
compileLegacyServer();
// the server can only be compiled with haxe 3.2+
// haxe 3.1.3 bundles haxelib client 3.1.0-rc.4, which is not upgradable to later haxelib
// so there is no need to test the client either
#if (haxe_ver >= 3.2)
compileClient();
testClient();
compileServer();
if (systemName() == "Windows") {
// The Neko 2.0 Windows binary archive is missing "msvcr71.dll", which is a dependency of "sqlite.ndll".
// https://github.com/HaxeFoundation/haxe/issues/2008#issuecomment-176849497
installDotNet11();
}
testServer();
#end
// integration test
switch (systemName()) {
case "Windows", "Linux":
integrationTests();
case "Mac":
#if (haxe_ver >= 3.2)
integrationTests();
#end
case _:
throw "Unknown system";
}
}
}

View File

@@ -0,0 +1,33 @@
import sys.*;
import sys.io.*;
import haxe.io.*;
import haxe.unit.*;
class TestBase extends TestCase {
static var haxelibPath = FileSystem.fullPath("run.n");
public function runHaxelib(args:Array<String>) {
var p = new Process("neko", [haxelibPath].concat(args));
var stdout = p.stdout.readAll().toString();
var stderr = p.stderr.readAll().toString();
var exitCode = p.exitCode();
p.close();
return {
stdout: stdout,
stderr: stderr,
exitCode: exitCode
}
}
public function deleteDirectory(dir:String):Void {
if (!FileSystem.exists(dir)) return;
var exitCode = switch (Sys.systemName()) {
case "Windows":
Sys.command("rmdir", ["/S", "/Q", StringTools.replace(FileSystem.fullPath(dir), "/", "\\")]);
case _:
Sys.command("rm", ["-rf", dir]);
}
if (exitCode != 0) {
throw 'unable to delete $dir';
}
}
}

View File

@@ -0,0 +1,44 @@
package;
import website.api.ProjectListApi;
import ufront.app.UfrontApplication;
import ufront.mailer.*;
import ufront.auth.EasyAuth;
import ufront.view.TemplatingEngines;
import twl.webapp.*;
import twl.*;
import buddy.*;
@:build(buddy.GenerateMain.withSuites([
website.controller.DocumentationControllerTest,
website.controller.HomeControllerTest,
// website.controller.ProjectControllerTest,
website.controller.RSSControllerTest,
// website.controller.UserControllerTest,
]))
class WebsiteTests {
static var ufApp:UfrontApplication;
public static function getTestApp():UfrontApplication {
if ( ufApp==null ) {
// Create a UfrontApplication suitable for unit testing.
ufApp = new UfrontApplication({
indexController: website.controller.HomeController,
errorHandlers: [],
disableBrowserTrace: true,
contentDirectory: "../uf-content/",
templatingEngines: [TemplatingEngines.erazor],
viewPath: "www/view/",
defaultLayout: "layout.html",
});
// Different injections for our test suite.
ufApp.injector.map( UFMailer ).toSingleton( TestMailer );
ufApp.injector.map( EasyAuth ).toValue( new EasyAuthAdminMode() );
ufApp.injector.map( String, "documentationPath" ).toValue( "www/documentation-files/" );
haxelib.server.SiteDb.init();
}
return ufApp;
}
}

View File

@@ -0,0 +1,21 @@
version: '2'
services:
web:
image: andyli/tora
ports:
- "2000:80"
volumes:
- ../www:/var/www/html
dbHost:
image: mariadb
ports:
- "3306:3306"
environment:
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
- MYSQL_DATABASE=haxelib
- MYSQL_USER=dbUser
- MYSQL_PASSWORD=dbPass
volumes:
- database:/var/lib/mysql
volumes:
database: {}

View File

@@ -0,0 +1,19 @@
version: '2'
services:
web:
build: ..
ports:
- "2000:80"
dbHost:
image: mariadb
ports:
- "3306:3306"
environment:
- MYSQL_ALLOW_EMPTY_PASSWORD=yes
- MYSQL_DATABASE=haxelib
- MYSQL_USER=dbUser
- MYSQL_PASSWORD=dbPass
volumes:
- database:/var/lib/mysql
volumes:
database: {}

View File

@@ -0,0 +1,11 @@
{
"name": "UseCp",
"url" : "http://example.org",
"license": "GPL",
"tags": [],
"description": "This project use a deep class path.",
"version": "0.0.1",
"releasenote": "Initial release, everything is working correctly",
"classPath": "lib/src",
"contributors": ["Bar"]
}

View File

@@ -0,0 +1,9 @@
package bar;
class Bar {
static function new() {
trace("new Bar");
}
}

View File

@@ -0,0 +1,9 @@
package bar;
class Bar {
static function new() {
trace("new Bar");
}
}

View File

@@ -0,0 +1,10 @@
{
"name": "Bar",
"url" : "http://example.org",
"license": "GPL",
"tags": ["bar", "test"],
"description": "This project is an example of an haxelib project",
"version": "1.0.0",
"releasenote": "Initial release, everything is working correctly",
"contributors": ["Bar"]
}

View File

@@ -0,0 +1,7 @@
<project name="Bar" url="http://example.org" license="GPL">
<user name="Bar"/>
<tag v="bar"/>
<tag v="test"/>
<description>This project is an example of an haxelib project</description>
<version name="1.0.0">Initial release, everything is working correctly</version>
</project>

View File

@@ -0,0 +1,9 @@
package bar;
class Bar {
static function new() {
trace("new Bar");
}
}

View File

@@ -0,0 +1,10 @@
{
"name": "Bar",
"url" : "http://example.org",
"license": "MIT",
"tags": ["bar", "version2"],
"description": "This project is an example of an haxelib project",
"version": "2.0.0",
"releasenote": "Version 2.",
"contributors": ["Bar"]
}

View File

@@ -0,0 +1,7 @@
<project name="Bar" url="http://example.org" license="GPL">
<user name="Bar"/>
<tag v="bar"/>
<tag v="test"/>
<description>This project is an example of an haxelib project</description>
<version name="1.0.0">Initial release, everything is working correctly</version>
</project>

View File

@@ -0,0 +1,9 @@
package bar;
class Bar {
static function new() {
trace("new Bar");
}
}

View File

@@ -0,0 +1,10 @@
{
"name": "Deep",
"url" : "http://example.org",
"license": "Public",
"tags": ["deep", "test"],
"description": "This project's zip contains a folder that holds the lib.",
"version": "1.0.0",
"releasenote": "N/A",
"contributors": ["DeepAuthor", "AnotherGuy"]
}

View File

@@ -0,0 +1,9 @@
package foo;
class Foo {
public function new() {
trace("new Foo");
}
}

View File

@@ -0,0 +1,13 @@
{
"name": "Foo",
"url" : "http://example.org",
"license": "GPL",
"tags": ["foo", "test"],
"description": "This project is an example of an haxelib project",
"version": "0.1.0-alpha.0",
"releasenote": "Initial release, everything is working correctly",
"dependencies": {
"Bar": ""
},
"contributors": ["Foo"]
}

View File

@@ -0,0 +1,7 @@
<project name="Foo" url="http://example.org" license="GPL">
<user name="Foo"/>
<tag v="foo"/>
<tag v="test"/>
<description>This project is an example of an haxelib project</description>
<version name="1.0.0-alpha.0">Initial release, everything is working correctly</version>
</project>

View File

@@ -0,0 +1,282 @@
package tests;
import haxe.ds.StringMap;
import haxe.Json;
import haxe.io.*;
import haxe.zip.*;
import sys.io.*;
import haxelib.Data;
using StringTools;
class TestData extends TestBase {
public function testSafe() {
assertEquals( "abc", checkSafe("abc") );
assertEquals( "bean,hx", checkSafe("bean.hx") );
assertEquals( "1,2,3", checkSafe("1.2.3") );
assertEquals( "_-,123", checkSafe("_-.123") );
assertEquals( "invalid", checkSafe("1,2") );
assertEquals( "invalid", checkSafe("space ") );
assertEquals( "invalid", checkSafe("\t") );
assertEquals( "invalid", checkSafe("\n") );
assertEquals( "invalid", checkSafe("") );
}
function checkSafe( str:String ) {
return try {
Data.safe( str );
} catch (e:String) "invalid";
}
public function testUnsafe() {
assertEquals( "abc", Data.unsafe("abc") );
assertEquals( "1.2.3", Data.unsafe("1,2,3") );
assertEquals( "", Data.unsafe("") );
}
public function testFileName() {
assertEquals( "lib-1,2,3.zip", checkFileName("lib","1.2.3") );
assertEquals( "lib-1,2,3-rc,3.zip", checkFileName("lib","1.2.3-rc.3") );
assertEquals( "invalid", checkFileName("lib",",") );
assertEquals( "invalid", checkFileName(",","version") );
assertEquals( "invalid", checkFileName("","version") );
}
function checkFileName( lib, ver ) {
return try {
Data.fileName( lib, ver );
} catch (e:String) "invalid";
}
public function testLocateBasePath() {
var zip = Reader.readZip(new BytesInput(File.getBytes("package.zip")));
assertEquals( "", Data.locateBasePath(zip) );
var zip = Reader.readZip(new BytesInput(File.getBytes("test/libraries/libDeep.zip")));
assertEquals( "libDeep/", Data.locateBasePath(zip) );
}
public function testReadDoc() {
var zip = Reader.readZip(new BytesInput(File.getBytes("package.zip")));
assertEquals( null, Data.readDoc(zip) );
//TODO
}
public function testReadInfos() {
var zip = Reader.readZip(new BytesInput(File.getBytes("package.zip")));
var info = Data.readInfos(zip, true);
assertEquals( "haxelib", info.name );
assertEquals( "GPL", info.license );
var zip = Reader.readZip(new BytesInput(File.getBytes("test/libraries/libDeep.zip")));
var info = Data.readInfos(zip, true);
assertEquals( "Deep", info.name );
assertEquals( "http://example.org", info.url );
assertEquals( "Public", info.license );
assertEquals( "deep, test", info.tags.join(", ") );
assertEquals( "This project's zip contains a folder that holds the lib.", info.description );
assertEquals( "1.0.0", info.version );
assertEquals( "N/A", info.releasenote );
assertEquals( "DeepAuthor, AnotherGuy", info.contributors.join(", ") );
}
public function testCheckClassPath() {
var zip = Reader.readZip(new BytesInput(File.getBytes("package.zip")));
var info = Data.readInfos(zip, true);
var ok:Dynamic = try {
Data.checkClassPath(zip,info);
true;
} catch (e:Dynamic) {
e;
}
assertEquals( ok, true );
var zip = Reader.readZip(new BytesInput(File.getBytes("test/libraries/libDeep.zip")));
var info = Data.readInfos(zip, true);
var ok:Dynamic = try {
Data.checkClassPath(zip,info);
true;
} catch (e:Dynamic) {
e;
}
assertEquals( ok, true );
}
public function testReadDataWithCheck() {
assertFalse( readDataOkay("bad json") );
assertTrue( readDataOkay(getJsonInfos()) );
// Names
assertFalse( readDataOkay("{}") );
assertFalse( readDataOkay(getJsonInfos({ name: null })) );
assertFalse( readDataOkay(getJsonInfos({ name: '' })) );
assertFalse( readDataOkay(getJsonInfos({ name: 'haxe' })) );
assertFalse( readDataOkay(getJsonInfos({ name: 'haXe' })) );
assertFalse( readDataOkay(getJsonInfos({ name: 'all' })) );
assertFalse( readDataOkay(getJsonInfos({ name: 'something.zip' })) );
assertFalse( readDataOkay(getJsonInfos({ name: 'something.hxml' })) );
assertFalse( readDataOkay(getJsonInfos({ name: '12' })) );
assertTrue( readDataOkay(getJsonInfos({ name: 'mylib' })) );
assertFalse( readDataOkay(getJsonInfos([ "name" ])) ); // remove the field altogether
// Description (optional)
assertTrue( readDataOkay(getJsonInfos({ description: 'Some Description' })) );
assertTrue( readDataOkay(getJsonInfos({ description: '' })) );
assertTrue( readDataOkay(getJsonInfos({ description: null })) );
// Licence
assertTrue( readDataOkay(getJsonInfos({ license: 'BSD' })) );
assertFalse( readDataOkay(getJsonInfos({ license: null })) );
assertFalse( readDataOkay(getJsonInfos({ license: '' })) );
assertFalse( readDataOkay(getJsonInfos({ license: 'CustomLicence' })) );
assertFalse( readDataOkay(getJsonInfos([ "license" ])) ); // remove the field altogether
// Contibutors
assertFalse( readDataOkay(getJsonInfos({ contributors: [] })) );
assertFalse( readDataOkay(getJsonInfos({ contributors: null })) );
assertFalse( readDataOkay(getJsonInfos({ contributors: "jason" })) );
assertTrue( readDataOkay(getJsonInfos({ contributors: ["jason"] })) );
assertTrue( readDataOkay(getJsonInfos({ contributors: ["jason","juraj"] })) );
assertFalse( readDataOkay(getJsonInfos([ "contributors" ])) ); // remove the field altogether
// Version
assertTrue( readDataOkay(getJsonInfos({ version: "0.1.2-rc.0" })) );
assertFalse( readDataOkay(getJsonInfos({ version: "non-semver" })) );
assertFalse( readDataOkay(getJsonInfos({ version: 0 })) );
assertFalse( readDataOkay(getJsonInfos({ version: null })) );
assertFalse( readDataOkay(getJsonInfos([ "version" ])) ); // remove the field altogether
// Tags (optional)
assertTrue( readDataOkay(getJsonInfos({ tags: ["tag1","tag2"] })) );
assertTrue( readDataOkay(getJsonInfos({ tags: null })) );
assertFalse( readDataOkay(getJsonInfos({ tags: "mytag" })) );
// Dependencies (optional)
assertTrue( readDataOkay(getJsonInfos({ dependencies: null })) );
assertTrue( readDataOkay(getJsonInfos({ dependencies: { somelib: "" } })) );
assertTrue( readDataOkay(getJsonInfos({ dependencies: { somelib:"1.3.0" } }) ));
assertFalse( readDataOkay(getJsonInfos({ dependencies: { somelib: "nonsemver" }})) );
assertFalse( readDataOkay(getJsonInfos({ dependencies: { somelib: 0 } })) );
assertFalse( readDataOkay(getJsonInfos({ dependencies: "somelib" })) );
// ReleaseNote
assertTrue( readDataOkay(getJsonInfos({ releasenote: "release" })) );
assertFalse( readDataOkay(getJsonInfos({ releasenote: ["some","note"] })) );
assertFalse( readDataOkay(getJsonInfos({ releasenote: null })) );
assertFalse( readDataOkay(getJsonInfos([ "releasenote" ])) ); // remove the field altogether
// ClassPath
assertTrue( readDataOkay(getJsonInfos({ classPath: 'src/' })) );
assertTrue( readDataOkay(getJsonInfos({ classPath: '' })) );
assertTrue( readDataOkay(getJsonInfos({ classPath: null })) );
assertFalse( readDataOkay(getJsonInfos({ classPath: ["src","othersrc"] })) );
}
public function testReadDataWithoutCheck() {
assertEquals( ProjectName.DEFAULT, Data.readData("bad json",false).name );
assertEquals( "0.0.0", Data.readData("bad json",false).version );
assertEquals( "mylib", Data.readData(getJsonInfos(),false).name );
assertEquals( "0.1.2", Data.readData(getJsonInfos(),false).version );
// Names
assertEquals( ProjectName.DEFAULT, Data.readData("{}",false).name );
assertEquals( ProjectName.DEFAULT, Data.readData(getJsonInfos({ name: null }),false).name );
assertEquals( ProjectName.DEFAULT, Data.readData(getJsonInfos({ name: '' }),false).name );
assertEquals( "mylib", Data.readData(getJsonInfos({ name: 'mylib' }),false).name );
assertEquals( ProjectName.DEFAULT, Data.readData(getJsonInfos([ "name" ]), false).name ); // remove the field altogether
/*
// Description (optional)
assertEquals( "Some Description", Data.readData(getJsonInfos({ description: 'Some Description' }),false).description );
assertEquals( "", Data.readData(getJsonInfos({ description: '' }),false).description );
assertEquals( "", Data.readData(getJsonInfos({ description: null }),false).description );
assertEquals( "", Data.readData(getJsonInfos([ "description" ]),false).description ); // remove the field altogether
// Licence
assertEquals( "BSD", Data.readData(getJsonInfos({ license: 'BSD' }),false).license );
assertEquals( "Unknown", Data.readData(getJsonInfos({ license: null }),false).license );
assertEquals( "Unknown", Data.readData(getJsonInfos({ license: '' }),false).license );
assertEquals( "CustomLicence", Data.readData(getJsonInfos({ license: 'CustomLicence' }),false).license );
assertEquals( "Unknown", Data.readData(getJsonInfos([ "license" ]),false).license ); // remove the field altogether
// Contibutors
assertEquals( 0, Data.readData(getJsonInfos({ contributors: [] }),false).contributors.length );
assertEquals( 0, Data.readData(getJsonInfos({ contributors: null }),false).contributors.length );
assertEquals( 0, Data.readData(getJsonInfos({ contributors: "jason" }),false).contributors.length );
assertEquals( 1, Data.readData(getJsonInfos({ contributors: ["jason"] }),false).contributors.length );
assertEquals( 2, Data.readData(getJsonInfos({ contributors: ["jason","juraj"] }),false).contributors.length );
assertEquals( 0, Data.readData(getJsonInfos([ "contributors" ]),false).contributors.length ); // remove the field altogether
*/
// Version
assertEquals( "0.1.2-rc.0", Data.readData(getJsonInfos({ version: "0.1.2-rc.0" }),false).version );
assertEquals( "0.0.0", Data.readData(getJsonInfos({ version: "non-semver" }),false).version );
assertEquals( "0.0.0", Data.readData(getJsonInfos({ version: 0 }),false).version );
assertEquals( "0.0.0", Data.readData(getJsonInfos({ version: null }),false).version );
assertEquals( "0.0.0", Data.readData(getJsonInfos([ "version" ]),false).version ); // remove the field altogether
/*
// Tags (optional)
assertEquals( 2, Data.readData(getJsonInfos({ tags: ["tag1","tag2"] }),false).tags.length );
assertEquals( 0, Data.readData(getJsonInfos({ tags: null }),false).tags.length );
assertEquals( 0, Data.readData(getJsonInfos({ tags: "mytag" }),false).tags.length );
*/
// Dependencies (optional)
assertEquals( 0, Data.readData(getJsonInfos({ dependencies: null }),false).dependencies.toArray().length );
assertEquals( "somelib", Data.readData(getJsonInfos({ dependencies: { somelib:"" } }),false).dependencies.toArray()[0].name );
assertEquals( "", Data.readData(getJsonInfos({ dependencies: { somelib:"" } }),false).dependencies.toArray()[0].version );
assertEquals( "1.3.0", Data.readData(getJsonInfos({ dependencies: { somelib:"1.3.0" } }),false).dependencies.toArray()[0].version );
assertEquals( "", Data.readData(getJsonInfos({ dependencies: { somelib:"nonsemver" } }),false).dependencies.toArray()[0].version );
assertEquals( "", Data.readData(getJsonInfos({ dependencies: { somelib:null } }),false).dependencies.toArray()[0].version );
assertEquals( "", Data.readData(getJsonInfos( { dependencies: { somelib:0 } } ), false).dependencies.toArray()[0].version );
/*
// ReleaseNote
assertEquals( "release", Data.readData(getJsonInfos({ releasenote: "release" }),false).releasenote );
assertEquals( "", Data.readData(getJsonInfos({ releasenote: null }),false).releasenote );
assertEquals( "", Data.readData(getJsonInfos([ "releasenote" ]),false).releasenote ); // remove the field altogether
*/
// ClassPath
assertEquals( "src", Data.readData(getJsonInfos({ classPath: 'src' }), false).classPath );
assertEquals( "", Data.readData(getJsonInfos({ classPath: '' }), false).classPath );
assertEquals( "", Data.readData(getJsonInfos({ classPath: null }), false).classPath );
}
function readDataOkay( json ) {
try {
Data.readData( json,true );
return true;
}
catch (e:String) {
return false;
}
}
function getJsonInfos( ?remove:Array<String>, ?change:Dynamic ) {
var infos = {
name: "mylib",
license: "MIT",
contributors: ["jason"],
version: "0.1.2",
releasenote: ""
};
if (change != null) {
for ( name in Reflect.fields(change) ) {
var value = Reflect.field( change, name );
Reflect.setField( infos, name, value );
}
}
if (remove != null) {
for ( f in remove )
Reflect.deleteField( infos, f );
}
return Json.stringify(infos);
}
}

View File

@@ -0,0 +1,9 @@
package tests;
import haxelib.client.Vcs;
class TestGit extends TestVcs {
public function new():Void {
super(VcsID.Git, "Git", "https://github.com/fzzr-/hx.signal.git", "0.9.2");
}
}

View File

@@ -0,0 +1,9 @@
package tests;
import haxelib.client.Vcs;
class TestHg extends TestVcs {
public function new():Void {
super(VcsID.Hg, "Mercurial", "https://bitbucket.org/fzzr/hx.signal", "78edb4b");
}
}

View File

@@ -0,0 +1,55 @@
package tests;
import sys.FileSystem;
import sys.io.*;
import haxe.io.Path;
import haxe.unit.TestCase;
class TestRemoveSymlinks extends TestBase
{
//----------- properties, fields ------------//
static var REPO = "haxelib-repo";
var lib:String = "symlinks";
var repo:String = null;
var origRepo:String;
//--------------- constructor ---------------//
public function new()
{
super();
this.repo = Path.join([Sys.getCwd(), "test", REPO]);
}
//--------------- initialize ----------------//
override public function setup():Void
{
origRepo = ~/\r?\n/.split(runHaxelib(["config"]).stdout)[0];
origRepo = Path.normalize(origRepo);
var libzip = Path.join([Sys.getCwd(), "test", "libraries", lib + ".zip"]);
if (runHaxelib(["setup", repo]).exitCode != 0) {
throw "haxelib setup failed";
}
if (runHaxelib(["local", libzip]).exitCode != 0) {
throw "haxelib local failed";
}
}
override public function tearDown():Void {
if (runHaxelib(["setup", origRepo]).exitCode != 0) {
throw "haxelib setup failed";
}
deleteDirectory(repo);
}
//----------------- tests -------------------//
public function testRemoveLibWithSymlinks():Void
{
var code = runHaxelib(["remove", lib]).exitCode;
assertEquals(code, 0);
assertFalse(FileSystem.exists(Path.join([repo, lib])));
}
}

View File

@@ -0,0 +1,9 @@
package tests;
class TestRemoveSymlinksBroken extends TestRemoveSymlinks
{
public function new():Void {
super();
this.lib = "symlinks-broken";
}
}

View File

@@ -0,0 +1,72 @@
package tests;
import haxelib.SemVer;
class TestSemVer extends TestBase {
static function make(major, minor, patch, ?preview, ?previewNum):SemVer {
return {
major : major,
minor : minor,
patch : patch,
preview : preview,
previewNum : previewNum
};
}
public function testToString() {
assertEquals( "0.1.2", make(0,1,2) );
// Release Tags
assertEquals( "0.1.2-alpha", make(0,1,2,ALPHA) );
assertEquals( "0.1.2-beta", make(0,1,2,BETA) );
assertEquals( "0.1.2-rc", make(0,1,2,RC) );
// Release Tag Versions
assertEquals( "0.1.2-alpha.0", make(0,1,2,ALPHA,0) );
assertEquals( "0.1.2-beta.0", make(0,1,2,BETA,0) );
assertEquals( "0.1.2-rc.0", make(0,1,2,RC,0) );
// Weird input
assertEquals( "0.1.2", make(0,1,2,null,0) );
// Multiple characters
assertEquals( "100.200.300-rc.400", make(100,200,300,RC,400) );
}
public function testOfString() {
// Normal
assertEquals( "0.1.2", (SemVer.ofString("0.1.2").data : SemVer));
assertEquals( "100.50.200", (SemVer.ofString("100.50.200").data : SemVer));
// Release tags
assertEquals( "0.1.2-alpha", (SemVer.ofString("0.1.2-ALPHA").data : SemVer));
assertEquals( "0.1.2-alpha", (SemVer.ofString("0.1.2-alpha").data : SemVer));
assertEquals( "0.1.2-beta", (SemVer.ofString("0.1.2-beta").data : SemVer));
assertEquals( "0.1.2-rc", (SemVer.ofString("0.1.2-rc").data : SemVer));
assertEquals( "0.1.2-rc.1", (SemVer.ofString("0.1.2-rc.1").data : SemVer));
}
public function testOfStringInvalid() {
assertEquals( "invalid", parseInvalid(null) );
assertEquals( "invalid", parseInvalid("") );
assertEquals( "invalid", parseInvalid("1") );
assertEquals( "invalid", parseInvalid("1.1") );
assertEquals( "invalid", parseInvalid("1.2.a") );
assertEquals( "invalid", parseInvalid("a.b.c") );
assertEquals( "invalid", parseInvalid("1.2.3-") );
assertEquals( "invalid", parseInvalid("1.2.3-rc.") );
assertEquals( "invalid", parseInvalid("1.2.3--rc.1") );
assertEquals( "invalid", parseInvalid("1.2.3-othertag") );
assertEquals( "invalid", parseInvalid("1.2.3-othertag.1") );
assertEquals( "invalid", parseInvalid("10.050.02"));
assertEquals( "invalid", parseInvalid("10.50.2-rc.01"));
}
function parseInvalid( str:String ) {
return try {
(SemVer.ofString( str ) : String);
} catch (e:String) {
"invalid";
}
}
}

View File

@@ -0,0 +1,246 @@
package tests;
import sys.io.*;
import sys.FileSystem;
import haxe.io.*;
import haxe.unit.TestCase;
import haxelib.client.Cli;
import haxelib.client.Vcs;
class TestVcs extends TestBase
{
//----------- properties, fields ------------//
static inline var REPO_ROOT = "test/libraries";
static inline var REPO_DIR = "vcs";
static var CWD:String = null;
var id:VcsID = null;
var vcsName:String = null;
var url:String = null;
var rev:String = null;
var counter:Int = 0;
//--------------- constructor ---------------//
public function new(id:VcsID, vcsName:String, url:String, ?rev:String)
{
super();
this.id = id;
this.url = url;
this.rev = rev;
this.vcsName = vcsName;
CWD = Sys.getCwd();
counter = 0;
}
//--------------- initialize ----------------//
override public function setup():Void
{
Sys.setCwd(Path.join([CWD, REPO_ROOT]));
if(FileSystem.exists(REPO_DIR)) {
deleteDirectory(REPO_DIR);
}
FileSystem.createDirectory(REPO_DIR);
Sys.setCwd(REPO_DIR);
}
override public function tearDown():Void
{
// restore original CWD:
Sys.setCwd(CWD);
deleteDirectory(Path.join([CWD, REPO_ROOT, REPO_DIR]));
}
//----------------- tests -------------------//
public function testGetVcs():Void
{
assertTrue(Vcs.get(id, {quiet: true}) != null);
assertTrue(Vcs.get(id, {quiet: true}).name == vcsName);
}
public function testAvailable():Void
{
assertTrue(getVcs().available);
}
// --------------- clone --------------- //
public function testGetVcsByDir():Void
{
var vcs = getVcs();
testCloneSimple();
assertEquals(vcs, Vcs.get(id, {quiet: true}));
}
public function testCloneSimple():Void
{
var vcs = getVcs();
var dir = vcs.directory + counter++;
vcs.clone(dir, url);
assertTrue(FileSystem.exists(dir));
assertTrue(FileSystem.isDirectory(dir));
assertTrue(FileSystem.exists('$dir/.${vcs.directory}'));
assertTrue(FileSystem.isDirectory('$dir/.${vcs.directory}'));
}
public function testCloneBranch():Void
{
var vcs = getVcs();
var dir = vcs.directory + counter++;
vcs.clone(dir, url, "develop");
assertTrue(FileSystem.exists(dir));
assertTrue(FileSystem.isDirectory(dir));
assertTrue(FileSystem.exists('$dir/.${vcs.directory}'));
assertTrue(FileSystem.isDirectory('$dir/.${vcs.directory}'));
}
public function testCloneBranchTag_0_9_2():Void
{
var vcs = getVcs();
var dir = vcs.directory + counter++;
vcs.clone(dir, url, "develop", "0.9.2");
Sys.sleep(3);
assertTrue(FileSystem.exists(dir));
assertTrue(FileSystem.exists('$dir/.${vcs.directory}'));
// if that repo "README.md" was added in tag/rev.: "0.9.3"
assertFalse(FileSystem.exists(dir + "/README.md"));
}
public function testCloneBranchTag_0_9_3():Void
{
var vcs = getVcs();
var dir = vcs.directory + counter++;
vcs.clone(dir, url, "develop", "0.9.3");
assertTrue(FileSystem.exists(dir));
assertTrue(FileSystem.exists('$dir/.${vcs.directory}'));
// if that repo "README.md" was added in tag/rev.: "0.9.3"
assertTrue(FileSystem.exists(dir + "/README.md"));
}
public function testCloneBranchRev():Void
{
var vcs = getVcs();
var dir = vcs.directory + counter++;
vcs.clone(dir, url, "develop", rev);
assertTrue(FileSystem.exists(dir));
assertTrue(FileSystem.exists('$dir/.${vcs.directory}'));
// if that repo "README.md" was added in tag/rev.: "0.9.3"
assertFalse(FileSystem.exists(dir + "/README.md"));
}
// --------------- update --------------- //
public function testUpdateBranchTag_0_9_2__toLatest():Void
{
var vcs = getVcs();
var dir = vcs.directory + counter;// increment will do in `testCloneBranchTag_0_9_2`
testCloneBranchTag_0_9_2();
assertFalse(FileSystem.exists("README.md"));
// save CWD:
var cwd = Sys.getCwd();
Sys.setCwd(cwd + dir);
assertTrue(FileSystem.exists("." + vcs.directory));
// in this case `libName` can get any value:
vcs.update("LIBNAME");
// Now we get actual version (0.9.3 or newer) with README.md.
assertTrue(FileSystem.exists("README.md"));
// restore CWD:
Sys.setCwd(cwd);
}
public function testUpdateBranchTag_0_9_2__toLatest__afterUserChanges_withReset():Void
{
var vcs = getVcs();
var dir = vcs.directory + counter;// increment will do in `testCloneBranchTag_0_9_2`
testCloneBranchTag_0_9_2();
assertFalse(FileSystem.exists("README.md"));
// save CWD:
var cwd = Sys.getCwd();
Sys.setCwd(cwd + dir);
// creating user-changes:
FileSystem.deleteFile("build.hxml");
File.saveContent("file", "new file \"file\" with content");
//Hack: set the default answer:
Cli.defaultAnswer = true;
// update to HEAD:
// in this case `libName` can get any value:
vcs.update("LIBNAME");
// Now we get actual version (0.9.3 or newer) with README.md.
assertTrue(FileSystem.exists("README.md"));
// restore CWD:
Sys.setCwd(cwd);
}
public function testUpdateBranchTag_0_9_2__toLatest__afterUserChanges_withoutReset():Void
{
var vcs = getVcs();
var dir = vcs.directory + counter;// increment will do in `testCloneBranchTag_0_9_2`
testCloneBranchTag_0_9_2();
assertFalse(FileSystem.exists("README.md"));
// save CWD:
var cwd = Sys.getCwd();
Sys.setCwd(cwd + dir);
// creating user-changes:
FileSystem.deleteFile("build.hxml");
File.saveContent("file", "new file \"file\" with content");
//Hack: set the default answer:
Cli.defaultAnswer = false;
// update to HEAD:
// in this case `libName` can get any value:
vcs.update("LIBNAME");
// We get no reset and update:
assertTrue(FileSystem.exists("file"));
assertFalse(FileSystem.exists("build.hxml"));
assertFalse(FileSystem.exists("README.md"));
// restore CWD:
Sys.setCwd(cwd);
}
//----------------- tools -------------------//
inline function getVcs():Vcs
{
return Vcs.get(id, {quiet: true});
}
}

View File

@@ -0,0 +1,183 @@
package tests;
import sys.FileSystem;
import haxe.io.*;
import haxelib.client.Vcs;
class TestVcsNotFound extends TestBase
{
//----------- properties, fields ------------//
static inline var REPO_ROOT = "test/libraries";
static inline var REPO_DIR = "vcs-no";
static var CWD:String = null;
//--------------- constructor ---------------//
public function new()
{
super();
CWD = Sys.getCwd();
}
//--------------- initialize ----------------//
override public function setup():Void
{
Sys.setCwd(Path.join([CWD, REPO_ROOT]));
if(FileSystem.exists(REPO_DIR)) {
deleteDirectory(REPO_DIR);
}
FileSystem.createDirectory(REPO_DIR);
Sys.setCwd(REPO_DIR);
}
override public function tearDown():Void
{
// restore original CWD & PATH:
Sys.setCwd(CWD);
deleteDirectory(Path.join([CWD, REPO_ROOT, REPO_DIR]));
}
//----------------- tests -------------------//
public function testAvailableHg():Void
{
assertFalse(getHg().available);
}
public function testAvailableGit():Void
{
assertFalse(getGit().available);
}
public function testCloneHg():Void
{
var vcs = getHg();
try
{
vcs.clone(vcs.directory, "https://bitbucket.org/fzzr/hx.signal");
assertFalse(true);
}
catch(error:VcsError)
{
switch(error)
{
case VcsError.CantCloneRepo(_, repo, stderr): assertTrue(true);
default: assertFalse(true);
}
}
}
public function testCloneGit():Void
{
var vcs = getGit();
try
{
vcs.clone(vcs.directory, "https://github.com/fzzr-/hx.signal.git");
assertFalse(true);
}
catch(error:VcsError)
{
switch(error)
{
case VcsError.CantCloneRepo(_, repo, stderr): assertTrue(true);
default: assertFalse(true);
}
}
}
//----------------- tools -------------------//
inline function getHg():Vcs
{
return new WrongHg({quiet: true});
}
inline function getGit():Vcs
{
return new WrongGit({quiet: true});
}
}
class WrongHg extends Mercurial
{
public function new(settings:Settings)
{
super(settings);
this.directory = "no-hg";
this.executable = "no-hg";
this.name = "Mercurial-not-found";
}
// copy of Mercurial.searchExecutablebut have a one change - regexp.
override private function searchExecutable():Void
{
super.searchExecutable();
if(available)
return;
// if we have already msys git/cmd in our PATH
var match = ~/(.*)no-hg-no([\\|\/])cmd$/;
for(path in Sys.getEnv("PATH").split(";"))
{
if(match.match(path.toLowerCase()))
{
var newPath = match.matched(1) + executable + match.matched(2) + "bin";
Sys.putEnv("PATH", Sys.getEnv("PATH") + ";" + newPath);
}
}
checkExecutable();
}
}
class WrongGit extends Git
{
public function new(settings:Settings)
{
super(settings);
this.directory = "no-git";
this.executable = "no-git";
this.name = "Git-not-found";
}
// copy of Mercurial.searchExecutablebut have a one change - regexp.
override private function searchExecutable():Void
{
super.searchExecutable();
if(available)
return;
// if we have already msys git/cmd in our PATH
var match = ~/(.*)no-git-no([\\|\/])cmd$/;
for(path in Sys.getEnv("PATH").split(";"))
{
if(match.match(path.toLowerCase()))
{
var newPath = match.matched(1) + executable + match.matched(2) + "bin";
Sys.putEnv("PATH", Sys.getEnv("PATH") + ";" + newPath);
}
}
if(checkExecutable())
return;
// look at a few default paths
for(path in ["C:\\Program Files (x86)\\Git\\bin", "C:\\Progra~1\\Git\\bin"])
if(FileSystem.exists(path))
{
Sys.putEnv("PATH", Sys.getEnv("PATH") + ";" + path);
if(checkExecutable())
return;
}
}
}

View File

@@ -0,0 +1,136 @@
package tests.integration;
import haxelib.*;
import IntegrationTests.*;
using IntegrationTests;
import haxe.io.*;
class TestDev extends IntegrationTests {
function testDev():Void {
{
var r = haxelib(["dev", "Bar", "test/libraries/libBar"]).result();
assertSuccess(r);
}
{
var r = haxelib(["list", "Bar"]).result();
assertTrue(r.out.indexOf("Bar") >= 0);
assertSuccess(r);
}
{
var r = haxelib(["path", "Bar"]).result();
var out = ~/\r?\n/g.split(r.out);
assertEquals(
Path.addTrailingSlash(Path.normalize(sys.FileSystem.fullPath("test/libraries/libBar"))),
Path.addTrailingSlash(Path.normalize(out[0]))
);
if (clientVer > SemVer.ofString("3.1.0-rc.4"))
assertEquals("-D Bar=1.0.0", out[1]);
else
assertEquals("-D Bar", out[1]);
assertSuccess(r);
}
{
var r = haxelib(["remove", "Bar"]).result();
assertSuccess(r);
}
{
var r = haxelib(["list", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("Bar") == -1);
}
}
function testWrongPath():Void {
{
var r = haxelib(["dev", "Bar", "test/libraries/libBar_not_exist"]).result();
// assertTrue(r.code != 0); //TODO
}
{
var r = haxelib(["list", "Bar"]).result();
assertSuccess(r);
if (clientVer > SemVer.ofString("3.1.0-rc.4"))
assertTrue(r.out.indexOf("Bar") == -1);
}
}
function testNoHaxelibJson():Void {
{
var r = haxelib(["dev", "Bar", "bin"]).result();
assertSuccess(r);
}
{
var r = haxelib(["list", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("Bar") >= 0);
}
{
var r = haxelib(["path", "Bar"]).result();
var out = ~/\r?\n/g.split(r.out);
assertEquals(
Path.addTrailingSlash(Path.normalize(sys.FileSystem.fullPath("bin"))),
Path.addTrailingSlash(Path.normalize(out[0]))
);
if (clientVer > SemVer.ofString("3.1.0-rc.4"))
assertEquals("-D Bar=0.0.0", out[1]);
else
assertEquals("-D Bar", out[1]);
assertSuccess(r);
}
{
var r = haxelib(["remove", "Bar"]).result();
assertSuccess(r);
}
{
var r = haxelib(["list", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("Bar") == -1);
}
}
function testClassPath():Void {
{
var r = haxelib(["dev", "UseCp", "test/libraries/UseCp"]).result();
assertSuccess(r);
}
{
var r = haxelib(["list", "UseCp"]).result();
assertTrue(r.out.indexOf("UseCp") >= 0);
assertSuccess(r);
}
{
var r = haxelib(["path", "UseCp"]).result();
var out = ~/\r?\n/g.split(r.out);
assertEquals(
Path.addTrailingSlash(Path.normalize(sys.FileSystem.fullPath("test/libraries/UseCp/lib/src"))),
Path.addTrailingSlash(Path.normalize(out[0]))
);
if (clientVer > SemVer.ofString("3.1.0-rc.4"))
assertEquals("-D UseCp=0.0.1", out[1]);
else
assertEquals("-D UseCp", out[1]);
assertSuccess(r);
}
{
var r = haxelib(["remove", "UseCp"]).result();
assertSuccess(r);
}
{
var r = haxelib(["list", "UseCp"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("UseCp") == -1);
}
}
}

View File

@@ -0,0 +1,78 @@
package tests.integration;
import haxe.*;
import haxe.io.*;
import haxelib.*;
import IntegrationTests.*;
using IntegrationTests;
class TestEmpty extends IntegrationTests {
function testEmpty():Void {
// the initial local and remote repos are empty
var installResult = haxelib(["install", "foo"]).result();
assertTrue(installResult.code != 0);
var upgradeResult = haxelib(["upgrade"]).result();
assertSuccess(upgradeResult);
var updateResult = haxelib(["update", "foo"]).result();
// assertTrue(updateResult.code != 0);
var removeResult = haxelib(["remove", "foo"]).result();
assertTrue(removeResult.code != 0);
var upgradeResult = haxelib(["list"]).result();
assertSuccess(upgradeResult);
var removeResult = haxelib(["set", "foo", "0.0"], "y\n").result();
assertTrue(removeResult.code != 0);
var searchResult = haxelib(["search", "foo"]).result();
assertSuccess(searchResult);
assertTrue(searchResult.out.indexOf("0") >= 0);
var infoResult = haxelib(["info", "foo"]).result();
assertTrue(infoResult.code != 0);
var userResult = haxelib(["user", "foo"]).result();
assertTrue(userResult.code != 0);
var configResult = haxelib(["config"]).result();
assertSuccess(configResult);
var pathResult = haxelib(["path", "foo"]).result();
assertTrue(pathResult.code != 0);
if (clientVer > SemVer.ofString("3.1.0-rc.4")) {
var versionResult = haxelib(["version"]).result();
assertSuccess(versionResult);
var helpResult = haxelib(["help"]).result();
assertSuccess(helpResult);
}
}
function testWebsite():Void {
// home page
assertNoError(function() Http.requestUrl(serverUrl));
// Haxelib Tags
assertNoError(function() Http.requestUrl(Path.join([serverUrl, "t"])));
// All Haxelibs
assertNoError(function() Http.requestUrl(Path.join([serverUrl, "all"])));
// Haxelib Contributors
assertNoError(function() Http.requestUrl(Path.join([serverUrl, "u"])));
// docs
assertNoError(function() Http.requestUrl(Path.join([serverUrl, "documentation"])));
assertNoError(function() Http.requestUrl(Path.join([serverUrl, "documentation/using-haxelib"])));
assertNoError(function() Http.requestUrl(Path.join([serverUrl, "documentation/creating-a-haxelib-package/"])));
assertNoError(function() Http.requestUrl(Path.join([serverUrl, "documentation/creating-a-haxelib-package/"])));
// RSS feed
assertNoError(function() Http.requestUrl(Path.join([serverUrl, "rss"])));
}
}

View File

@@ -0,0 +1,66 @@
package tests.integration;
import IntegrationTests.*;
using IntegrationTests;
class TestInfo extends IntegrationTests {
function test():Void {
{
var r = haxelib(["register", bar.user, bar.email, bar.fullname, bar.pw, bar.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["submit", "test/libraries/libBar.zip", bar.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["info", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("Bar") >= 0);
// license
assertTrue(r.out.indexOf("GPL") >= 0);
// tags
assertTrue(r.out.indexOf("bar") >= 0);
assertTrue(r.out.indexOf("test") >= 0);
// versions
assertTrue(r.out.indexOf("1.0.0") >= 0);
}
{
var r = haxelib(["submit", "test/libraries/libBar2.zip", bar.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["info", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("Bar") >= 0);
// license
assertTrue(r.out.indexOf("MIT") >= 0);
// tags
assertTrue(r.out.indexOf("bar") >= 0);
assertTrue(r.out.indexOf("test") == -1);
assertTrue(r.out.indexOf("version2") >= 0);
// versions
assertTrue(r.out.indexOf("1.0.0") >= 0);
assertTrue(r.out.indexOf("2.0.0") >= 0);
}
}
function testNotExist():Void {
{
var r = haxelib(["info", "Bar"]).result();
assertTrue(r.code != 0);
}
}
}

View File

@@ -0,0 +1,116 @@
package tests.integration;
import haxelib.*;
import IntegrationTests.*;
using IntegrationTests;
class TestList extends IntegrationTests {
function test():Void {
{
var r = haxelib(["list"]).result();
assertSuccess(r);
}
{
var r = haxelib(["register", bar.user, bar.email, bar.fullname, bar.pw, bar.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["submit", "test/libraries/libBar.zip", bar.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["install", "Bar"]).result();
assertSuccess(r);
}
{
var r = haxelib(["list"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("Bar") >= 0);
}
{
var r = haxelib(["list", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("Bar") >= 0);
assertTrue(r.out.indexOf("[1.0.0]") >= 0);
}
{
var r = haxelib(["submit", "test/libraries/libBar2.zip", bar.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["update", "Bar"]).result();
assertSuccess(r);
}
{
var r = haxelib(["list"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("Bar") >= 0);
}
{
var r = haxelib(["list", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("Bar") >= 0);
var pos1 = r.out.indexOf("1.0.0");
var pos2 = r.out.indexOf("2.0.0");
assertTrue(pos1 >= 0);
assertTrue(pos2 >= 0);
if (SemVer.compare(clientVer, SemVer.ofString("3.3.0")) >= 0) {
assertTrue(pos2 >= pos1);
}
}
}
/**
Make sure the version list is in ascending order, independent of the installation order.
**/
function testInstallNewThenOld():Void {
{
var r = haxelib(["register", bar.user, bar.email, bar.fullname, bar.pw, bar.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["submit", "test/libraries/libBar.zip", bar.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["submit", "test/libraries/libBar2.zip", bar.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["install", "Bar", "2.0.0"]).result();
assertSuccess(r);
}
{
var r = haxelib(["install", "Bar", "1.0.0"]).result();
assertSuccess(r);
}
{
var r = haxelib(["list", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("Bar") >= 0);
var pos1 = r.out.indexOf("1.0.0");
var pos2 = r.out.indexOf("2.0.0");
assertTrue(pos1 >= 0);
assertTrue(pos2 >= 0);
if (SemVer.compare(clientVer, SemVer.ofString("3.3.0")) >= 0) {
assertTrue(pos2 >= pos1);
}
}
}
}

View File

@@ -0,0 +1,77 @@
package tests.integration;
import IntegrationTests.*;
using IntegrationTests;
using StringTools;
class TestSet extends IntegrationTests {
function test():Void {
{
var r = haxelib(["register", bar.user, bar.email, bar.fullname, bar.pw, bar.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["submit", "test/libraries/libBar.zip", bar.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["submit", "test/libraries/libBar2.zip", bar.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["search", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("Bar") >= 0);
}
{
var r = haxelib(["install", "Bar"]).result();
assertSuccess(r);
}
{
var r = haxelib(["list", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("[2.0.0]") >= 0);
}
{
var r = haxelib(["install", "Bar", "1.0.0"]).result();
assertSuccess(r);
}
{
var r = haxelib(["list", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("[2.0.0]") >= 0);
assertTrue(r.out.indexOf("1.0.0") >= 0);
}
{
var r = haxelib(["set", "Bar", "1.0.0"]).result();
assertSuccess(r);
}
{
var r = haxelib(["list", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("[1.0.0]") >= 0);
assertTrue(r.out.indexOf("2.0.0") >= 0);
}
{
var r = haxelib(["set", "Bar", "2.0.0"]).result();
assertSuccess(r);
}
{
var r = haxelib(["list", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("1.0.0") >= 0);
assertTrue(r.out.indexOf("[2.0.0]") >= 0);
}
}
}

View File

@@ -0,0 +1,91 @@
package tests.integration;
import IntegrationTests.*;
using IntegrationTests;
class TestSimple extends IntegrationTests {
function testNormal():Void {
{
var r = haxelib(["register", bar.user, bar.email, bar.fullname, bar.pw, bar.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["submit", "test/libraries/libBar.zip", bar.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["search", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("Bar") >= 0);
}
{
var r = haxelib(["register", foo.user, foo.email, foo.fullname, foo.pw, foo.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["submit", "test/libraries/libFoo.zip", foo.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["search", "Foo"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("Foo") >= 0);
}
{
var r = haxelib(["install", "Bar"]).result();
assertSuccess(r);
}
{
var r = haxelib(["install", "Foo"]).result();
assertSuccess(r);
}
{
var r = haxelib(["list", "Bar"]).result();
assertTrue(r.out.indexOf("Bar") >= 0);
assertSuccess(r);
}
{
var r = haxelib(["list", "Foo"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("Foo") >= 0);
}
{
var r = haxelib(["list"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("Foo") >= 0);
assertTrue(r.out.indexOf("Bar") >= 0);
}
{
var r = haxelib(["remove", "Foo"]).result();
assertSuccess(r);
}
{
var r = haxelib(["list", "Foo"]).result();
assertTrue(r.out.indexOf("Foo") < 0);
assertSuccess(r);
}
{
var r = haxelib(["remove", "Bar"]).result();
assertSuccess(r);
}
{
var r = haxelib(["list", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("Bar") < 0);
}
}
}

View File

@@ -0,0 +1,69 @@
package tests.integration;
import IntegrationTests.*;
using IntegrationTests;
using StringTools;
class TestUpdate extends IntegrationTests {
function test():Void {
{
var r = haxelib(["register", bar.user, bar.email, bar.fullname, bar.pw, bar.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["submit", "test/libraries/libBar.zip", bar.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["search", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("Bar") >= 0);
}
{
var r = haxelib(["install", "Bar"]).result();
assertSuccess(r);
}
{
var r = haxelib(["update", "Bar"]).result();
assertSuccess(r);
}
{
var r = haxelib(["list", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("[1.0.0]") >= 0);
}
{
var r = haxelib(["submit", "test/libraries/libBar2.zip", bar.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["update", "Bar"]).result();
assertSuccess(r);
}
{
var r = haxelib(["list", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("[2.0.0]") >= 0);
assertTrue(r.out.indexOf("1.0.0") >= 0);
}
{
var r = haxelib(["remove", "Bar"]).result();
assertSuccess(r);
}
{
var r = haxelib(["list", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("Bar") < 0);
}
}
}

View File

@@ -0,0 +1,79 @@
package tests.integration;
import IntegrationTests.*;
using IntegrationTests;
using StringTools;
class TestUpgrade extends IntegrationTests {
function test():Void {
{
var r = haxelib(["upgrade"]).result();
assertSuccess(r);
}
{
var r = haxelib(["register", bar.user, bar.email, bar.fullname, bar.pw, bar.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["submit", "test/libraries/libBar.zip", bar.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["search", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("Bar") >= 0);
}
{
var r = haxelib(["install", "Bar"]).result();
assertSuccess(r);
}
{
var r = haxelib(["list", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("[1.0.0]") >= 0);
}
{
var r = haxelib(["upgrade"]).result();
assertSuccess(r);
}
{
var r = haxelib(["submit", "test/libraries/libBar2.zip", bar.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["upgrade"], "y\n").result();
assertSuccess(r);
}
{
var r = haxelib(["list", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("[2.0.0]") >= 0);
assertTrue(r.out.indexOf("1.0.0") >= 0);
}
{
var r = haxelib(["upgrade"]).result();
assertSuccess(r);
}
{
var r = haxelib(["remove", "Bar"]).result();
assertSuccess(r);
}
{
var r = haxelib(["list", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("Bar") < 0);
}
}
}

View File

@@ -0,0 +1,49 @@
package tests.integration;
import IntegrationTests.*;
using IntegrationTests;
class TestUser extends IntegrationTests {
function test():Void {
{
var r = haxelib(["register", bar.user, bar.email, bar.fullname, bar.pw, bar.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["user", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("Bar") >= 0);
assertTrue(r.out.indexOf(bar.email) >= 0);
assertTrue(r.out.indexOf(bar.fullname) >= 0);
assertTrue(r.out.indexOf(bar.pw) == -1);
}
{
var r = haxelib(["submit", "test/libraries/UseCp.zip", bar.pw]).result();
assertSuccess(r);
}
{
var r = haxelib(["user", "Bar"]).result();
assertSuccess(r);
assertTrue(r.out.indexOf("Bar") >= 0);
assertTrue(r.out.indexOf(bar.email) >= 0);
assertTrue(r.out.indexOf(bar.fullname) >= 0);
assertTrue(r.out.indexOf(bar.pw) == -1);
assertTrue(r.out.indexOf("UseCp") >= 0);
}
}
function testNotExist():Void {
{
var r = haxelib(["user", "Bar"]).result();
assertTrue(r.code != 0);
}
}
}

View File

@@ -0,0 +1,48 @@
package website.controller;
import website.controller.*;
import ufront.web.result.ViewResult;
import website.Server;
using tink.CoreApi;
// These imports are common for our various test-suite tools.
import buddy.*;
import mockatoo.Mockatoo.*;
import ufront.test.TestUtils.NaturalLanguageTests.*;
import utest.Assert;
using haxe.io.Path;
using buddy.Should;
using ufront.test.TestUtils;
using mockatoo.Mockatoo;
class DocumentationControllerTest extends BuddySuite {
public function new() {
var haxelibSite = WebsiteTests.getTestApp();
describe("When viewing documentation", {
it("Should load all pages without errors", function (done) {
var pages = DocumentationController.getDocumentationPages();
var allResults = [];
for ( url in pages.keys() ) {
var title = pages.get( url );
var page =
if ( url=="/documentation/" ) null
else url.substr( "/documentation/".length ).removeTrailingSlashes();
var result = whenIVisit( url )
.onTheApp( haxelibSite )
.itShouldLoad( DocumentationController, "documentationPage", [page] )
.itShouldReturn( ViewResult, function (result) {
Assert.same( TFromEngine("documentation/documentationPage"), result.templateSource );
Assert.same( TFromEngine("layout.html"), result.layoutSource );
(result.data['title']:String).should.be('$title - Haxelib Documentation');
});
allResults.push( result.result );
}
Future.ofMany( allResults ).handle( function() done() );
});
});
}
}

View File

@@ -0,0 +1,137 @@
package website.controller;
import website.api.ProjectListApi;
import website.controller.*;
import ufront.web.result.*;
import ufront.web.result.ViewResult;
import website.Server;
using tink.CoreApi;
import haxelib.server.SiteDb;
// These imports are common for our various test-suite tools.
import buddy.*;
import mockatoo.Mockatoo.*;
import ufront.test.TestUtils.NaturalLanguageTests.*;
import utest.Assert;
using buddy.Should;
using ufront.test.TestUtils;
using mockatoo.Mockatoo;
class HomeControllerTest extends BuddySuite {
public function new() {
var haxelibSite = WebsiteTests.getTestApp();
var mockApi = mock( ProjectListApi );
haxelibSite.injector.map( ProjectListApi ).toValue( mockApi );
mockApi.all().returns( Success(new List()) );
mockApi.byUser(cast anyString).returns( Success(new List()) );
mockApi.byTag(cast anyString).returns( Success(new List()) );
mockApi.search(cast anyString).returns( Success(new List()) );
mockApi.latest(cast anyInt).returns( Success(new List()) );
mockApi.getTagList(cast anyInt).returns( Success(new List()) );
describe("When I go to the homepage", {
it("Should show our homepage view", function (done) {
whenIVisit( "/" )
.onTheApp( haxelibSite )
.itShouldLoad( HomeController, "homepage", [] )
.itShouldReturn( ViewResult, function (result) {
var title:String = result.data['title'];
(result.data['title']:String).should.be("Haxelib - the Haxe package manager");
Assert.same( result.templateSource, TFromEngine("home/homepage") );
Assert.same( result.layoutSource, TFromEngine("layout.html") );
// TODO: check we have a list of popular projects
// TODO: check we have a list of recent projects
})
.andFinishWith( done );
});
// TODO: it("Show me my projects if I am logged in");
});
describe("When I load the tags page", {
it("Should show me a list of the most popular tags, sorted by popularity", function (done) {
whenIVisit( "/t/")
.onTheApp( haxelibSite )
.itShouldLoad( HomeController, "tagList", [] )
.itShouldReturn( ViewResult, function(result) {
Assert.same( result.templateSource, TFromEngine("home/tagList") );
Assert.same( result.layoutSource, TFromEngine("layout.html") );
// TODO: check that the tags are listed...
})
.andFinishWith( done );
});
});
describe("When I load a tag page", {
it("Should show the list of projects with that tag", function (done) {
whenIVisit( "/t/games")
.onTheApp( haxelibSite )
.itShouldLoad( HomeController, "tag", ["games"] )
.itShouldReturn( ViewResult, function(result) {
Assert.same( result.templateSource, TFromEngine("home/projectList.html") );
Assert.same( result.layoutSource, TFromEngine("layout.html") );
// TODO: check that the matching projects are correct
})
.andFinishWith( done );
});
});
describe("When I load the 'all projects' page", {
it("Should show them all", function (done) {
whenIVisit( "/all")
.onTheApp( haxelibSite )
.itShouldLoad( HomeController, "all", [] )
.itShouldReturn( ViewResult, function(result) {
Assert.same( result.templateSource, TFromEngine("home/projectList.html") );
Assert.same( result.layoutSource, TFromEngine("layout.html") );
// TODO: check that all projects are loaded
})
.andFinishWith( done );
});
});
describe("When I search", {
// TODO: ask Nicolas, should we just use Google?
// it("Should show me the search form if there is no search term entered");
// it("Should show projects matching the name");
// it("Should show projects matching the description");
// it("Redirect straight to the project page if there's only 1 search result");
});
describe("When I want to access the data through a JSON API", {
it("Should give me search via JSON", function (done) {
whenIVisit( "/search.json" )
.withTheQueryParams([ "v"=>"web" ])
.onTheApp( haxelibSite )
.itShouldLoad( HomeController, "searchJson", [{ v: "web" }] )
.itShouldReturn( JsonResult, function (result) {
// TODO: check the data is good.
// TODO: check the JSON is valid.
})
.andFinishWith( done );
});
it("Should give me tags via JSON", function (done) {
whenIVisit( "/t/games.json" )
.onTheApp( haxelibSite )
.itShouldLoad( HomeController, "tag", ["games.json"] )
.itShouldReturn( JsonResult, function (result) {
// TODO: check the data is good.
// TODO: check the JSON is valid.
})
.andFinishWith( done );
});
it("Should give me all via JSON", function (done) {
whenIVisit( "/all.json" )
.onTheApp( haxelibSite )
.itShouldLoad( HomeController, "allJson", [] )
.itShouldReturn( JsonResult, function (result) {
// TODO: check the data is good.
// TODO: check the JSON is valid.
})
.andFinishWith( done );
});
});
}
}

View File

@@ -0,0 +1,158 @@
package website.controller;
import haxe.io.Bytes;
import website.api.ProjectApi;
import website.controller.*;
import ufront.web.result.*;
import ufront.web.result.ViewResult;
import website.Server;
import haxe.ds.Option;
using tink.CoreApi;
// These imports are common for our various test-suite tools.
import buddy.*;
import mockatoo.Mockatoo.*;
import ufront.test.TestUtils.NaturalLanguageTests.*;
import utest.Assert;
using buddy.Should;
using ufront.test.TestUtils;
using mockatoo.Mockatoo;
class ProjectControllerTest extends BuddySuite {
public function new() {
var haxelibSite = WebsiteTests.getTestApp();
var mockApi = mock( ProjectApi );
haxelibSite.injector.map( ProjectApi ).toValue( mockApi );
mockApi.projectInfo(cast anyString).returns( Success({
name: "detox",
desc: "Detox Description",
website: "https://github.com/jasononeil/detox",
owner: "jason",
license: "MIT",
curversion: "1.0.0-rc.8",
versions: [{ date: "2010-01-01 34:56:12", name:"1.0.0-rc.8", downloads:150, comments:"Breaking changes everywhere." }],
tags: new List(),
}) );
mockApi.readContentFromZip(cast anyString, cast anyString, cast anyString).returns( Success(Some("content")) );
mockApi.readBytesFromZip(cast anyString, cast anyString, cast anyString).returns( Success(Some(Bytes.ofString(""))) );
mockApi.getInfoForPath(cast anyString, cast anyString, cast anyString).returns( Success(Binary(12)) );
describe("When I view a project", {
it("Should show the project view for the latest version", function (done) {
whenIVisit( "/p/detox" )
.onTheApp( haxelibSite )
.itShouldLoad( ProjectController, "project", ["detox"] )
.itShouldReturn( ViewResult, function (result) {
// TODO: Check we got the latest version.
// TODO: Check we got the correct project.
Assert.same( TFromEngine("project/version.html"), result.templateSource );
Assert.same( TFromEngine("layout.html"), result.layoutSource );
})
.andFinishWith( done );
});
});
describe("When I view a project version", {
var whenILoadAProjectVersion = whenIVisit( "/p/detox/1.0.0-rc.8/" ).onTheApp( haxelibSite );
it("Should load the correct layout / view", function (done) {
whenILoadAProjectVersion
.itShouldLoad( ProjectController, "version", ["detox","1.0.0-rc.8"] )
.itShouldReturn( ViewResult, function(result) {
Assert.same( TFromEngine("project/version.html"), result.templateSource );
Assert.same( TFromEngine("layout.html"), result.layoutSource );
}).andFinishWith( done );
});
it("Should show me the README for the current version", function (done) {
whenILoadAProjectVersion.itShouldReturn( ViewResult, function(result) {
// TODO: add appropriate tests here...
}).andFinishWith( done );
});
it("Should show me the file list for the current version", function (done) {
whenILoadAProjectVersion.itShouldReturn( ViewResult, function(result) {
// TODO: add appropriate tests here...
}).andFinishWith( done );
});
it("Should show me a list of all versions", function (done) {
whenILoadAProjectVersion.itShouldReturn( ViewResult, function(result) {
// TODO: add appropriate tests here...
}).andFinishWith( done );
});
it("Should show me the haxelibs this depends on", function (done) {
whenILoadAProjectVersion.itShouldReturn( ViewResult, function(result) {
// TODO: add appropriate tests here...
}).andFinishWith( done );
});
it("Should show me the haxelibs that depend on this", function (done) {
whenILoadAProjectVersion.itShouldReturn( ViewResult, function(result) {
// TODO: add appropriate tests here...
}).andFinishWith( done );
});
it("Should let me know if there is a more recent version", function (done) {
whenILoadAProjectVersion.itShouldReturn( ViewResult, function(result) {
// TODO: add appropriate tests here...
}).andFinishWith( done );
});
it("Should let me know if this version is not considered stable", function (done) {
whenILoadAProjectVersion.itShouldReturn( ViewResult, function(result) {
// TODO: add appropriate tests here...
}).andFinishWith( done );
});
});
describe("When I view a project's versions", {
it("Should show me a list of all the versions of that project, with the ability to show stable releases only.", function(done) {
whenIVisit( "/p/detox/versions" )
.onTheApp( haxelibSite )
.itShouldLoad( ProjectController, "versionList", ["detox"] )
.itShouldReturn( ViewResult, function (result) {
// TODO: Check it shows the list of versions.
})
.andFinishWith( done );
});
});
describe("When I view a project's files", {
it("Should show me that file's source code in line", function (done) {
whenIVisit( "/p/detox/1.0.0-rc.8/files/src/Detox.hx" )
.onTheApp( haxelibSite )
.itShouldLoad( ProjectController, "file", ["detox","1.0.0-rc.8",["src","Detox.hx"]] )
.itShouldReturn( ViewResult, function (result) {
// TODO: Check it shows the source code for the file.
})
.andFinishWith( done );
});
it("Should render markdown files as HTML", function (done) {
whenIVisit( "/p/detox/1.0.0-rc.8/files/README.md" )
.onTheApp( haxelibSite )
.itShouldLoad( ProjectController, "file", ["detox","1.0.0-rc.8",["README.md"]] )
.itShouldReturn( ViewResult, function (result) {
// TODO: Check it shows the rendered markdown.
})
.andFinishWith( done );
});
it("Should show binary files size and a link to download it", function (done) {
whenIVisit( "/p/hxssl/3.0.0-alpha/files/ndll/Linux64/hxssl.ndll" )
.onTheApp( haxelibSite )
.itShouldLoad( ProjectController, "file", ["hxssl","3.0.0-alpha",["ndll","Linux64","hxssl.ndll"]] )
.itShouldReturn( ViewResult, function (result) {
// TODO: Check it shows the file name and download size.
})
.andFinishWith( done );
});
});
describe("When I view a projects docs", {
it("Should show the correct documentation for this version", function(done) {
whenIVisit( "/p/detox/1.0.0-rc.8/doc/dtx.widget.Widget" )
.onTheApp( haxelibSite )
.itShouldLoad( ProjectController, "docs", ["detox","1.0.0-rc.8","dtx.widget.Widget"] )
.itShouldReturn( ViewResult, function (result) {
// TODO: Check it loads the correct view, documentation is rendered, etc.
})
.andFinishWith( done );
});
});
}
}

View File

@@ -0,0 +1,46 @@
package website.controller;
import website.controller.*;
import ufront.web.result.*;
import website.Server;
// These imports are common for our various test-suite tools.
import buddy.*;
import mockatoo.Mockatoo.*;
import ufront.test.TestUtils.NaturalLanguageTests.*;
import utest.Assert;
using buddy.Should;
using ufront.test.TestUtils;
using mockatoo.Mockatoo;
class RSSControllerTest extends BuddySuite {
public function new() {
var haxelibSite = WebsiteTests.getTestApp();
describe("When I try to view the RSS feed", {
it("Should give me some valid XML with the latest updates", function (done) {
whenIVisit( "/rss" )
.onTheApp( haxelibSite )
.itShouldLoad( RSSController, "rss", [{number:null}] )
.itShouldReturn( ContentResult, function (result) {
result.contentType.should.be( "text/xml" );
var rss = Xml.parse( result.content );
})
.andFinishWith( done );
});
it("Should let me set the number of entries to include", function (done) {
whenIVisit( "/rss" )
.withTheQueryParams([ "number"=>"3" ])
.onTheApp( haxelibSite )
.itShouldLoad( RSSController, "rss", [{number:3}] )
.itShouldReturn( ContentResult, function (result) {
result.contentType.should.be( "text/xml" );
var rss = Xml.parse( result.content );
// TODO: check that 3 results were loaded.
})
.andFinishWith( done );
});
});
}
}

View File

@@ -0,0 +1,73 @@
package website.controller;
import haxe.crypto.Md5;
import haxelib.server.SiteDb;
import website.controller.*;
import website.api.UserApi;
import ufront.web.result.*;
import ufront.web.result.ViewResult;
import website.Server;
using tink.CoreApi;
// These imports are common for our various test-suite tools.
import buddy.*;
import mockatoo.Mockatoo.*;
import ufront.test.TestUtils.NaturalLanguageTests.*;
import utest.Assert;
using buddy.Should;
using ufront.test.TestUtils;
using mockatoo.Mockatoo;
class UserControllerTest extends BuddySuite {
public function new() {
var haxelibSite = WebsiteTests.getTestApp();
var mockApi = mock( UserApi );
haxelibSite.injector.map( UserApi ).toValue( mockApi );
function mockUser(user,name,email) {
var u = new User();
u.name = user;
u.fullname = name;
u.email = email;
var hash = Md5.encode( email );
return { user:u, emailHash:hash, projects:[], totalDownloads:[] };
}
var user1 = mockUser( "jason", "Jason O'Neil", "jason@example.org" );
var user2 = mockUser( "ncanasse", "Nicolas Canasse", "nc@example.org" );
var projects = [];
mockApi.getUserProfile(cast anyString).returns( Success(new Pair(user1.user,[])) );
mockApi.getUserList().returns( Success([user1, user2]) );
describe("When I look at the profile of a user", {
it("Should show me that users profile and their projects", function (done) {
whenIVisit( "/u/jason" )
.onTheApp( haxelibSite )
.itShouldLoad( UserController, "profile", ["jason"] )
.itShouldReturn( ViewResult, function (result) {
var title:String = result.data['title'];
(result.data['title']:String).should.be("jason (Jason O'Neil) on Haxelib");
Assert.same( result.templateSource, TFromEngine("user/profile") );
Assert.same( result.layoutSource, TFromEngine("layout.html") );
})
.andFinishWith( done );
});
});
describe("When I want to see a list of users", {
it("Should show me that list, sorted by number of projects", function (done) {
whenIVisit( "/u" )
.onTheApp( haxelibSite )
.itShouldLoad( UserController, "list", [] )
.itShouldReturn( ViewResult, function (result) {
var title:String = result.data['title'];
(result.data['title']:String).should.be("Haxelib Contributors");
Assert.same( result.templateSource, TFromEngine("user/list") );
Assert.same( result.layoutSource, TFromEngine("layout.html") );
})
.andFinishWith( done );
});
});
}
}