Skip to content

Commit

Permalink
Merge pull request #8 from kyoden/tcx-namespace
Browse files Browse the repository at this point in the history
TCX detects namespace
  • Loading branch information
Conn Warwicker authored Jul 9, 2019
2 parents 48b2a9e + 06191f4 commit 5b93759
Show file tree
Hide file tree
Showing 3 changed files with 2,829 additions and 25 deletions.
30 changes: 27 additions & 3 deletions src/Parsers/TCXParser.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,13 @@

class TCXParser extends Parser
{
const NS_ACTIVITY_EXTENSION_V2 = 'http://www.garmin.com/xmlschemas/ActivityExtension/v2';

/**
* @var string
*/
private $nameNSActivityExtensionV2;

/**
* Parse the TCX file
* @param type $file
Expand All @@ -30,6 +36,7 @@ public function parse($file)
if (!isset($data->Activities->Activity)){
throw new \Exception("Unable to find valid activity in file contents");
}
$this->detectsNamespace($data);

// Parse the first activity
$activityNode = $data->Activities->Activity[0];
Expand All @@ -48,6 +55,22 @@ public function parse($file)


}

/**
*
* @var \SimpleXMLElement $xml
*/
private function detectsNamespace(\SimpleXMLElement $xml)
{
$this->nameNSActivityExtensionV2 = null;

$namespaces = $xml->getNamespaces(true);
foreach($namespaces as $name => $ns) {
if ($ns === self::NS_ACTIVITY_EXTENSION_V2) {
$this->nameNSActivityExtensionV2 = $name;
}
}
}

/**
* Parse the lap XML
Expand Down Expand Up @@ -87,9 +110,10 @@ protected function parseTrackPoint($trackPointNode)
$point->setAltitude( (float)$trackPointNode->AltitudeMeters );
$point->setDistance( (float)$trackPointNode->DistanceMeters );

if (isset($trackPointNode->Extensions->children('x', true)->TPX->children()->Speed))
{
$point->setSpeed( (float)$trackPointNode->Extensions->children('x', true)->TPX->children()->Speed );
if ($this->nameNSActivityExtensionV2) {
if (isset($trackPointNode->Extensions->children('x', true)->TPX->children()->Speed)) {
$point->setSpeed( (float)$trackPointNode->Extensions->children('x', true)->TPX->children()->Speed );
}
}

return $point;
Expand Down
71 changes: 49 additions & 22 deletions tests/Parsers/TCXParserTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,75 +4,102 @@

class TXCParserTest extends \PHPUnit\Framework\TestCase
{

public $parser, $activity;
public $parser;

public function setUp() {
$this->parser = new \Waddle\Parsers\TCXParser();
$this->activity = $this->parser->parse( __DIR__ . '/../run.tcx' );
}

// Not sure how to test this, as if run on a system with different timezone/daylight saving, will be different
// public function testActivityStartTime(){
// $this->assertEquals('2017-05-27 09:13:01', $this->activity->getStartTime('Y-m-d H:i:s'));
// }

public function testDetectsNamespace() {
$reflector = new \ReflectionClass($this->parser );
$method = $reflector->getMethod('detectsNamespace');
$method->setAccessible(true);
$method->invokeArgs($this->parser, [simplexml_load_file(__DIR__ . '/../run_garmin.tcx')]);

$reflector = new \ReflectionClass($this->parser);
$property = $reflector->getProperty('nameNSActivityExtensionV2');
$property->setAccessible(true);

$this->assertEquals('ns3', $property->getValue($this->parser));
}

public function testDetectsNamespaceSeveralParse() {
$reflector = new \ReflectionClass($this->parser );
$method = $reflector->getMethod('detectsNamespace');
$method->setAccessible(true);

$reflector = new \ReflectionClass($this->parser);
$property = $reflector->getProperty('nameNSActivityExtensionV2');

$method->invokeArgs($this->parser, [simplexml_load_file(__DIR__ . '/../run_garmin.tcx')]);
$property->setAccessible(true);
$this->assertEquals('ns3', $property->getValue($this->parser));

$method->invokeArgs($this->parser, [simplexml_load_file(__DIR__ . '/../run.tcx')]);
$property->setAccessible(true);
$this->assertEquals('x', $property->getValue($this->parser));
}

private function getActivity() {
return $this->parser->parse( __DIR__ . '/../run.tcx' );
}

public function testActivityLaps(){
$this->assertEquals(1, count($this->activity->getLaps()));
$this->assertEquals(1, count($this->getActivity()->getLaps()));
}

public function testActivityTotalDistance(){
$this->assertEquals(4824.94, $this->activity->getTotalDistance());
$this->assertEquals(4824.94, $this->getActivity()->getTotalDistance());
}

public function testActivityTotalDuration(){
$this->assertEquals(1424, $this->activity->getTotalDuration());
$this->assertEquals(1424, $this->getActivity()->getTotalDuration());
}

public function testActivityAveragePacePerMile(){
$this->assertEquals('00:07:54', $this->activity->getAveragePacePerMile());
$this->assertEquals('00:07:54', $this->getActivity()->getAveragePacePerMile());
}

public function testActivityAveragePacePerKilometre(){
$this->assertEquals('00:04:55', $this->activity->getAveragePacePerKilometre());
$this->assertEquals('00:04:55', $this->getActivity()->getAveragePacePerKilometre());
}

public function testActivityAverageSpeedMPH(){
$this->assertEquals('7.58', round($this->activity->getAverageSpeedInMPH(), 2));
$this->assertEquals('7.58', round($this->getActivity()->getAverageSpeedInMPH(), 2));
}

public function testActivityAverageSpeedKPH(){
$this->assertEquals('12.20', round($this->activity->getAverageSpeedInKPH(), 2));
$this->assertEquals('12.20', round($this->getActivity()->getAverageSpeedInKPH(), 2));
}

public function testActivityTotalCalories(){
$this->assertEquals(372, $this->activity->getTotalCalories());
$this->assertEquals(372, $this->getActivity()->getTotalCalories());
}

public function testActivityMaxSpeedMPH(){
$this->assertEquals('10.45', round($this->activity->getMaxSpeedInMPH(), 2));
$this->assertEquals('10.45', round($this->getActivity()->getMaxSpeedInMPH(), 2));
}

public function testActivityMaxSpeedKPH(){
$this->assertEquals('16.81', round($this->activity->getMaxSpeedInKPH(), 2));
$this->assertEquals('16.81', round($this->getActivity()->getMaxSpeedInKPH(), 2));
}

public function testActivityTotalAscent(){
$result = $this->activity->getTotalAscentDescent();
$result = $this->getActivity()->getTotalAscentDescent();
$this->assertEquals(50.9, $result['ascent']);
}

public function testActivityTotalDescent(){
$result = $this->activity->getTotalAscentDescent();
$result = $this->getActivity()->getTotalAscentDescent();
$this->assertEquals(50.2, $result['descent']);
}

public function testActivitySplitsInMiles(){
$this->assertEquals(3, count($this->activity->getSplits('mi')));
$this->assertEquals(3, count($this->getActivity()->getSplits('mi')));
}

public function testActivitySplitsInKilometres(){
$this->assertEquals(5, count($this->activity->getSplits('k')));
$this->assertEquals(5, count($this->getActivity()->getSplits('k')));
}

}
Loading

0 comments on commit 5b93759

Please sign in to comment.