Changeset b73ae09 in OpenWorkouts-current


Ignore:
Timestamp:
Jan 9, 2019, 12:54:27 PM (5 years ago)
Author:
borja <borja@…>
Branches:
current, feature/docs, master
Children:
c555386
Parents:
119412d
Message:

Added missing tests covering ow.fit, ow.models.workout and ow.utilities

Location:
ow
Files:
5 added
3 edited

Legend:

Unmodified
Added
Removed
  • ow/fit.py

    r119412d rb73ae09  
    33import gpxpy.gpx
    44
    5 try:
     5try:  # pragma: no cover
    66    import lxml.etree as mod_etree  # Load LXML or fallback to cET or ET
    7 except:
     7except ImportError:  # pragma: no cover
    88    try:
    99        import xml.etree.cElementTree as mod_etree
    10     except:
     10    except ImportError:
    1111        import xml.etree.ElementTree as mod_etree
    1212
  • ow/tests/models/test_workout.py

    r119412d rb73ae09  
    1111from ow.models.user import User
    1212from ow.models.root import OpenWorkouts
     13from ow.utilities import create_blob
    1314
    1415
     
    121122        assert workout.duration_seconds == '15'
    122123
     124    def test__duration(self):
     125        # covering the property that shows the duration of a workout properly
     126        # formatted in hours:minutes:seconds
     127        duration = timedelta(hours=1, minutes=30, seconds=15)
     128        workout = Workout(duration=duration)
     129        assert workout._duration == '01:30:15'
     130
    123131    def test_rounded_distance_no_value(self):
    124132        workout = Workout()
     
    209217        assert workout.tracking_file_path == '/var/db/blobs/blobfile'
    210218
     219    def test_fit_file_path(self):
     220        workout = Workout()
     221        # no tracking file, path is None
     222        assert workout.fit_file_path is None
     223        # workout still not saved to the db
     224        workout.fit_file = Mock()
     225        workout.fit_file._p_blob_uncommitted = '/tmp/blobtempfile'
     226        workout.fit_file._p_blob_committed = None
     227        assert workout.fit_file_path == '/tmp/blobtempfile'
     228        workout.fit_file._p_blob_uncommitted = None
     229        workout.fit_file._p_blob_committed = '/var/db/blobs/blobfile'
     230        assert workout.fit_file_path == '/var/db/blobs/blobfile'
     231
    211232    def test_load_from_file_invalid(self):
    212233        workout = Workout()
     
    222243            workout.load_from_file()
    223244            assert lfg.called
     245
     246    def test_load_from_file_fit(self):
     247        workout = Workout()
     248        workout.tracking_filetype = 'fit'
     249        with patch.object(workout, 'load_from_fit') as lff:
     250            workout.load_from_file()
     251            assert lff.called
    224252
    225253    gpx_params = (
     
    372400        assert res == {}
    373401
     402    fit_params = (
     403        # complete fit file from a garmin 520 device
     404        ('fixtures/20181230_101115.fit', {
     405            'start': datetime(2018, 12, 30, 9, 11, 15, tzinfo=timezone.utc),
     406            'duration': timedelta(0, 13872, 45000),
     407            'distance': Decimal('103.4981999999999970896169543'),
     408            'title': 'Synapse cycling',
     409            'hr': {'min': 93, 'max': 170, 'avg': 144},
     410            'cad': {'min': 0, 'max': 121, 'avg': 87},
     411            'atemp': {'min': -4, 'max': 15, 'avg': 2},
     412            'gpx_file': 'fixtures/20181230_101115.gpx'}),
     413        # fit file from a garmin 520 without heart rate or cadence data
     414        ('fixtures/20181231_110728.fit', {
     415            'start': datetime(2018, 12, 31, 10, 7, 28, tzinfo=timezone.utc),
     416            'duration': timedelta(0, 2373, 142000),
     417            'distance': Decimal('6.094909999999999854480847716'),
     418            'title': 'Synapse cycling',
     419            'hr': None,
     420            'cad': None,
     421            'atemp': {'min': -1, 'max': 11, 'avg': 1},
     422            'gpx_file': 'fixtures/20181231_110728.gpx'}),
     423    )
     424
     425    @pytest.mark.parametrize(('filename', 'expected'), fit_params)
     426    def test_load_from_fit(self, filename, expected):
     427        """
     428        Load a fit file located in tests/fixtures using the load_from_fit()
     429        method of the Workout model, then check that certain attrs on the
     430        workout are updated correctly.
     431
     432        Ensure also that the proper gpx file is created automatically from
     433        the fit file, with the proper contents (we have a matching gpx file
     434        in tests/fixtures for each fit file)
     435        """
     436        # expected values
     437        start = expected['start']
     438        duration = expected['duration']
     439        distance = expected['distance']
     440        title = expected['title']
     441        hr = expected['hr']
     442        cad = expected['cad']
     443        atemp = expected['atemp']
     444        # gpx_file = expected['gpx_file']
     445
     446        workout = Workout()
     447
     448        # Check the values are different by default
     449        assert workout.start != start
     450        assert workout.duration != duration
     451        assert workout.distance != distance
     452
     453        # by default no tracking file and no fit file are associated with this
     454        # workout.
     455        assert workout.tracking_file is None
     456        assert workout.fit_file is None
     457        assert not workout.has_tracking_file
     458        assert not workout.has_gpx
     459        assert not workout.has_fit
     460
     461        fit_file_path = os.path.join(
     462            os.path.dirname(os.path.dirname(__file__)), filename)
     463
     464        # gpx_file_path = os.path.join(
     465        #     os.path.dirname(os.path.dirname(__file__)), gpx_file)
     466
     467        # add the fit file as a blob to tracking_file
     468        with open(fit_file_path, 'rb') as fit_file:
     469            fit_blob = create_blob(fit_file.read(), file_extension='fit',
     470                                   binary=True)
     471        workout.tracking_file = fit_blob
     472        workout.tracking_filetype = 'fit'
     473
     474        res = workout.load_from_fit()
     475
     476        assert res is True
     477        assert workout.start == start
     478        assert workout.duration == duration
     479        assert isinstance(workout.distance, Decimal)
     480        assert round(workout.distance) == round(distance)
     481        # The title of the workout is taken from the gpx file
     482        assert workout.title == title
     483
     484        if hr is not None:
     485            for k in hr.keys():
     486                # We use 'fail' as the fallback in the getattr call
     487                # because None is one of the posible values, and we
     488                # want to be sure those attrs are there
     489                value = getattr(workout, 'hr_' + k, 'fail')
     490                # Use round() to avoid problems when comparing long
     491                # Decimal objects
     492                assert round(hr[k]) == round(value)
     493
     494        if cad is not None:
     495            for k in cad.keys():
     496                value = getattr(workout, 'cad_' + k, 'fail')
     497                assert round(cad[k]) == round(value)
     498
     499        if atemp is not None:
     500            for k in atemp.keys():
     501                value = getattr(workout, 'atemp_' + k, 'fail')
     502                assert round(atemp[k]) == round(value)
     503
     504        assert workout.tracking_file is not None
     505        # the tracking file type is set back to gpx, as we have
     506        # automatically generated the gpx version
     507        assert workout.tracking_filetype == 'gpx'
     508        assert workout.fit_file is not None
     509        assert workout.has_tracking_file
     510        assert workout.has_gpx
     511        assert workout.has_fit
     512
    374513    def test_has_tracking_file(self, root):
    375514        workout = root['john']['1']
  • ow/tests/test_utilities.py

    r119412d rb73ae09  
    55import pytest
    66
    7 from ow.utilities import slugify, GPXMinidomParser
     7from ow.utilities import (
     8    slugify,
     9    GPXMinidomParser,
     10    semicircles_to_degrees,
     11    degrees_to_semicircles,
     12    miles_to_kms,
     13    kms_to_miles,
     14    meters_to_kms,
     15    kms_to_meters,
     16    mps_to_kmph,
     17    kmph_to_mps,
     18)
    819
    920
     
    1930        res = slugify(u'(r)-[i]\u00AE')
    2031        assert res == u'r-i-r'
     32
     33    def test_semicircles_to_degrees(self):
     34        assert semicircles_to_degrees(10) == 10 * (180 / pow(2, 31))
     35
     36    def test_degrees_to_semicircles(self):
     37        assert degrees_to_semicircles(10) == 10 * (pow(2, 31) / 180)
     38
     39    def test_miles_to_kms(self):
     40        assert miles_to_kms(100) == 100 / 0.62137119
     41
     42    def test_kms_to_miles(self):
     43        assert kms_to_miles(100) == 100 * 0.62137119
     44
     45    def test_meters_to_kms(self):
     46        assert meters_to_kms(1000) == 1
     47
     48    def test_kms_to_meters(self):
     49        assert kms_to_meters(1) == 1000
     50
     51    def test_mps_to_kmph(self):
     52        assert mps_to_kmph(5) == 5 * 3.6
     53
     54    def test_kmph_to_mps(self):
     55        assert kmph_to_mps(30) == 30 * 0.277778
    2156
    2257
Note: See TracChangeset for help on using the changeset viewer.