$res = $stratum->store($key, $value); } $res = $stratum->query(); asort($pairs, TRUE); Tap::is($res, $pairs, 'stored a bunch of pairs ... query matches what I stored'); //Tap::debug( $pairs ); //Tap::debug( $res ); Tap::is($stratum->query(array('limit' => '0,1')), array_slice($pairs, 0, 1, TRUE), 'queried the first in the list'); Tap::is($stratum->query(array('limit' => 2, 'sort' => 'desc')), array_slice($pairs, -2, NULL, TRUE), 'queried the last two in the list'); $middle = array_slice($pairs, 5, 1, TRUE); list($key, $value) = each($middle); Tap::is($stratum->query(array('min' => $value, 'limit' => 2)), array_slice($pairs, 5, 2, TRUE), 'queried from the middle of the list'); Tap::is($stratum->query(array('max' => $value, 'limit' => 2, 'sort' => 'DESC')), array_reverse(array_slice($pairs, 4, 2, TRUE), TRUE), 'queried from the middle of the list in reverse'); Tap::is($stratum->query(array('search' => array_values(array_slice($pairs, 2, 3, TRUE)))), array_slice($pairs, 2, 3, TRUE), 'search by value matches correct result set'); $expected = $pairs; ksort($expected); $res = $stratum->batch(); Tap::is(count($res), count($pairs), 'batch call returns correct result count'); if ($use_bin_constraint) { $expected = $res; Tap::ok(TRUE, 'skipping first sort order because we cant do exact match of mysql binary ordering'); } else { Tap::is($res, $expected, 'batch call returns result set sorted by key'); } Tap::is($stratum->batch(array('limit' => '0,1')), array_slice($expected, 0, 1, TRUE), 'batch the first in the list'); Tap::is($stratum->batch(array('limit' => 2, 'sort' => 'desc')), array_slice(array_reverse($expected, TRUE), 0, 2, TRUE), 'batch the last two in the list'); Tap::is($stratum->batch(array('start_after' => min(array_keys($expected)))), array_slice($expected, 1, count($expected), TRUE), 'batch starting after the first one'); $expected = array_reverse($expected, TRUE); Tap::is($stratum->batch(array('sort' => 'DESC')), $expected, 'batch call returns result set sorted by key and sort desc works'); Tap::ok($stratum->delete($key), 'successfully deleted a constraint'); //Tap::debug($pairs);
<?php namespace Gaia\Stockpile; use Gaia\DB\Transaction; use Gaia\Test\Tap; $user_id = uniqueUserID(); $item_id = uniqueNumber(1, 1000000); stockpile($app, $user_id)->add($item_id, 5); // cant subtract zero $e = NULL; try { stockpile($app, $user_id)->subtract($item_id, 0); } catch (\Exception $e) { } Tap::ok($e instanceof \Exception && preg_match('/cannot subtract/', $e->getMessage()), 'cant subtract zero'); // subtract more than we have. $starting_total = stockpile($app, $user_id)->get($item_id); $e = NULL; try { $stockpile = stockpile($app, $user_id); $stockpile->subtract($item_id, quantify($stockpile->get($item_id)) + 1); } catch (\Exception $e) { } Tap::ok($e instanceof \Exception && preg_match('/not enough/', $e->getMessage()), 'wont allow to subtract more than you have'); // after failed subtraction, amount is still correct. $total = stockpile($app, $user_id)->get($item_id); Tap::is($total, $starting_total, 'after failed subtract, amount is still the same');
Transaction::reset(); Tap::ok(Transaction::start(), 'started a transaction at the global level'); $conn1 = $newconn(); $conn2 = $newconn(); Tap::ok($conn1->start(), 'started a transaction on conn1'); Tap::ok($conn2->start(), 'started a transaction on conn2'); $rs = $conn1->execute("insert into {$table} values (3)"); Tap::ok($rs, 'inserted a row into test table from conn1'); //if( ! $rs ) Tap::debug( $conn1 ); $rs = $conn2->execute("insert into {$table} values(4)"); Tap::ok($rs, 'inserted a row into test table from conn2'); //if( ! $rs ) Tap::debug( $conn2 ); Tap::ok($conn1->commit(), 'committed inserted row on conn1'); Tap::ok($conn2->commit(), 'committed inserted row on conn2'); Tap::ok(Transaction::rollback(), 'rolled back the transaction at the global level'); Tap::ok($rs = $dbmain->execute("select id from {$table}"), 'selected all rows from the table'); $ct = $rs->affected(); Tap::is($ct, 2, '2 rows in the table, new rows rolled back'); $rs = $conn1->execute("select id from {$table}"); Tap::is($rs, FALSE, 'after rolling back, new queries fail on rolled back db object'); $dbmain->execute("drop table {$table}"); $db = $newconn(); $raw = file_get_contents(__DIR__ . '/../sample/i_can_eat_glass.txt'); $lines = explode("\n", $raw); $lines = array_slice($lines, 0, 10) + array_slice($lines, 100, 10) + array_slice($lines, 200, 10) + array_slice($lines, 200, 10); $raw = implode("\n", $lines); $sql = "CREATE TEMPORARY TABLE t1utf8 (`i` INT UNSIGNED NOT NULL PRIMARY KEY, `line` VARCHAR(5000) ) ENGINE=InnoDB DEFAULT CHARACTER SET utf8"; $db->execute($sql); foreach ($lines as $i => $line) { //$lines[ $i ] = $line = mb_convert_encoding($line, 'UTF-8', 'auto'); $db->execute('INSERT INTO t1utf8 (`i`, `line`) VALUES (%i, %s)', $i, $line);
advanceCurrentTime(1); $q->set($stockpile->newId(), array('test')); advanceCurrentTime(1); $quantity = stockpile($app, $user_id)->add($item_id, $q); $serials = $quantity->serials(); Tap::ok(is_array($serials) && count($serials) == 4, 'after adding 3 new items, quantity returns 4 serials, since we had 1 before'); $digit_test = TRUE; foreach ($serials as $serial) { if (!ctype_digit(quantify($serial))) { $digit_test = FALSE; } if ($serial < 1) { $digit_test = FALSE; } } Tap::ok($digit_test, 'all the serials returned are integers'); $quantity = stockpile($app, $user_id)->subtract($item_id, $quantity->grab(3)); Tap::is($quantity->serials(), array($first_serial), 'after deleting 3, back down to my original item'); $quantity->set($serial = lastElement($quantity->serials()), array('event' => 'xmas')); $res = stockpile($app, $user_id)->add($item_id, $quantity); Tap::is($quantity->all(), $res->all(), 'after adding properties, returned result matches what we just stored'); Tap::is($res->get($serial), array('event' => 'xmas'), 'the property was properly stored for the serial'); for ($i = 0; $i < 10; $i++) { stockpile($app, $user_id)->add($item_id, $quantity); } Tap::is(stockpile($app, $user_id)->get($item_id), $quantity, 'after adding the same serial over and over, still only have the one item'); // need to think about how to test deadlocks ... without deadlocking in a test :P $user_id = uniqueUserID(); $stockpile = stockpile($app, $user_id); $item_id = uniqueNumber(1, 10000000); $quantity = $stockpile->quantity();
$res = array(); foreach (souk($app)->fetch(souk($app)->search(array('item_id' => $item_id, 'seller' => $seller_id, 'floor' => 4, 'ceiling' => 6))) as $id => $listing) { $res[$listing->price] = TRUE; } $res = array_keys($res); sort($res); Tap::is($res, array(4, 5, 6), 'setting floor and ceiling limits the result set to prices in the correct range'); $search = souk($app)->search(array('item_id' => $item_id, 'seller' => $seller_id, 'closed' => 0)); $id = array_shift($search); souk($app)->close($id); $ids = souk($app)->search(array('item_id' => $item_id, 'seller' => $seller_id, 'closed' => 0)); Tap::ok(!in_array($id, $ids, TRUE), 'after closing an item, it no longer appears in the list of unclosed items'); $res = souk($app)->fetch(souk($app)->search(array('item_id' => $item_id, 'seller' => $seller_id, 'closed' => 0, 'only' => 'bid'))); $bidonly = TRUE; foreach ($res as $listing) { if (!$listing->step || $listing->price) { $bidonly = FALSE; } } Tap::ok($bidonly, 'searching with only=>bid param returns results that are all bid only items, no prices'); $res = souk($app)->fetch(souk($app)->search(array('item_id' => $item_id, 'seller' => $seller_id, 'closed' => 0, 'only' => 'buy'))); $buynow = TRUE; foreach ($res as $listing) { if ($listing->step || !$listing->price) { $buynow = FALSE; } } Tap::ok($buynow, 'searching with only=>buy param returns results that are all buy now only items, no bids'); unset($seller_id); unset($buyer_id); unset($item_id);
<?php use Gaia\Test\Tap; use Gaia\affiliate; Tap::plan(14); Tap::ok($affiliate instanceof affiliate\Iface, 'object implements the affiliate interface'); $identifiers = array('a' . microtime(TRUE) . '.' . mt_rand(), 'b' . microtime(TRUE) . '.' . mt_rand(), 'c' . microtime(TRUE) . '.' . mt_rand()); $res = $affiliate->join($identifiers); $affiliate_id = $res[$identifiers[0]]; Tap::is($res, array_fill_keys($identifiers, $affiliate_id), 'ran the join command and got back a key list of identifiers mapping to my affiliate id'); Tap::ok(ctype_digit($affiliate_id), 'affiliate id is a string of digits'); Tap::is($affiliate->related($identifiers), $res, 'affiliate::related() returns same response as join did'); $identifiers[] = $last = 'd' . microtime(TRUE) . '.' . mt_rand(); $res = $affiliate->join($identifiers); Tap::is($res, array_fill_keys($identifiers, $affiliate_id), 'join a new identifier to the group'); Tap::is($affiliate->related($identifiers), $res, 'affiliate::related() returns same response as join did'); Tap::is($affiliate->identifiers(array($affiliate_id)), array($affiliate_id => $identifiers), 'affiliate::get returns identifiers mapped to the affiliate id'); $unrelated = 'd' . microtime(TRUE) . '.' . mt_rand(); $res = $affiliate->join(array($unrelated)); $new_affiliate_id = $res[$unrelated]; Tap::is($affiliate->identifiers(array($new_affiliate_id)), array($new_affiliate_id => array($unrelated)), 'joining a single identifer, creates an orphaned new affiliateid'); Tap::isnt($affiliate_id, $new_affiliate_id, 'old and new affiliate ids are different'); $res = $affiliate->join(array($last, $unrelated)); Tap::is($res, array_fill_keys(array_merge($identifiers, array($unrelated)), $affiliate_id), 'joined unrelated to the other identifiers'); Tap::is($affiliate->related($identifiers), array_fill_keys(array_merge($identifiers, array($unrelated)), $affiliate_id), 'the new identifer is now related to the rest'); $affiliate->delete($identifiers); Tap::is($affiliate->related($identifiers), array_fill_keys($identifiers, NULL), 'after deleting the identifiers, no associations'); Tap::is($affiliate->related(array($unrelated)), array_fill_keys(array($unrelated), $affiliate_id), 'the one identifier we didnt delete still remains'); $affiliate->delete(array($unrelated)); Tap::is($affiliate->related(array($unrelated)), array_fill_keys(array($unrelated), NULL), 'deleted the last identifier');
<?php use Gaia\Skein; use Gaia\Test\Tap; use Gaia\Time; if (!isset($extra_tests)) { $extra_tests = 0; } Tap::plan(27 + $extra_tests); Tap::ok($skein instanceof Skein\Iface, 'created new skein object, implements expected interface'); $id = $skein->add($data = array('foo' => mt_rand(1, 100000000))); Tap::ok(ctype_digit($id), 'added data, got back an id'); Tap::is($skein->get($id), $data, 'read back the data I stored'); Tap::is($skein->get(array($id)), array($id => $data), 'multi-get interface works too'); $data = array('foo' => mt_rand(1, 100000000)); $skein->store($id, $data); Tap::is($skein->get($id), $data, 'stored the data with new values, get returns what I wrote'); $batch = array($id => $data); for ($i = 0; $i < 10; $i++) { Time::offset(86400 * 5); $id = $skein->add($data = array('foo' => mt_rand(1, 100000000))); $batch[$id] = $data; } $ids = array_keys($batch); $res = $skein->get($ids); Tap::is($res, $batch, 'added a bunch of keys and read them back using get( ids ) interface'); Tap::is($skein->ids(array('limit' => 100)), $ids, 'got the keys back in ascending order'); Tap::is($res = $skein->ids(array('sort' => 'ascending', 'limit' => 5)), array_slice($ids, 0, 5), 'got the keys back in ascending order, limit 5'); Tap::is($res = $skein->ids(array('sort' => 'ascending', 'limit' => 5, 'start_after' => $ids[5])), array_slice($ids, 6, 5), 'got the keys back in ascending order, limit 5, starting after the 5th id'); Tap::is($res = $skein->ids(array('limit' => 1)), array($ids[0]), 'with limit 1, got back the 1st id'); $ids = array_reverse($ids);
Tap::cmp_ok($cache->get(array($k)), '===', array(), 'after setting the key to null, key is deleted'); Tap::is($cache->set($k, $v = '0'), TRUE, 'setting a key to zero returns true'); Tap::cmp_ok($cache->get($k), '===', $v, 'after setting the key to 0, get returns zero value'); Tap::cmp_ok($cache->get(array($k)), '===', array($k => $v), 'multi-get returns the key with zero value'); Tap::ok($cache->set($k, 1, $ttl = 3600 * 24 * 30), 'setting with a huge timeout'); Tap::cmp_ok(strval($cache->get($k)), '===', '1', 'get returns correct value'); $incr = 1000000; Tap::ok($cache->increment($k, $incr), 'incrementing with a large number'); Tap::cmp_ok(strval($cache->get($k)), '===', strval($incr + 1), 'get returns correct value'); Tap::ok($cache->decrement($k, $incr), 'decrementing with a large number'); Tap::cmp_ok(intval($cache->get($k)), '===', 1, 'get returns correct value'); $huge_number = 9.223372036854776E+18; if (!is_int($huge_number)) { $huge_number = 2147483646; } Tap::Debug("testing with {$huge_number}"); Tap::ok($cache->set($k, $v = $huge_number), 'setting a huge number'); Tap::cmp_ok(strval($cache->get($k)), '===', strval($v), 'get returns correct value'); $v = $v + 1; Tap::cmp_ok(strval($cache->increment($k, 1)), '===', strval($v), 'increment a huge number by 1'); Tap::cmp_ok(strval($cache->get($k)), '===', strval($v), 'get returns correct value'); $cache->set($k, $v); $v = $v - 1; Tap::cmp_ok(strval($cache->decrement($k, 1)), '===', strval($v), 'decrement a huge number by 1'); Tap::cmp_ok(strval($cache->get($k)), '===', strval($v), 'get returns correct value'); $k = 'gaia/cache/test/' . microtime(TRUE) . '/' . mt_rand(1, 10000); $v = '我能吞下玻璃而不傷身體'; Tap::ok($cache->set($k, $v), 'setting a string with utf-8 chars in it'); Tap::cmp_ok(strval($cache->get($k)), '===', $v, 'get returns correct value'); Tap::ok($cache->delete($k), 'deleting the key'); Tap::cmp_ok($cache->get($k), '===', NULL, 'after deleting, get returns NULL');
<?php use Gaia\Test\Tap; use Gaia\NewId; Tap::plan(4); $app = 'test'; $new = new NewId\DB($db, $app = 'test'); $res = $new->testInit(); $id = $new->id(); Tap::ok(ctype_digit($id), 'id returned is a string of digits'); $ids = $new->ids(10); Tap::ok(is_array($ids) && count($ids) == 10, 'ids returned a list of 10 items when I asked for 10'); $status = TRUE; foreach ($ids as $id) { if (!ctype_digit($id)) { $status = FALSE; } } Tap::ok($status, 'all of the ids are digits'); $id1 = $new->id(); $id2 = $new->id(); Tap::cmp_ok($id1, '<', $id2, 'an id generated a second later is larger than the first one');
Tap::ok($elapsed < 10, "added {$i} items in 10 seconds or less (no transaction). did it in: " . number_format($elapsed, 3) . ' seconds'); // read back those same items $start = microtime(TRUE); for ($i = 0; $i < $iterations; $i++) { $stockpile->get($i + 1); } $elapsed = microtime(TRUE) - $start; Tap::ok($elapsed < 10, "read {$i} items in 10 seconds or less (serial order). did it in: " . number_format($elapsed, 3) . ' seconds'); // change user ids and do it again, this time with a transaction. $user_id = uniqueUserID(); Transaction::claimStart(); $stockpile = stockpile($app, $user_id); $start = microtime(TRUE); for ($i = 0; $i < $iterations; $i++) { $stockpile->add($i + 1, uniqueNumber(1, 10000)); } Transaction::commit(); $elapsed = microtime(TRUE) - $start; Tap::ok($elapsed < 10, "added {$i} items in 10 seconds or less (with transaction). did it in: " . number_format($elapsed, 3) . ' seconds'); $stockpile = stockpile($app, $user_id); $start = microtime(TRUE); for ($i = 0; $i < $iterations; $i += 100) { $stockpile->get(range($i + 1, $i + 101)); } $elapsed = microtime(TRUE) - $start; Tap::ok($elapsed < 3, "read {$i} items in 3 seconds or less (multi-get, chunks of 100). did it in: " . number_format($elapsed, 3) . ' seconds'); $start = microtime(TRUE); $stockpile->all(); $elapsed = microtime(TRUE) - $start; Tap::ok($elapsed < 3, "read {$i} items in 3 seconds or less (all at once). did it in: " . number_format($elapsed, 3) . ' seconds');
$e = NULL; try { stockpile($app, '01'); } catch (\Exception $e) { } Tap::ok($e instanceof \Exception && preg_match('/invalid user/', $e->getMessage()), 'user id cant have leading zeros'); $e = NULL; try { stockpile($app, $user_id)->get('a'); } catch (\Exception $e) { } Tap::ok($e instanceof \Exception && preg_match('/invalid item/', $e->getMessage()), 'get item id must be a number'); $e = NULL; try { stockpile($app, $user_id)->get('001'); } catch (\Exception $e) { } Tap::ok($e instanceof \Exception && preg_match('/invalid item/', $e->getMessage()), 'get item id cant have leading zeros'); $e = NULL; try { stockpile($app, $user_id)->get('-1'); } catch (\Exception $e) { } Tap::ok($e instanceof \Exception && preg_match('/invalid item/', $e->getMessage()), 'get item id must be a positive number'); $e = NULL; try { stockpile($app, $user_id)->get(array('-1')); } catch (\Exception $e) { } Tap::ok($e instanceof \Exception && preg_match('/invalid item/', $e->getMessage()), 'get item id must be a positive number when passed in as a multi-get too');
Tap::ok($identifier->store($id, $name), 'able to overwrite with the same name'); $oldname = $name; $name = 'name' . microtime(TRUE); Tap::ok($identifier->store($id, $name), 'able to overwrite with the a new name'); Tap::is($identifier->byName($name), $id, 'found the id by new name'); Tap::is($identifier->byName($oldname), NULL, 'oldname doesnt match anything now'); $oldid = $id; $id = strval(mt_rand(1, 100000000)); Tap::ok($identifier->store($id, $name), 'able to overwrite name with the a new id'); Tap::is($identifier->byId($id), $name, 'found the name by new id'); Tap::is($identifier->byID($oldid), NULL, 'oldid doesnt match anything now'); $e = null; try { $identifier->store(strval(mt_rand(1, 100000000)), $name, $strict = TRUE); } catch (Exception $e) { $e = $e->__toString(); } Tap::like($e, '#name-taken#i', 'trying to map name to new id with strict clause thrown in fails'); Tap::ok($identifier->delete($id, $name), 'deleted the pairing'); Tap::is($identifier->byName($name), NULL, 'after deleting, no name lookup'); Tap::is($identifier->byId($id), NULL, 'after deleting, no id lookup'); Transaction::start(); $identifier = $create_identifier(); Tap::ok($identifier->store($id, $name), 'store the name/id pairing with txn'); Tap::is($identifier->byName($name), $id, 'found the id by name'); Tap::is($identifier->byId($id), $name, 'found the name by id'); Transaction::rollback(); Transaction::reset(); $identifier = $create_identifier(); Tap::is($identifier->byName($name), NULL, 'after rollback, no id found by name'); Tap::is($identifier->byId($id), NULL, 'after rollback, no name found by id');
new Transfer($trade, $other); } catch (\Exception $e) { } Tap::ok($e instanceof \Exception && preg_match('/transfer/i', $e->getMessage()), 'no nesting of transfers'); $e = NULL; Transaction::claimStart(); try { new Transfer($core, $core); } catch (\Exception $e) { } Tap::ok($e instanceof \Exception && preg_match('/need\\stwo/i', $e->getMessage()), 'enforce two different parties to trade'); $e = NULL; Transaction::reset(); try { new Transfer(stockpile($app, $other_id), stockpile($app, $other_id)); } catch (\Exception $e) { } Tap::ok($e instanceof \Exception && preg_match('/transaction/i', $e->getMessage()), 'blow up when no transaction'); $e = NULL; try { new Transfer(stockpile($app, $other_id), stockpile($app, $other_id)); } catch (\Exception $e) { } Tap::ok($e instanceof \Exception && preg_match('/transaction/i', $e->getMessage()), 'blow up when neither has a transaction'); Transaction::reset(); Transaction::claimStart(); $trade = new Transfer(stockpile($app, $user_id), stockpile('test2', $user_id)); Tap::is(quantify($trade->subtract($item_id)), 2, 'move items for same user to different app (escrow example with transaction)'); Tap::is(quantify($trade->add($item_id)), 3, 'add it back from other app to main'); Tap::ok(Transaction::commit(), 'transaction commits successfully');
namespace Gaia\Stockpile; use Gaia\DB\Transaction; use Gaia\Test\Tap; $user_id = uniqueUserID(); $item_id = uniqueNumber(1, 1000000); // add several items to the account. $items = array($item_id, uniqueNumber(1, 1000000), uniqueNumber(1, 1000000)); sort($items, SORT_NUMERIC); Transaction::claimStart(); $stockpile = stockpile($app, $user_id); foreach ($items as $id) { $stockpile->add($id); } Tap::ok(Transaction::commit(), 'add many items in a transaction'); // grab all the data at once $all = $stockpile->all(); Tap::is(array_keys($all), $items, 'got back all the items we put in'); // test multi-get $some = $stockpile->get($some_keys = array($items[0], $items[1])); Tap::is(array_keys($some), $some_keys, 'multi-get only grabs the items we specified'); // test multi-get with an item that isn't in the list. $stockpile = stockpile($app, $user_id); do { $not_in_list = uniqueNumber(1, 100000); } while (in_array($not_in_list, $items)); $res = $stockpile->get($not_in_list); Tap::is(quantify($res), 0, 'get for an item that doesnt exist in user inventory returns zero'); $res = $stockpile->get(array($not_in_list)); Tap::is($res, array(), 'multi-get for an item that doesnt exist in user inventory returns empty array');