add authors, composers, history and settings to Tune::merge()

This commit is contained in:
2018-05-10 21:34:53 -04:00
parent 82dc3de079
commit d4d3654653
12 changed files with 640 additions and 28 deletions

View File

@@ -20,7 +20,8 @@
"illuminate/database": "^5.5",
"enzyme/collection": "^1.0",
"illuminate/Pipeline": "^5.5",
"league/pipeline": "^0.3.0"
"league/pipeline": "^0.3.0",
"php-deal/framework": "^0.4.1"
},
"autoload": {
"psr-4": {

516
composer.lock generated
View File

@@ -4,8 +4,63 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "e46f731a6416a18f1e837a755b805e75",
"content-hash": "fccd5312f23cc5a37ed9a08186f8a1ef",
"packages": [
{
"name": "beberlei/assert",
"version": "v2.9.5",
"source": {
"type": "git",
"url": "https://github.com/beberlei/assert.git",
"reference": "c07fe163d6a3b3e4b1275981ec004397954afa89"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/beberlei/assert/zipball/c07fe163d6a3b3e4b1275981ec004397954afa89",
"reference": "c07fe163d6a3b3e4b1275981ec004397954afa89",
"shasum": ""
},
"require": {
"ext-mbstring": "*",
"php": ">=5.3"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^2.1.1",
"phpunit/phpunit": "^4.8.35|^5.7"
},
"type": "library",
"autoload": {
"psr-4": {
"Assert\\": "lib/Assert"
},
"files": [
"lib/Assert/functions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-2-Clause"
],
"authors": [
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de",
"role": "Lead Developer"
},
{
"name": "Richard Quadling",
"email": "rquadling@gmail.com",
"role": "Collaborator"
}
],
"description": "Thin assertion library for input validation in business models.",
"keywords": [
"assert",
"assertion",
"validation"
],
"time": "2018-04-16T11:18:27+00:00"
},
{
"name": "behat/gherkin",
"version": "v4.5.1",
@@ -232,6 +287,148 @@
"description": "Flexible Stub wrapper for PHPUnit's Mock Builder",
"time": "2018-02-18T13:56:56+00:00"
},
{
"name": "doctrine/annotations",
"version": "v1.6.0",
"source": {
"type": "git",
"url": "https://github.com/doctrine/annotations.git",
"reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/annotations/zipball/c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5",
"reference": "c7f2050c68a9ab0bdb0f98567ec08d80ea7d24d5",
"shasum": ""
},
"require": {
"doctrine/lexer": "1.*",
"php": "^7.1"
},
"require-dev": {
"doctrine/cache": "1.*",
"phpunit/phpunit": "^6.4"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.6.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\Common\\Annotations\\": "lib/Doctrine/Common/Annotations"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "Docblock Annotations Parser",
"homepage": "http://www.doctrine-project.org",
"keywords": [
"annotations",
"docblock",
"parser"
],
"time": "2017-12-06T07:11:42+00:00"
},
{
"name": "doctrine/cache",
"version": "v1.7.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/cache.git",
"reference": "b3217d58609e9c8e661cd41357a54d926c4a2a1a"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/cache/zipball/b3217d58609e9c8e661cd41357a54d926c4a2a1a",
"reference": "b3217d58609e9c8e661cd41357a54d926c4a2a1a",
"shasum": ""
},
"require": {
"php": "~7.1"
},
"conflict": {
"doctrine/common": ">2.2,<2.4"
},
"require-dev": {
"alcaeus/mongo-php-adapter": "^1.1",
"mongodb/mongodb": "^1.1",
"phpunit/phpunit": "^5.7",
"predis/predis": "~1.0"
},
"suggest": {
"alcaeus/mongo-php-adapter": "Required to use legacy MongoDB driver"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.7.x-dev"
}
},
"autoload": {
"psr-4": {
"Doctrine\\Common\\Cache\\": "lib/Doctrine/Common/Cache"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Benjamin Eberlei",
"email": "kontakt@beberlei.de"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Jonathan Wage",
"email": "jonwage@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "Caching library offering an object-oriented API for many cache backends",
"homepage": "http://www.doctrine-project.org",
"keywords": [
"cache",
"caching"
],
"time": "2017-08-25T07:02:50+00:00"
},
{
"name": "doctrine/inflector",
"version": "v1.3.0",
@@ -353,6 +550,60 @@
],
"time": "2017-07-22T11:58:36+00:00"
},
{
"name": "doctrine/lexer",
"version": "v1.0.1",
"source": {
"type": "git",
"url": "https://github.com/doctrine/lexer.git",
"reference": "83893c552fd2045dd78aef794c31e694c37c0b8c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/doctrine/lexer/zipball/83893c552fd2045dd78aef794c31e694c37c0b8c",
"reference": "83893c552fd2045dd78aef794c31e694c37c0b8c",
"shasum": ""
},
"require": {
"php": ">=5.3.2"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0.x-dev"
}
},
"autoload": {
"psr-0": {
"Doctrine\\Common\\Lexer\\": "lib/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Roman Borschel",
"email": "roman@code-factory.org"
},
{
"name": "Guilherme Blanco",
"email": "guilhermeblanco@gmail.com"
},
{
"name": "Johannes Schmitt",
"email": "schmittjoh@gmail.com"
}
],
"description": "Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.",
"homepage": "http://www.doctrine-project.org",
"keywords": [
"lexer",
"parser"
],
"time": "2014-09-09T13:34:57+00:00"
},
{
"name": "enzyme/axiom",
"version": "v4.2.0",
@@ -624,6 +875,123 @@
],
"time": "2017-11-15T11:08:09+00:00"
},
{
"name": "goaop/framework",
"version": "2.2.0",
"source": {
"type": "git",
"url": "https://github.com/goaop/framework.git",
"reference": "152abbffffcba72d2d159b892deb40b0829d0f28"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/goaop/framework/zipball/152abbffffcba72d2d159b892deb40b0829d0f28",
"reference": "152abbffffcba72d2d159b892deb40b0829d0f28",
"shasum": ""
},
"require": {
"doctrine/annotations": "^1.2.3",
"doctrine/cache": "^1.5",
"goaop/parser-reflection": "~1.4",
"jakubledl/dissect": "~1.0",
"php": ">=5.6.0"
},
"require-dev": {
"adlawson/vfs": "^0.12",
"doctrine/orm": "^2.5",
"phpunit/phpunit": "^5.7",
"symfony/console": "^2.7|^3.0",
"symfony/filesystem": "^3.3",
"symfony/process": "^3.3"
},
"suggest": {
"symfony/console": "Enables the usage of the command-line tool."
},
"bin": [
"bin/aspect"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.0-dev"
}
},
"autoload": {
"psr-4": {
"Go\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Lisachenko Alexander",
"homepage": "https://github.com/lisachenko"
}
],
"description": "Framework for aspect-oriented programming in PHP.",
"homepage": "http://go.aopphp.com/",
"keywords": [
"aop",
"aspect",
"library",
"php"
],
"time": "2018-01-05T23:07:51+00:00"
},
{
"name": "goaop/parser-reflection",
"version": "1.4.1",
"source": {
"type": "git",
"url": "https://github.com/goaop/parser-reflection.git",
"reference": "d9c1dcc7ce4a5284fe3530e011faf9c9c10e1166"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/goaop/parser-reflection/zipball/d9c1dcc7ce4a5284fe3530e011faf9c9c10e1166",
"reference": "d9c1dcc7ce4a5284fe3530e011faf9c9c10e1166",
"shasum": ""
},
"require": {
"nikic/php-parser": "^1.2|^2.0|^3.0",
"php": ">=5.6.0"
},
"require-dev": {
"phpunit/phpunit": "~4.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.x-dev"
}
},
"autoload": {
"psr-4": {
"Go\\ParserReflection\\": "src"
},
"files": [
"src/bootstrap.php"
],
"exclude-from-classmap": [
"/tests/"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Alexander Lisachenko",
"email": "lisachenko.it@gmail.com"
}
],
"description": "Provides reflection information, based on raw source",
"time": "2018-03-19T15:57:41+00:00"
},
{
"name": "guzzlehttp/guzzle",
"version": "6.3.3",
@@ -1105,6 +1473,61 @@
"homepage": "https://laravel.com",
"time": "2018-04-17T12:26:47+00:00"
},
{
"name": "jakubledl/dissect",
"version": "v1.0.1",
"source": {
"type": "git",
"url": "https://github.com/jakubledl/dissect.git",
"reference": "d3a391de31e45a247e95cef6cf58a91c05af67c4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/jakubledl/dissect/zipball/d3a391de31e45a247e95cef6cf58a91c05af67c4",
"reference": "d3a391de31e45a247e95cef6cf58a91c05af67c4",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"require-dev": {
"symfony/console": "~2.1"
},
"suggest": {
"symfony/console": "for the command-line tool"
},
"bin": [
"bin/dissect.php",
"bin/dissect"
],
"type": "library",
"autoload": {
"psr-0": {
"Dissect": [
"src/"
]
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"unlicense"
],
"authors": [
{
"name": "Jakub Lédl",
"email": "jakubledl@gmail.com"
}
],
"description": "Lexing and parsing in pure PHP",
"homepage": "https://github.com/jakubledl/dissect",
"keywords": [
"ast",
"lexing",
"parser",
"parsing"
],
"time": "2013-01-29T21:29:14+00:00"
},
{
"name": "league/pipeline",
"version": "0.3.0",
@@ -1245,6 +1668,57 @@
],
"time": "2018-04-23T09:02:57+00:00"
},
{
"name": "nikic/php-parser",
"version": "v3.1.5",
"source": {
"type": "git",
"url": "https://github.com/nikic/PHP-Parser.git",
"reference": "bb87e28e7d7b8d9a7fda231d37457c9210faf6ce"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/bb87e28e7d7b8d9a7fda231d37457c9210faf6ce",
"reference": "bb87e28e7d7b8d9a7fda231d37457c9210faf6ce",
"shasum": ""
},
"require": {
"ext-tokenizer": "*",
"php": ">=5.5"
},
"require-dev": {
"phpunit/phpunit": "~4.0|~5.0"
},
"bin": [
"bin/php-parse"
],
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.0-dev"
}
},
"autoload": {
"psr-4": {
"PhpParser\\": "lib/PhpParser"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"BSD-3-Clause"
],
"authors": [
{
"name": "Nikita Popov"
}
],
"description": "A PHP parser written in PHP",
"keywords": [
"parser",
"php"
],
"time": "2018-02-28T20:30:58+00:00"
},
{
"name": "pdepend/pdepend",
"version": "2.5.2",
@@ -1387,6 +1861,46 @@
"description": "Library for handling version information and constraints",
"time": "2017-03-05T17:38:23+00:00"
},
{
"name": "php-deal/framework",
"version": "0.4.1",
"source": {
"type": "git",
"url": "https://github.com/php-deal/framework.git",
"reference": "a1e3bd96f8b02ddfac9126e95a79cfc8ee6d8b22"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/php-deal/framework/zipball/a1e3bd96f8b02ddfac9126e95a79cfc8ee6d8b22",
"reference": "a1e3bd96f8b02ddfac9126e95a79cfc8ee6d8b22",
"shasum": ""
},
"require": {
"beberlei/assert": "^2.4",
"goaop/framework": "~1.0|~2.0@dev"
},
"require-dev": {
"symfony/console": "~2.7|~3.0"
},
"type": "library",
"autoload": {
"psr-4": {
"PhpDeal\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Alexander Lisachenko",
"email": "lisachenko.it@gmail.com"
}
],
"description": "Design by Contract framework for PHP",
"time": "2016-04-03T17:59:11+00:00"
},
{
"name": "phpdocumentor/reflection-common",
"version": "1.0.1",

View File

@@ -77,6 +77,26 @@ class Setting
*/
protected $music = [];
/**
* Setting constructor.
* @param array|null $params
*/
public function __construct(array $params = [])
{
foreach ($params as $attribute => $value) {
$this->set($attribute, $value);
}
}
/**
* @param array $attributes
* @return \XaiCorp\AbcParser\Domain\Core\Setting
*/
public static function create(array $attributes)
{
return new static($attributes);
}
/**
* @return \XaiCorp\AbcParser\Domain\Core\Transcriber[]
*/
@@ -310,4 +330,25 @@ class Setting
$this->music[] = $music;
return $this;
}
/**
* @param $attribute
* @param $value
*/
private function set($attribute, $value)
{
switch ($attribute) {
default:
$this->append($attribute, $value);
}
}
protected function append($attribute, MultivalueAttribute $values)
{
$method = 'add' . substr($attribute, 0, -1);
foreach ($values->toArray() as $value) {
call_user_func([$this, $method], $value);
}
}
}

View File

@@ -283,6 +283,16 @@ class Tune implements EntityInterface
call_user_func([$this, 'addAuthor'], $value);
break;
case 'Composers':
$this->addComposer($value);
break;
case 'settings':
foreach ($value as $key => $settingParams) {
$this->addSetting(Setting::create($settingParams));
}
break;
default:
$this->append($attribute, $value);
}
@@ -333,6 +343,7 @@ class Tune implements EntityInterface
/**
* @param StringAtom $musicLine
* @return $this
* @deprecated this should be on the setting
*/
public function addMusicLine(string $musicLine)
{
@@ -350,6 +361,10 @@ class Tune implements EntityInterface
{
//TODO
$this->titles = array_merge($this->getTitles(), $source->getTitles());
$this->authors = array_merge($this->getAuthors(), $source->getAuthors());
$this->composers = array_merge($this->getComposers(), $source->getComposers());
$this->history = array_merge($this->getHistory(), $source->getHistory());
$this->tuneSettings = array_merge($this->getSettings(), $source->getSettings());
return $this;
}
}

View File

@@ -10,11 +10,17 @@ class TuneAttributeArrayBuilder implements TuneBuilder
{
protected $attributes = [];
protected $settingIndex = 0;
public static function create()
{
return new self();
}
/**
* @param \Webpatser\Uuid\Uuid|null $identity
* @return \XaiCorp\AbcParser\Domain\Core\Tune
*/
public function getTune(Uuid $identity = null): \XaiCorp\AbcParser\Domain\Core\Tune
{
return new Tune($this->attributes, $identity);
@@ -25,7 +31,8 @@ class TuneAttributeArrayBuilder implements TuneBuilder
*/
public function handleEndOfMusic()
{
// TODO: Implement handleEndOfMusic() method.
$this->settingIndex++;
return $this;
}
/**
@@ -40,18 +47,18 @@ class TuneAttributeArrayBuilder implements TuneBuilder
}
/**
* @param \Enzyme\Axiom\Atoms\StringAtom $param
* @param string $param
* @return $this
*/
public function appendMusic(StringAtom $param): \XaiCorp\AbcParser\Domain\Core\TuneBuilder
public function appendMusic(string $param): \XaiCorp\AbcParser\Domain\Core\TuneBuilder
{
$index = 'MusicLines';
$item = $param->getValue();
$item = $param;
if (!isset($this->attributes[$index])) {
$this->attributes[$index] = MultivalueAttribute::create($item);
if (!isset($this->attributes['settings'][$this->settingIndex][$index])) {
$this->attributes['settings'][$this->settingIndex][$index] = MultivalueAttribute::create($item);
} else {
$this->attributes[$index]->add($item);
$this->attributes['settings'][$this->settingIndex][$index]->add($item);
}
return $this;
@@ -95,9 +102,18 @@ class TuneAttributeArrayBuilder implements TuneBuilder
return $this;
}
public function addComposer(StringAtom $composerName)
public function addComposer(string $name): \XaiCorp\AbcParser\Domain\Core\TuneBuilder
{
// TODO: Implement addComposer() method.
$index = 'Composers';
$item = Composer::create($name, new EmailAtom(''));
if (!isset($this->attributes[$index])) {
$this->attributes[$index] = $item;
} else {
$this->attributes[$index]->add($item);
}
return $this;
}
public function addTranscriber(StringAtom $transcriberName)
@@ -130,9 +146,18 @@ class TuneAttributeArrayBuilder implements TuneBuilder
// TODO: Implement addFilename() method.
}
public function addHistory(StringAtom $history)
public function addHistory(string $history): \XaiCorp\AbcParser\Domain\Core\TuneBuilder
{
// TODO: Implement addHistory() method.
$index = 'HistoryLines';
$item = MultivalueAttribute::create($history);
if (!isset($this->attributes[$index])) {
$this->attributes[$index] = $item;
} else {
$this->attributes[$index]->add($item);
}
return $this;
}
public function addRhythm(StringAtom $rhythm)

View File

@@ -27,7 +27,7 @@ interface TuneBuilder
*/
public function setIndex(UnsignedIntegerAtom $param): \XaiCorp\AbcParser\Domain\Core\TuneBuilder;
public function appendMusic(StringAtom $param): \XaiCorp\AbcParser\Domain\Core\TuneBuilder;
public function appendMusic(string $param): \XaiCorp\AbcParser\Domain\Core\TuneBuilder;
public function addTitle(string $title): \XaiCorp\AbcParser\Domain\Core\TuneBuilder;
@@ -37,7 +37,7 @@ interface TuneBuilder
public function addAuthor(string $name): \XaiCorp\AbcParser\Domain\Core\TuneBuilder;
public function addComposer(StringAtom $composerName);
public function addComposer(string $name): \XaiCorp\AbcParser\Domain\Core\TuneBuilder;
public function addTranscriber(StringAtom $transcriberName);
@@ -51,7 +51,7 @@ interface TuneBuilder
public function addFilename(StringAtom $filename);
public function addHistory(StringAtom $history);
public function addHistory(string $history): \XaiCorp\AbcParser\Domain\Core\TuneBuilder;
public function addRhythm(StringAtom $rhythm);

View File

@@ -94,9 +94,9 @@ class Builder implements TuneBuilder
return $this;
}
public function appendMusic(StringAtom $param): \XaiCorp\AbcParser\Domain\Core\TuneBuilder
public function appendMusic(string $param): \XaiCorp\AbcParser\Domain\Core\TuneBuilder
{
$this->setting->addMusicLine($param->getValue());
$this->setting->addMusicLine($param);
return $this;
}
@@ -130,9 +130,9 @@ class Builder implements TuneBuilder
return $this;
}
public function addComposer(StringAtom $composerName)
public function addComposer(string $name): \XaiCorp\AbcParser\Domain\Core\TuneBuilder
{
$composer = new Composer($composerName, new EmailAtom(''));
$composer = Composer::create($name, new EmailAtom(''));
$this->tune->addComposer($composer);
return $this;
@@ -173,9 +173,11 @@ class Builder implements TuneBuilder
$this->setting->addFilename($filename->getValue());
}
public function addHistory(StringAtom $history)
public function addHistory(string $history): \XaiCorp\AbcParser\Domain\Core\TuneBuilder
{
$this->tune->addHistoryLine($history->getValue());
$this->tune->addHistoryLine($history);
return $this;
}
public function addRhythm(StringAtom $rhythm)

View File

@@ -33,7 +33,7 @@ class Composer implements Lex
list($key, $data) = $this->getKeyDataFromLine($line);
if ($key === 'C') {
$this->builder->addComposer(new StringAtom($data));
$this->builder->addComposer($data);
}
return $next($context);

View File

@@ -36,10 +36,10 @@ class History implements Lex
if ($key === 'H'
&& $context->isState($context::MODE_TUNE_HEADER)
) {
$this->builder->addHistory(new StringAtom($data));
$this->builder->addHistory($data);
$context->setStateInHistory();
} elseif ($context->isState($context::MODE_HISTORY)) {
$this->builder->addHistory(new StringAtom($line));
$this->builder->addHistory($line);
if ($this->nextLineNotHistory($context)) {
$context->setStateInTuneHeader();

View File

@@ -36,7 +36,7 @@ class MusicLine implements Lex
&& $key !== 'K'
&& $line !== ''
) {
$this->builder->appendMusic(new StringAtom($line));
$this->builder->appendMusic($line);
}
return $next($context);

View File

@@ -26,12 +26,14 @@ class TuneAttributeArrayBuilderTest extends \Codeception\Test\Unit
public function testAppendMusic()
{
$music = new \Enzyme\Axiom\Atoms\StringAtom('Abcd|');
$music = 'Abcd|';
$builder = new TuneAttributeArrayBuilder();
$tune = $builder->appendMusic($music)->getTune();
$this->assertInstanceOf(Tune::class, $tune);
$this->assertEquals($music->getValue(), trim($tune->getMusic()));
$settings = $tune->getSettings();
$this->assertEquals($music, trim($settings[0]->getMusic()));
}
}

View File

@@ -188,19 +188,31 @@ class TuneTest extends \PHPUnit_Framework_TestCase
{
$targetTune = TuneAttributeArrayBuilder::create()
->addTitle('target')
->appendMusic('|:BAG BAG|')
->getTune();
$sourceTune = TuneAttributeArrayBuilder::create()
->addTitle('source')
->appendMusic('|:GAB GAB|')
->addAuthor('a.non')
->addComposer('composer')
->addHistory('some story')
->getTune();
$expected = TuneAttributeArrayBuilder::create()
->addTitle('target')
->addTitle('source')
->appendMusic('|:BAG BAG|')
->handleEndOfMusic()
->appendMusic('|:GAB GAB|')
->addAuthor('a.non')
->addComposer('composer')
->addHistory('some story')
->getTune($targetTune->identity());
$result = $targetTune->merge($sourceTune);
$this->assertEquals($expected, $result);
}
}