RedUNIT\Base\Cross::testSelfReferentialCRUD PHP Method

testSelfReferentialCRUD() public method

Test many different scenarios with self referential many-to-many relations.
public testSelfReferentialCRUD ( ) : void
return void
    public function testSelfReferentialCRUD()
    {
        R::nuke();
        $buddies = R::dispense('buddy', 4);
        $buddies[0]->name = 'A';
        $buddies[1]->name = 'B';
        $buddies[2]->name = 'C';
        $buddies[3]->name = 'D';
        $buddies[0]->sharedBuddyList = array($buddies[1], $buddies[2]);
        $buddies[3]->sharedBuddyList = array($buddies[2]);
        R::storeAll($buddies);
        $buddies[0] = $buddies[0]->fresh();
        asrt(count($buddies[0]->sharedBuddyList), 2);
        //does this yield valid combinations - cross relations / self ref n-m
        //need to symmetric....
        $names = R::gatherLabels($buddies[0]->sharedBuddyList);
        sort($names);
        $names = implode(',', $names);
        asrt($names, 'B,C');
        unset($buddies[0]->sharedBuddy);
        R::storeAll($buddies);
        $buddies[0] = $buddies[0]->fresh();
        asrt(count($buddies[0]->sharedBuddyList), 2);
        $buddies[3] = $buddies[3]->fresh();
        asrt(count($buddies[3]->sharedBuddyList), 1);
        $names = R::gatherLabels($buddies[3]->sharedBuddyList);
        sort($names);
        $names = implode(',', $names);
        asrt($names, 'C');
        $buddies[2] = $buddies[2]->fresh();
        asrt(count($buddies[2]->sharedBuddyList), 2);
        $names = R::gatherLabels($buddies[2]->sharedBuddyList);
        sort($names);
        $names = implode(',', $names);
        asrt($names, 'A,D');
        $buddies[1] = $buddies[1]->fresh();
        asrt(count($buddies[1]->sharedBuddyList), 1);
        $names = R::gatherLabels($buddies[1]->sharedBuddyList);
        sort($names);
        $names = implode(',', $names);
        asrt($names, 'A');
        //Can we add one?
        $buddies[1]->sharedBuddyList[] = R::dispense('buddy')->setAttr('name', 'E');
        R::store($buddies[1]);
        $buddies[0] = $buddies[0]->fresh();
        asrt(count($buddies[0]->sharedBuddyList), 2);
        $names = R::gatherLabels($buddies[0]->sharedBuddyList);
        sort($names);
        $names = implode(',', $names);
        asrt($names, 'B,C');
        $buddies[1] = $buddies[1]->fresh();
        asrt(count($buddies[1]->sharedBuddyList), 2);
        $names = R::gatherLabels($buddies[1]->sharedBuddyList);
        sort($names);
        $names = implode(',', $names);
        asrt($names, 'A,E');
        $all = R::find('buddy');
        asrt(count($all), 5);
        foreach ($buddies[1]->sharedBuddy as $buddy) {
            if ($buddy->name === 'E') {
                $buddyE = $buddy;
            }
        }
        asrt(isset($buddyE), TRUE);
        asrt($buddyE->name, 'E');
        //can we update?
        foreach ($buddies[0]->sharedBuddy as $buddy) {
            if ($buddy->name === 'C') {
                $buddy->name = 'C2';
            }
        }
        R::store($buddies[0]);
        $buddies[0] = $buddies[0]->fresh();
        asrt(count($buddies[0]->sharedBuddyList), 2);
        $names = R::gatherLabels($buddies[0]->sharedBuddyList);
        sort($names);
        $names = implode(',', $names);
        asrt($names, 'B,C2');
        $buddies[2] = $buddies[2]->fresh();
        asrt(count($buddies[2]->sharedBuddyList), 2);
        $names = R::gatherLabels($buddies[2]->sharedBuddyList);
        sort($names);
        $names = implode(',', $names);
        asrt($names, 'A,D');
        //can we delete?
        foreach ($buddies[0]->sharedBuddyList as $id => $buddy) {
            if ($buddy->name === 'B') {
                unset($buddies[0]->sharedBuddyList[$id]);
            }
        }
        R::store($buddies[0]);
        $buddies[0] = $buddies[0]->fresh();
        asrt(count($buddies[0]->sharedBuddyList), 1);
        $names = R::gatherLabels($buddies[0]->sharedBuddyList);
        sort($names);
        $names = implode(',', $names);
        asrt($names, 'C2');
        $buddies[1] = $buddies[1]->fresh();
        asrt(count($buddies[1]->sharedBuddyList), 1);
        $names = R::gatherLabels($buddies[1]->sharedBuddyList);
        sort($names);
        $names = implode(',', $names);
        asrt($names, 'E');
        asrt(R::count('buddy'), 5);
        asrt(R::count('buddyBuddy'), 3);
        $buddies[3] = $buddies[3]->fresh();
        asrt(count($buddies[3]->sharedBuddyList), 1);
        $names = R::gatherLabels($buddies[3]->sharedBuddyList);
        sort($names);
        $names = implode(',', $names);
        asrt($names, 'C2');
        $buddies[2] = $buddies[2]->fresh();
        asrt(count($buddies[2]->sharedBuddyList), 2);
        $names = R::gatherLabels($buddies[2]->sharedBuddyList);
        sort($names);
        $names = implode(',', $names);
        asrt($names, 'A,D');
        $buddyE = $buddyE->fresh();
        asrt(count($buddyE->sharedBuddyList), 1);
        $names = R::gatherLabels($buddyE->sharedBuddyList);
        sort($names);
        $names = implode(',', $names);
        asrt($names, 'B');
        //can we access linked_by -- o dear mysql again! cant have alias in WHERE!
        if ($this->currentlyActiveDriverID === 'mysql') {
            $buddyE = $buddyE->fresh();
            asrt(count($buddyE->with(' HAVING linked_by > 0 ')->sharedBuddyList), 1);
            $buddyE = $buddyE->fresh();
            asrt(count($buddyE->with(' HAVING linked_by < 0 ')->sharedBuddyList), 0);
        }
        //even postgres sucks. Only SQLite knows how to handle this.
        //I dont give a fuck whether it's an SQL standard or not, it should just work.
        if ($this->currentlyActiveDriverID === 'sqlite') {
            $buddyE = $buddyE->fresh();
            asrt(count($buddyE->withCondition(' linked_by > 0 ')->sharedBuddyList), 1);
            $buddyE = $buddyE->fresh();
            asrt(count($buddyE->withCondition(' linked_by < 0 ')->sharedBuddyList), 0);
        }
        $buddyE = $buddyE->fresh();
        asrt(count($buddyE->withCondition(' buddy_buddy.buddy_id > 0 AND buddy_buddy.buddy2_id > 0 ')->sharedBuddyList), 1);
        $buddyE = $buddyE->fresh();
        asrt(count($buddyE->withCondition(' buddy_buddy.buddy_id < 0 AND buddy_buddy.buddy2_id < 0 ')->sharedBuddyList), 0);
    }