Skip to content

Test Tools > Collectors

TestCollectYearsList

Source code in tests/tools/test_collectors.py
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
class TestCollectYearsList:
    def test_empty_list(self):
        """Test the behavior of collect_years_list when provided with an
        empty list.

        An empty list should trigger a ValueError to indicate that valid years
        are required for processing.

        Raises
        ------
        ValueError
            If the provided list is empty.
        """
        empty_list = []  # type: ignore
        with pytest.raises(ValueError) as excinfo:
            collect_years_list(empty_list)
        assert (
            f"The list is empty. Provide a list with years after {first_year} and before {last_year}."  # noqa
            in str(excinfo.value)
        )

    def test_all_valid_years(
        self,
        list_with_valid_years,
    ):
        """Test collect_years_list with a list containing only valid years.

        The function should return the same list of years if all are valid
        within the accepted range.

        Parameters
        ----------
        list_with_valid_years : list
            A list of years that are all valid and within the collection range.
        """
        result_list = collect_years_list(list_with_valid_years)

        assert result_list == [2000, 2010, 2023]

    def test_all_invalid_years(
        self,
        list_with_invalid_int_years,
        list_with_invalid_str_years,
    ):
        """Test collect_years_list with lists that contain only invalid years.

        The function is expected to raise a ValueError indicating that no
        valid years were provided.

        Parameters
        ----------
        list_with_invalid_int_years : list
            A list of integers representing years, all of which are invalid.
        list_with_invalid_str_years : list
            A list of strings, none of which are valid representations of
            years.

        Raises
        ------
        ValueError
            If the list does not contain any valid years.
        """
        with pytest.raises(ValueError) as excinfo:
            collect_years_list(list_with_invalid_int_years)
        assert (
            f"The list is empty. Provide a list with years after {first_year} and before {last_year}."  # noqa
            in str(excinfo.value)
        )

        with pytest.raises(ValueError) as excinfo:
            collect_years_list(list_with_invalid_str_years)
        assert (
            f"The list is empty. Provide a list with years after {first_year} and before {last_year}."  # noqa
            in str(excinfo.value)
        )

    def test_mixed_list(
        self,
        list_with_mix_int_years,
        list_with_mix_int_str_years,
        capsys,
    ):
        """Test collect_years_list with lists that contain a mixture of valid
        and invalid years or strings.

        Valid years should be returned and invalid ones should be reported via
        standard output.

        Parameters
        ----------
        list_with_mix_int_years : list
            A list containing a mix of valid and invalid integer years.
        list_with_mix_int_str_years : list
            A list containing both valid integer years and invalid string
            years.
        capsys : fixture
            Pytest fixture that captures standard output and error streams.
        """
        result_with_int = collect_years_list(list_with_mix_int_years)

        assert result_with_int == [2010, 2023]

        assert (
            capsys.readouterr().out
            == "The elements [1999] were removed from the list.\n"
        )

        result_with_str = collect_years_list(list_with_mix_int_str_years)

        assert result_with_str == [2010, 2023]

        assert (
            capsys.readouterr().out
            == "The elements ['A'] were removed from the list.\n"
        )

test_all_invalid_years(list_with_invalid_int_years, list_with_invalid_str_years)

Test collect_years_list with lists that contain only invalid years.

The function is expected to raise a ValueError indicating that no valid years were provided.

Parameters

list_with_invalid_int_years : list A list of integers representing years, all of which are invalid. list_with_invalid_str_years : list A list of strings, none of which are valid representations of years.

Raises

ValueError If the list does not contain any valid years.

Source code in tests/tools/test_collectors.py
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
def test_all_invalid_years(
    self,
    list_with_invalid_int_years,
    list_with_invalid_str_years,
):
    """Test collect_years_list with lists that contain only invalid years.

    The function is expected to raise a ValueError indicating that no
    valid years were provided.

    Parameters
    ----------
    list_with_invalid_int_years : list
        A list of integers representing years, all of which are invalid.
    list_with_invalid_str_years : list
        A list of strings, none of which are valid representations of
        years.

    Raises
    ------
    ValueError
        If the list does not contain any valid years.
    """
    with pytest.raises(ValueError) as excinfo:
        collect_years_list(list_with_invalid_int_years)
    assert (
        f"The list is empty. Provide a list with years after {first_year} and before {last_year}."  # noqa
        in str(excinfo.value)
    )

    with pytest.raises(ValueError) as excinfo:
        collect_years_list(list_with_invalid_str_years)
    assert (
        f"The list is empty. Provide a list with years after {first_year} and before {last_year}."  # noqa
        in str(excinfo.value)
    )

test_all_valid_years(list_with_valid_years)

Test collect_years_list with a list containing only valid years.

The function should return the same list of years if all are valid within the accepted range.

Parameters

list_with_valid_years : list A list of years that are all valid and within the collection range.

Source code in tests/tools/test_collectors.py
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
def test_all_valid_years(
    self,
    list_with_valid_years,
):
    """Test collect_years_list with a list containing only valid years.

    The function should return the same list of years if all are valid
    within the accepted range.

    Parameters
    ----------
    list_with_valid_years : list
        A list of years that are all valid and within the collection range.
    """
    result_list = collect_years_list(list_with_valid_years)

    assert result_list == [2000, 2010, 2023]

test_empty_list()

Test the behavior of collect_years_list when provided with an empty list.

An empty list should trigger a ValueError to indicate that valid years are required for processing.

Raises

ValueError If the provided list is empty.

Source code in tests/tools/test_collectors.py
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
def test_empty_list(self):
    """Test the behavior of collect_years_list when provided with an
    empty list.

    An empty list should trigger a ValueError to indicate that valid years
    are required for processing.

    Raises
    ------
    ValueError
        If the provided list is empty.
    """
    empty_list = []  # type: ignore
    with pytest.raises(ValueError) as excinfo:
        collect_years_list(empty_list)
    assert (
        f"The list is empty. Provide a list with years after {first_year} and before {last_year}."  # noqa
        in str(excinfo.value)
    )

test_mixed_list(list_with_mix_int_years, list_with_mix_int_str_years, capsys)

Test collect_years_list with lists that contain a mixture of valid and invalid years or strings.

Valid years should be returned and invalid ones should be reported via standard output.

Parameters

list_with_mix_int_years : list A list containing a mix of valid and invalid integer years. list_with_mix_int_str_years : list A list containing both valid integer years and invalid string years. capsys : fixture Pytest fixture that captures standard output and error streams.

Source code in tests/tools/test_collectors.py
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
def test_mixed_list(
    self,
    list_with_mix_int_years,
    list_with_mix_int_str_years,
    capsys,
):
    """Test collect_years_list with lists that contain a mixture of valid
    and invalid years or strings.

    Valid years should be returned and invalid ones should be reported via
    standard output.

    Parameters
    ----------
    list_with_mix_int_years : list
        A list containing a mix of valid and invalid integer years.
    list_with_mix_int_str_years : list
        A list containing both valid integer years and invalid string
        years.
    capsys : fixture
        Pytest fixture that captures standard output and error streams.
    """
    result_with_int = collect_years_list(list_with_mix_int_years)

    assert result_with_int == [2010, 2023]

    assert (
        capsys.readouterr().out
        == "The elements [1999] were removed from the list.\n"
    )

    result_with_str = collect_years_list(list_with_mix_int_str_years)

    assert result_with_str == [2010, 2023]

    assert (
        capsys.readouterr().out
        == "The elements ['A'] were removed from the list.\n"
    )

TestStationDataCollector

Source code in tests/tools/test_collectors.py
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
class TestStationDataCollector:
    def test_collecting_empty_folder(
        self,
        tmp_path_factory,
    ):
        """Ensure StationDataCollector raises an error when scanning an empty
        folder.

        Parameters
        ----------
        tmp_path_factory : fixture
            Pytest fixture that provides a factory for temporary directories.

        Asserts
        ------
        ValueError
            Expected error when the collector encounters an empty folder.
        """
        stage_empty = tmp_path_factory.mktemp("stage_empty")
        output_empty = tmp_path_factory.mktemp("output_empty")

        stations_data = StationDataCollector(
            stage_empty,
            output_empty,
            STATIONS_FILE,
            STATION_COLUMN_NAMES,
            StationData,
        )

        output_file = STATIONS_FILE + ".parquet"

        output_empty_file_path = output_empty / output_file

        with pytest.raises(ValueError) as excinfo:
            stations_data.start()
        assert "No CSV files found in the specified folder." in str(
            excinfo.value,
        )
        assert not os.path.exists(output_empty_file_path)

    def test_collecting_valid_data(
        self,
        tmp_station_valid_data,
    ):
        """Ensure StationDataCollector does not create a log file when
        processing valid data.

        Parameters
        ----------
        tmp_station_valid_data : fixture
            Fixture providing a directory with valid CSV data.

        Asserts
        ------
        bool
            No log file is created and an output file exists.
        """
        stage_valid, output_valid = tmp_station_valid_data

        stations_data = StationDataCollector(
            stage_valid,
            output_valid,
            STATIONS_FILE,
            STATION_COLUMN_NAMES,
            StationData,
        )

        stations_data.start()

        log_file = STATIONS_FILE + "_invalid_records.log"

        log_file_path = output_valid / log_file

        output_file = STATIONS_FILE + ".parquet"

        output_valid_file_path = output_valid / output_file

        assert not os.path.exists(log_file_path)
        assert os.path.exists(output_valid_file_path)

    def test_collecting_invalid_data(
        self,
        tmp_station_invalid_data,
    ):
        """Ensure StationDataCollector creates a log file when processing
        invalid data.

        Parameters
        ----------
        tmp_station_invalid_data : fixture
            Fixture providing a directory with invalid CSV data.

        Asserts
        ------
        Exception
            Expected error when the collector encounters only invalid data.
        """
        stage_invalid, output_invalid = tmp_station_invalid_data

        stations_data = StationDataCollector(
            stage_invalid,
            output_invalid,
            STATIONS_FILE,
            STATION_COLUMN_NAMES,
            StationData,
        )

        output_file = STATIONS_FILE + ".parquet"
        output_invalid_file_path = output_invalid / output_file

        with pytest.raises(Exception) as excinfo:
            stations_data.start()
        assert "All collected data was invalid." in str(
            excinfo.value,
        )

        log_files = glob.glob(os.path.join(output_invalid, "*.log"))

        assert len(log_files) == 3
        assert not os.path.exists(output_invalid_file_path)

    def test_collecting_mixed_data(
        self,
        tmp_station_mixed_data,
    ):
        """Ensure StationDataCollector handles mixed data correctly.

        Parameters
        ----------
        tmp_station_mixed_data : fixture
            Fixture providing a directory with mixed CSV data.

        Asserts
        ------
        bool
            A log file is created for invalid records and an output file
            exists.
        """
        stage_mixed, output_mixed = tmp_station_mixed_data

        stations_data = StationDataCollector(
            stage_mixed,
            output_mixed,
            STATIONS_FILE,
            STATION_COLUMN_NAMES,
            StationData,
        )

        output_file = STATIONS_FILE + ".parquet"
        output_mixed_file_path = output_mixed / output_file

        stations_data.start()

        log_files = glob.glob(os.path.join(output_mixed, "*.log"))

        assert len(log_files) == 1

        assert os.path.exists(output_mixed_file_path)

test_collecting_empty_folder(tmp_path_factory)

Ensure StationDataCollector raises an error when scanning an empty folder.

Parameters

tmp_path_factory : fixture Pytest fixture that provides a factory for temporary directories.

Asserts

ValueError Expected error when the collector encounters an empty folder.

Source code in tests/tools/test_collectors.py
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
def test_collecting_empty_folder(
    self,
    tmp_path_factory,
):
    """Ensure StationDataCollector raises an error when scanning an empty
    folder.

    Parameters
    ----------
    tmp_path_factory : fixture
        Pytest fixture that provides a factory for temporary directories.

    Asserts
    ------
    ValueError
        Expected error when the collector encounters an empty folder.
    """
    stage_empty = tmp_path_factory.mktemp("stage_empty")
    output_empty = tmp_path_factory.mktemp("output_empty")

    stations_data = StationDataCollector(
        stage_empty,
        output_empty,
        STATIONS_FILE,
        STATION_COLUMN_NAMES,
        StationData,
    )

    output_file = STATIONS_FILE + ".parquet"

    output_empty_file_path = output_empty / output_file

    with pytest.raises(ValueError) as excinfo:
        stations_data.start()
    assert "No CSV files found in the specified folder." in str(
        excinfo.value,
    )
    assert not os.path.exists(output_empty_file_path)

test_collecting_invalid_data(tmp_station_invalid_data)

Ensure StationDataCollector creates a log file when processing invalid data.

Parameters

tmp_station_invalid_data : fixture Fixture providing a directory with invalid CSV data.

Asserts

Exception Expected error when the collector encounters only invalid data.

Source code in tests/tools/test_collectors.py
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
def test_collecting_invalid_data(
    self,
    tmp_station_invalid_data,
):
    """Ensure StationDataCollector creates a log file when processing
    invalid data.

    Parameters
    ----------
    tmp_station_invalid_data : fixture
        Fixture providing a directory with invalid CSV data.

    Asserts
    ------
    Exception
        Expected error when the collector encounters only invalid data.
    """
    stage_invalid, output_invalid = tmp_station_invalid_data

    stations_data = StationDataCollector(
        stage_invalid,
        output_invalid,
        STATIONS_FILE,
        STATION_COLUMN_NAMES,
        StationData,
    )

    output_file = STATIONS_FILE + ".parquet"
    output_invalid_file_path = output_invalid / output_file

    with pytest.raises(Exception) as excinfo:
        stations_data.start()
    assert "All collected data was invalid." in str(
        excinfo.value,
    )

    log_files = glob.glob(os.path.join(output_invalid, "*.log"))

    assert len(log_files) == 3
    assert not os.path.exists(output_invalid_file_path)

test_collecting_mixed_data(tmp_station_mixed_data)

Ensure StationDataCollector handles mixed data correctly.

Parameters

tmp_station_mixed_data : fixture Fixture providing a directory with mixed CSV data.

Asserts

bool A log file is created for invalid records and an output file exists.

Source code in tests/tools/test_collectors.py
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
def test_collecting_mixed_data(
    self,
    tmp_station_mixed_data,
):
    """Ensure StationDataCollector handles mixed data correctly.

    Parameters
    ----------
    tmp_station_mixed_data : fixture
        Fixture providing a directory with mixed CSV data.

    Asserts
    ------
    bool
        A log file is created for invalid records and an output file
        exists.
    """
    stage_mixed, output_mixed = tmp_station_mixed_data

    stations_data = StationDataCollector(
        stage_mixed,
        output_mixed,
        STATIONS_FILE,
        STATION_COLUMN_NAMES,
        StationData,
    )

    output_file = STATIONS_FILE + ".parquet"
    output_mixed_file_path = output_mixed / output_file

    stations_data.start()

    log_files = glob.glob(os.path.join(output_mixed, "*.log"))

    assert len(log_files) == 1

    assert os.path.exists(output_mixed_file_path)

test_collecting_valid_data(tmp_station_valid_data)

Ensure StationDataCollector does not create a log file when processing valid data.

Parameters

tmp_station_valid_data : fixture Fixture providing a directory with valid CSV data.

Asserts

bool No log file is created and an output file exists.

Source code in tests/tools/test_collectors.py
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
def test_collecting_valid_data(
    self,
    tmp_station_valid_data,
):
    """Ensure StationDataCollector does not create a log file when
    processing valid data.

    Parameters
    ----------
    tmp_station_valid_data : fixture
        Fixture providing a directory with valid CSV data.

    Asserts
    ------
    bool
        No log file is created and an output file exists.
    """
    stage_valid, output_valid = tmp_station_valid_data

    stations_data = StationDataCollector(
        stage_valid,
        output_valid,
        STATIONS_FILE,
        STATION_COLUMN_NAMES,
        StationData,
    )

    stations_data.start()

    log_file = STATIONS_FILE + "_invalid_records.log"

    log_file_path = output_valid / log_file

    output_file = STATIONS_FILE + ".parquet"

    output_valid_file_path = output_valid / output_file

    assert not os.path.exists(log_file_path)
    assert os.path.exists(output_valid_file_path)

TestWeatherDataCollector

Source code in tests/tools/test_collectors.py
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
class TestWeatherDataCollector:
    def test_collecting_empty_folder(
        self,
        tmp_path_factory,
    ):
        """Ensure WeatherDataCollector raises an error when scanning an empty
        folder.

        Parameters
        ----------
        tmp_path_factory : fixture
            Pytest fixture that provides a factory for temporary directories.

        Asserts
        ------
        ValueError
            Expected error when the collector encounters an empty folder.
        """
        stage_empty = tmp_path_factory.mktemp("stage_empty")
        output_empty = tmp_path_factory.mktemp("output_empty")

        weather_data = WeatherDataCollector(
            stage_empty,
            output_empty,
            WEATHER_FILE,
            WEATHER_COLUMN_NAMES,
            WeatherData,
        )

        output_file = WEATHER_FILE + ".parquet"

        output_empty_file_path = output_empty / output_file

        with pytest.raises(ValueError) as excinfo:
            weather_data.start()
        assert "No CSV files found in the specified folder." in str(
            excinfo.value,
        )
        assert not os.path.exists(output_empty_file_path)

    def test_collecting_valid_data(
        self,
        tmp_station_valid_data,
    ):
        """Ensure WeatherDataCollector does not create a log file when
        processing valid data.

        Parameters
        ----------
        tmp_station_valid_data : fixture
            Fixture providing a directory with valid CSV data.

        Asserts
        ------
        bool
            No log file is created and an output file exists.
        """
        stage_valid, output_valid = tmp_station_valid_data

        weather_data = WeatherDataCollector(
            stage_valid,
            output_valid,
            WEATHER_FILE,
            WEATHER_COLUMN_NAMES,
            WeatherData,
        )

        weather_data.start()

        log_file = WEATHER_FILE + "_invalid_records.log"

        log_file_path = output_valid / log_file

        output_file = WEATHER_FILE + ".parquet"

        output_valid_file_path = output_valid / output_file

        assert not os.path.exists(log_file_path)
        assert os.path.exists(output_valid_file_path)

    def test_collecting_invalid_data(
        self,
        tmp_station_invalid_data,
    ):
        """Ensure WeatherDataCollector creates a log file when processing
        invalid data.

        Parameters
        ----------
        tmp_station_invalid_data : fixture
            Fixture providing a directory with invalid CSV data.

        Asserts
        ------
        Exception
            Expected error when the collector encounters only invalid data.
        """
        stage_invalid, output_invalid = tmp_station_invalid_data

        weather_data = WeatherDataCollector(
            stage_invalid,
            output_invalid,
            WEATHER_FILE,
            WEATHER_COLUMN_NAMES,
            WeatherData,
        )

        output_file = WEATHER_FILE + ".parquet"
        output_invalid_file_path = output_invalid / output_file

        with pytest.raises(Exception) as excinfo:
            weather_data.start()

        log_files = glob.glob(os.path.join(output_invalid, "*.log"))

        assert "All collected data was invalid." in str(
            excinfo.value,
        )
        assert len(log_files) == 3
        assert not os.path.exists(output_invalid_file_path)

    def test_collecting_mixed_data(
        self,
        tmp_station_mixed_data,
    ):
        """Ensure WeatherDataCollector handles mixed data correctly.

        Parameters
        ----------
        tmp_station_mixed_data : fixture
            Fixture providing a directory with mixed CSV data.

        Asserts
        ------
        bool
            A log file is created for invalid records and an output file
            exists.
        """
        stage_mixed, output_mixed = tmp_station_mixed_data

        weather_data = WeatherDataCollector(
            stage_mixed,
            output_mixed,
            WEATHER_FILE,
            WEATHER_COLUMN_NAMES,
            WeatherData,
        )

        output_file = WEATHER_FILE + ".parquet"
        output_mixed_file_path = output_mixed / output_file

        weather_data.start()

        log_files = glob.glob(os.path.join(output_mixed, "*.log"))

        assert len(log_files) == 2

        assert os.path.exists(output_mixed_file_path)

test_collecting_empty_folder(tmp_path_factory)

Ensure WeatherDataCollector raises an error when scanning an empty folder.

Parameters

tmp_path_factory : fixture Pytest fixture that provides a factory for temporary directories.

Asserts

ValueError Expected error when the collector encounters an empty folder.

Source code in tests/tools/test_collectors.py
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
def test_collecting_empty_folder(
    self,
    tmp_path_factory,
):
    """Ensure WeatherDataCollector raises an error when scanning an empty
    folder.

    Parameters
    ----------
    tmp_path_factory : fixture
        Pytest fixture that provides a factory for temporary directories.

    Asserts
    ------
    ValueError
        Expected error when the collector encounters an empty folder.
    """
    stage_empty = tmp_path_factory.mktemp("stage_empty")
    output_empty = tmp_path_factory.mktemp("output_empty")

    weather_data = WeatherDataCollector(
        stage_empty,
        output_empty,
        WEATHER_FILE,
        WEATHER_COLUMN_NAMES,
        WeatherData,
    )

    output_file = WEATHER_FILE + ".parquet"

    output_empty_file_path = output_empty / output_file

    with pytest.raises(ValueError) as excinfo:
        weather_data.start()
    assert "No CSV files found in the specified folder." in str(
        excinfo.value,
    )
    assert not os.path.exists(output_empty_file_path)

test_collecting_invalid_data(tmp_station_invalid_data)

Ensure WeatherDataCollector creates a log file when processing invalid data.

Parameters

tmp_station_invalid_data : fixture Fixture providing a directory with invalid CSV data.

Asserts

Exception Expected error when the collector encounters only invalid data.

Source code in tests/tools/test_collectors.py
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
def test_collecting_invalid_data(
    self,
    tmp_station_invalid_data,
):
    """Ensure WeatherDataCollector creates a log file when processing
    invalid data.

    Parameters
    ----------
    tmp_station_invalid_data : fixture
        Fixture providing a directory with invalid CSV data.

    Asserts
    ------
    Exception
        Expected error when the collector encounters only invalid data.
    """
    stage_invalid, output_invalid = tmp_station_invalid_data

    weather_data = WeatherDataCollector(
        stage_invalid,
        output_invalid,
        WEATHER_FILE,
        WEATHER_COLUMN_NAMES,
        WeatherData,
    )

    output_file = WEATHER_FILE + ".parquet"
    output_invalid_file_path = output_invalid / output_file

    with pytest.raises(Exception) as excinfo:
        weather_data.start()

    log_files = glob.glob(os.path.join(output_invalid, "*.log"))

    assert "All collected data was invalid." in str(
        excinfo.value,
    )
    assert len(log_files) == 3
    assert not os.path.exists(output_invalid_file_path)

test_collecting_mixed_data(tmp_station_mixed_data)

Ensure WeatherDataCollector handles mixed data correctly.

Parameters

tmp_station_mixed_data : fixture Fixture providing a directory with mixed CSV data.

Asserts

bool A log file is created for invalid records and an output file exists.

Source code in tests/tools/test_collectors.py
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
def test_collecting_mixed_data(
    self,
    tmp_station_mixed_data,
):
    """Ensure WeatherDataCollector handles mixed data correctly.

    Parameters
    ----------
    tmp_station_mixed_data : fixture
        Fixture providing a directory with mixed CSV data.

    Asserts
    ------
    bool
        A log file is created for invalid records and an output file
        exists.
    """
    stage_mixed, output_mixed = tmp_station_mixed_data

    weather_data = WeatherDataCollector(
        stage_mixed,
        output_mixed,
        WEATHER_FILE,
        WEATHER_COLUMN_NAMES,
        WeatherData,
    )

    output_file = WEATHER_FILE + ".parquet"
    output_mixed_file_path = output_mixed / output_file

    weather_data.start()

    log_files = glob.glob(os.path.join(output_mixed, "*.log"))

    assert len(log_files) == 2

    assert os.path.exists(output_mixed_file_path)

test_collecting_valid_data(tmp_station_valid_data)

Ensure WeatherDataCollector does not create a log file when processing valid data.

Parameters

tmp_station_valid_data : fixture Fixture providing a directory with valid CSV data.

Asserts

bool No log file is created and an output file exists.

Source code in tests/tools/test_collectors.py
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
def test_collecting_valid_data(
    self,
    tmp_station_valid_data,
):
    """Ensure WeatherDataCollector does not create a log file when
    processing valid data.

    Parameters
    ----------
    tmp_station_valid_data : fixture
        Fixture providing a directory with valid CSV data.

    Asserts
    ------
    bool
        No log file is created and an output file exists.
    """
    stage_valid, output_valid = tmp_station_valid_data

    weather_data = WeatherDataCollector(
        stage_valid,
        output_valid,
        WEATHER_FILE,
        WEATHER_COLUMN_NAMES,
        WeatherData,
    )

    weather_data.start()

    log_file = WEATHER_FILE + "_invalid_records.log"

    log_file_path = output_valid / log_file

    output_file = WEATHER_FILE + ".parquet"

    output_valid_file_path = output_valid / output_file

    assert not os.path.exists(log_file_path)
    assert os.path.exists(output_valid_file_path)

create_files(destiny_folder, data_to_files)

Create CSV files from a list of CSV content strings in a specified folder.

Parameters

destiny_folder : pathlib.Path Destination folder where CSV files will be created. data_to_files : List[str] List of strings, each representing the content of a CSV file.

Source code in tests/tools/test_collectors.py
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
def create_files(
    destiny_folder: pathlib.Path,
    data_to_files: List[str],
) -> None:
    """Create CSV files from a list of CSV content strings in a specified
    folder.

    Parameters
    ----------
    destiny_folder : pathlib.Path
        Destination folder where CSV files will be created.
    data_to_files : List[str]
        List of strings, each representing the content of a CSV file.
    """
    for file_number, csv_data in enumerate(data_to_files):
        file_name = "file_" + str(file_number) + ".csv"
        file = destiny_folder / file_name
        file.write_text(csv_data)

list_with_invalid_int_years()

Provide a list of integer years that are not valid for data collection, as they precede the established start year.

This fixture is used to simulate scenarios where the data collector receives years that are outside the scope of the collection period.

Returns

list A list containing integer years that fall before the first year from which data collection is considered valid.

Source code in tests/tools/test_collectors.py
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
@pytest.fixture()
def list_with_invalid_int_years():
    """Provide a list of integer years that are not valid for data collection,
    as they precede the established start year.

    This fixture is used to simulate scenarios where the data collector
    receives years that are outside the scope of the collection period.

    Returns
    -------
    list
        A list containing integer years that fall before the first year from
        which data collection is considered valid.
    """
    return [1998, 1988, 1999]

list_with_invalid_str_years()

Supply a list of strings that are not valid year representations for testing the data collector's year filtering.

This fixture is useful for testing the data collector's ability to ignore non-integer inputs when filtering years.

Returns

list A list containing strings that are invalid as year inputs.

Source code in tests/tools/test_collectors.py
289
290
291
292
293
294
295
296
297
298
299
300
301
302
@pytest.fixture()
def list_with_invalid_str_years():
    """Supply a list of strings that are not valid year representations for
    testing the data collector's year filtering.

    This fixture is useful for testing the data collector's ability to ignore
    non-integer inputs when filtering years.

    Returns
    -------
    list
        A list containing strings that are invalid as year inputs.
    """
    return ["A", "B", "C"]

list_with_mix_int_str_years()

Produce a list with a combination of valid integer years and invalid string representations for testing year filtering.

This fixture aids in testing the data collector's robustness in handling mixed data types in year lists.

Returns

list A list that includes both valid integer years and strings that represent invalid years.

Source code in tests/tools/test_collectors.py
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
@pytest.fixture()
def list_with_mix_int_str_years():
    """Produce a list with a combination of valid integer years and invalid
    string representations for testing year filtering.

    This fixture aids in testing the data collector's robustness in handling
    mixed data types in year lists.

    Returns
    -------
    list
        A list that includes both valid integer years and strings that
        represent invalid years.
    """
    return ["A", 2010, 2023]

list_with_mix_int_years()

Generate a list with a mix of valid and invalid integer years for testing the data collector's filtering logic.

This fixture helps to ensure that the data collector correctly identifies and filters out years that are not within the valid range.

Returns

list A list containing a combination of valid and invalid integer years.

Source code in tests/tools/test_collectors.py
319
320
321
322
323
324
325
326
327
328
329
330
331
332
@pytest.fixture()
def list_with_mix_int_years():
    """Generate a list with a mix of valid and invalid integer years for
    testing the data collector's filtering logic.

    This fixture helps to ensure that the data collector correctly identifies
    and filters out years that are not within the valid range.

    Returns
    -------
    list
        A list containing a combination of valid and invalid integer years.
    """
    return [1999, 2010, 2023]

list_with_valid_years()

Provide a list of integer years that are all within the valid data collection range for testing.

Returns

list A list containing only valid integer years, starting from the first year data collection is considered valid.

Source code in tests/tools/test_collectors.py
305
306
307
308
309
310
311
312
313
314
315
316
@pytest.fixture()
def list_with_valid_years():
    """Provide a list of integer years that are all within the valid data
    collection range for testing.

    Returns
    -------
    list
        A list containing only valid integer years, starting from the first
        year data collection is considered valid.
    """
    return [2000, 2010, 2023]

tmp_station_invalid_data(tmp_path)

Create a temporary directory with invalid station data for testing.

Parameters

tmp_path : py.path.local Fixture provided by pytest to create and return temporary directories.

Yields

tuple A tuple containing the path to the invalid staging data and the output directory.

Source code in tests/tools/test_collectors.py
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
@pytest.fixture()
def tmp_station_invalid_data(tmp_path):
    """Create a temporary directory with invalid station data for testing.

    Parameters
    ----------
    tmp_path : py.path.local
        Fixture provided by pytest to create and return temporary directories.

    Yields
    ------
    tuple
        A tuple containing the path to the invalid staging data and the output directory.
    """
    temp_stage_invalid = tmp_path / "stage-invalid"
    temp_stage_invalid.mkdir()
    temp_output_invalid = tmp_path / "output-invalid"
    temp_output_invalid.mkdir()

    csv_data_infos = [
        "REGIAO:;CO\n"
        "UF:;DF\n"
        "ESTACAO:;BRASILIA\n"
        "CODIGO (WMO):;A001\n"
        "LATITUDE:;aaaaaaaaaa\n"
        "LONGITUDE:;-47,92583332\n"
        "ALTITUDE:;1160,96\n"
        "DATA DE FUNDACAO:;07/05/00\n"
        "Data;Hora UTC;PRECIPITAÇÃO TOTAL, HORÁRIO (mm);PRESSAO ATMOSFERICA AO NIVEL DA ESTACAO, HORARIA (mB);PRESSÃO ATMOSFERICA MAX.NA HORA ANT. (AUT) (mB);PRESSÃO ATMOSFERICA MIN. NA HORA ANT. (AUT) (mB);RADIACAO GLOBAL (Kj/m²);TEMPERATURA DO AR - BULBO SECO, HORARIA (°C);TEMPERATURA DO PONTO DE ORVALHO (°C);TEMPERATURA MÁXIMA NA HORA ANT. (AUT) (°C);TEMPERATURA MÍNIMA NA HORA ANT. (AUT) (°C);TEMPERATURA ORVALHO MAX. NA HORA ANT. (AUT) (°C);TEMPERATURA ORVALHO MIN. NA HORA ANT. (AUT) (°C);UMIDADE REL. MAX. NA HORA ANT. (AUT) (%);UMIDADE REL. MIN. NA HORA ANT. (AUT) (%);UMIDADE RELATIVA DO AR, HORARIA (%);VENTO, DIREÇÃO HORARIA (gr) (° (gr));VENTO, RAJADA MAXIMA (m/s);VENTO, VELOCIDADE HORARIA (m/s);\n"
        "2023/01/01;0000 ;0;887,7;887,7;887,2;;20,1;17,9;20,9;20;19,2;17,8;91;87;87;187;3,3;1,2;\n"
        "2023/01/01;0100 ;0;888,1;888,1;887,7;;19,2;17,5;20,1;19,2;17,8;17,4;90;87;90;153;2,9;,8;\n"
        "2023/01/01;0200 ;0;887,8;888,1;887,8;;19,3;17,6;19,5;19;17,8;17,3;90;89;90;145;2,5;1,5;\n"
        "2023/01/01;0300 ;0;887,8;887,9;887,7;;19,3;17,7;19,4;19,1;17,8;17,5;91;90;91;162;3,2;1,4;\n"
        "2023/01/01;0400 ;0;887,6;887,9;887,6;;19,7;18,1;19,7;19,1;18,1;17,4;91;90;90;140;5,7;2,7;\n"
        "2023/01/01;0500 ;0;886,7;887,6;886,7;;19,1;17,7;19,7;19,1;18,1;17,7;92;90;92;128;7,1;2;"
        "",
        "REGIAO:;CO\n"
        "UF:;DF\n"
        "ESTACAO:;BRAZLANDIA\n"
        "CODIGO (WMO):;A042\n"
        "LATITUDE:;-15,59972221\n"
        "LONGITUDE:;aaaaaaa\n"
        "ALTITUDE:;1143\n"
        "DATA DE FUNDACAO:;19/07/17\n"
        "Data;Hora UTC;PRECIPITAÇÃO TOTAL, HORÁRIO (mm);PRESSAO ATMOSFERICA AO NIVEL DA ESTACAO, HORARIA (mB);PRESSÃO ATMOSFERICA MAX.NA HORA ANT. (AUT) (mB);PRESSÃO ATMOSFERICA MIN. NA HORA ANT. (AUT) (mB);RADIACAO GLOBAL (Kj/m²);TEMPERATURA DO AR - BULBO SECO, HORARIA (°C);TEMPERATURA DO PONTO DE ORVALHO (°C);TEMPERATURA MÁXIMA NA HORA ANT. (AUT) (°C);TEMPERATURA MÍNIMA NA HORA ANT. (AUT) (°C);TEMPERATURA ORVALHO MAX. NA HORA ANT. (AUT) (°C);TEMPERATURA ORVALHO MIN. NA HORA ANT. (AUT) (°C);UMIDADE REL. MAX. NA HORA ANT. (AUT) (%);UMIDADE REL. MIN. NA HORA ANT. (AUT) (%);UMIDADE RELATIVA DO AR, HORARIA (%);VENTO, DIREÇÃO HORARIA (gr) (° (gr));VENTO, RAJADA MAXIMA (m/s);VENTO, VELOCIDADE HORARIA (m/s);\n"  # noqa
        "/01/01;0000 UTC;0;888,7;888,9;888,2;;20,5;18;21;20,5;18,4;18;87;84;86;146;3,9;1,8;\n"
        "/01/01;0100 UTC;0;889;889;888,7;;20,4;17,5;20,5;20,3;18;17,5;86;84;84;142;4,1;1,8;\n"
        "/01/01;0200 UTC;0;888,9;889,1;888,9;;19,9;17,4;20,4;19,8;17,5;17,3;86;83;86;153;4;,2;\n"
        "/01/01;0300 UTC;0;888,7;888,9;888,7;;19,8;17,4;19,9;19,7;17,4;17,2;87;85;86;140;3,5;1,2;\n"
        "/01/01;0400 UTC;0;888,4;888,8;888,4;;20,1;17,3;20,1;19,8;17,5;17,3;86;84;84;139;3,3;,3;\n"
        "/01/01;0500 UTC;0;887,8;888,4;887,8;;19,8;17,6;20,3;19,8;17,6;17,2;87;83;87;138;5,2;1,3;\n"
        "/01/01;0600 UTC;0;887,5;887,9;887,5;;19,6;17,3;19,8;19,5;17,7;17,3;89;87;87;133;4,1;,3;\n"
        "/01/01;0700 UTC;0;887,5;887,5;887,3;;19,1;17,3;19,6;19,1;17,3;17,2;89;87;89;95;4,4;1,4;\n"
        "/01/01;0800 UTC;0;887,6;887,6;887,5;;18,9;17,1;19,2;18,3;17,5;16,9;92;89;89;49;5,5;2,4;\n"
        "/01/01;0900 UTC;0;888;888;887,4;5,3;18,8;17;19,1;18,4;17,1;16,6;90;88;89;73;4,8;,6;",
        "REGIAO:;N\n"
        "UF:;AM\n"
        "ESTACAO:;COARI\n"
        "CODIGO (WMO):;A117\n"
        "LATITUDE:;-4,09749999\n"
        "LONGITUDE:;aaaaaaaa\n"
        "ALTITUDE:;33,84\n"
        "DATA DE FUNDACAO:;12/04/08\n"
        "Data;Hora UTC;PRECIPITAÇÃO TOTAL, HORÁRIO (mm);PRESSAO ATMOSFERICA AO NIVEL DA ESTACAO, HORARIA (mB);PRESSÃO ATMOSFERICA MAX.NA HORA ANT. (AUT) (mB);PRESSÃO ATMOSFERICA MIN. NA HORA ANT. (AUT) (mB);RADIACAO GLOBAL (Kj/m²);TEMPERATURA DO AR - BULBO SECO, HORARIA (°C);TEMPERATURA DO PONTO DE ORVALHO (°C);TEMPERATURA MÁXIMA NA HORA ANT. (AUT) (°C);TEMPERATURA MÍNIMA NA HORA ANT. (AUT) (°C);TEMPERATURA ORVALHO MAX. NA HORA ANT. (AUT) (°C);TEMPERATURA ORVALHO MIN. NA HORA ANT. (AUT) (°C);UMIDADE REL. MAX. NA HORA ANT. (AUT) (%);UMIDADE REL. MIN. NA HORA ANT. (AUT) (%);UMIDADE RELATIVA DO AR, HORARIA (%);VENTO, DIREÇÃO HORARIA (gr) (° (gr));VENTO, RAJADA MAXIMA (m/s);VENTO, VELOCIDADE HORARIA (m/s);\n"
        "2023//01;0000 UTC;;;;;;;;;;;;;;;;;;\n"
        "2023//01;0100 UTC;;;;;;;;;;;;;;;;;;\n"
        "2023//01;0200 UTC;;;;;;;;;;;;;;;;;;\n"
        "2023//01;0300 UTC;;;;;;;;;;;;;;;;;;\n"
        "2023//01;0400 UTC;;;;;;;;;;;;;;;;;;",
    ]

    create_files(temp_stage_invalid, csv_data_infos)

    yield temp_stage_invalid, temp_output_invalid

tmp_station_mixed_data(tmp_path)

Create a temporary directory with mixed (valid and invalid) station data for testing.

Parameters

tmp_path : py.path.local Fixture provided by pytest to create and return temporary directories.

Yields

tuple A tuple containing the path to the mixed staging data and the output directory.

Source code in tests/tools/test_collectors.py
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
@pytest.fixture()
def tmp_station_mixed_data(tmp_path):
    """Create a temporary directory with mixed (valid and invalid) station data for testing.

    Parameters
    ----------
    tmp_path : py.path.local
        Fixture provided by pytest to create and return temporary directories.

    Yields
    ------
    tuple
        A tuple containing the path to the mixed staging data and the output directory.
    """
    temp_stage_mixed = tmp_path / "stage-mixed"
    temp_stage_mixed.mkdir()
    temp_output_mixed = tmp_path / "output-mixed"
    temp_output_mixed.mkdir()

    csv_data_infos = [
        "REGIAO:;CO\n"
        "UF:;DF\n"
        "ESTACAO:;BRASILIA\n"
        "CODIGO (WMO):;A001\n"
        "LATITUDE:;-15,78944444\n"
        "LONGITUDE:;-47,92583332\n"
        "ALTITUDE:;1160,96\n"
        "DATA DE FUNDACAO:;07/05/00\n"
        "Data;Hora UTC;PRECIPITAÇÃO TOTAL, HORÁRIO (mm);PRESSAO ATMOSFERICA AO NIVEL DA ESTACAO, HORARIA (mB);PRESSÃO ATMOSFERICA MAX.NA HORA ANT. (AUT) (mB);PRESSÃO ATMOSFERICA MIN. NA HORA ANT. (AUT) (mB);RADIACAO GLOBAL (Kj/m²);TEMPERATURA DO AR - BULBO SECO, HORARIA (°C);TEMPERATURA DO PONTO DE ORVALHO (°C);TEMPERATURA MÁXIMA NA HORA ANT. (AUT) (°C);TEMPERATURA MÍNIMA NA HORA ANT. (AUT) (°C);TEMPERATURA ORVALHO MAX. NA HORA ANT. (AUT) (°C);TEMPERATURA ORVALHO MIN. NA HORA ANT. (AUT) (°C);UMIDADE REL. MAX. NA HORA ANT. (AUT) (%);UMIDADE REL. MIN. NA HORA ANT. (AUT) (%);UMIDADE RELATIVA DO AR, HORARIA (%);VENTO, DIREÇÃO HORARIA (gr) (° (gr));VENTO, RAJADA MAXIMA (m/s);VENTO, VELOCIDADE HORARIA (m/s);\n"  # noqa
        "2023/01/01;0000 UTC;0;887,7;887,7;887,2;;20,1;17,9;20,9;20;19,2;17,8;91;87;87;187;3,3;1,2;\n"
        "2023/01/01;0100 UTC;0;888,1;888,1;887,7;;19,2;17,5;20,1;19,2;17,8;17,4;90;87;90;153;2,9;,8;\n"
        "2023/01/01;0200 UTC;0;887,8;888,1;887,8;;19,3;17,6;19,5;19;17,8;17,3;90;89;90;145;2,5;1,5;\n"
        "2023/01/01;0300 UTC;0;887,8;887,9;887,7;;19,3;17,7;19,4;19,1;17,8;17,5;91;90;91;162;3,2;1,4;\n"
        "2023/01/01;0400 UTC;0;887,6;887,9;887,6;;19,7;18,1;19,7;19,1;18,1;17,4;91;90;90;140;5,7;2,7;\n"
        "2023/01/01;0500 UTC;0;886,7;887,6;886,7;;19,1;17,7;19,7;19,1;18,1;17,7;92;90;92;128;7,1;2;",
        "REGIAO:;CO\n"
        "UF:;DF\n"
        "ESTACAO:;BRAZLANDIA\n"
        "CODIGO (WMO):;AAAA\n"
        "LATITUDE:;-15,59972221\n"
        "LONGITUDE:;-48,1311111\n"
        "ALTITUDE:;1143\n"
        "DATA DE FUNDACAO:;19/07/17\n"
        "Data;Hora UTC;PRECIPITAÇÃO TOTAL, HORÁRIO (mm);PRESSAO ATMOSFERICA AO NIVEL DA ESTACAO, HORARIA (mB);PRESSÃO ATMOSFERICA MAX.NA HORA ANT. (AUT) (mB);PRESSÃO ATMOSFERICA MIN. NA HORA ANT. (AUT) (mB);RADIACAO GLOBAL (Kj/m²);TEMPERATURA DO AR - BULBO SECO, HORARIA (°C);TEMPERATURA DO PONTO DE ORVALHO (°C);TEMPERATURA MÁXIMA NA HORA ANT. (AUT) (°C);TEMPERATURA MÍNIMA NA HORA ANT. (AUT) (°C);TEMPERATURA ORVALHO MAX. NA HORA ANT. (AUT) (°C);TEMPERATURA ORVALHO MIN. NA HORA ANT. (AUT) (°C);UMIDADE REL. MAX. NA HORA ANT. (AUT) (%);UMIDADE REL. MIN. NA HORA ANT. (AUT) (%);UMIDADE RELATIVA DO AR, HORARIA (%);VENTO, DIREÇÃO HORARIA (gr) (° (gr));VENTO, RAJADA MAXIMA (m/s);VENTO, VELOCIDADE HORARIA (m/s);\n"  # noqa
        "2023/01/01;0000 UTC;0;888,7;888,9;888,2;;20,5;18;21;20,5;18,4;18;87;84;86;146;3,9;1,8;\n"
        "2023/01/01;0100 UTC;0;889;889;888,7;;20,4;17,5;20,5;20,3;18;17,5;86;84;84;142;4,1;1,8;\n"
        "2023/01/01;0200 UTC;0;888,9;889,1;888,9;;19,9;17,4;20,4;19,8;17,5;17,3;86;83;86;153;4;,2;\n"
        "2023/01/01;0300 UTC;0;888,7;888,9;888,7;;19,8;17,4;19,9;19,7;17,4;17,2;87;85;86;140;3,5;1,2;\n"
        "2023/01/01;0400 UTC;0;888,4;888,8;888,4;;20,1;17,3;20,1;19,8;17,5;17,3;86;84;84;139;3,3;,3;\n"
        "2023/01/01;0500 UTC;0;887,8;888,4;887,8;;19,8;17,6;20,3;19,8;17,6;17,2;87;83;87;138;5,2;1,3;\n"
        "2023/01/01;0600 UTC;0;887,5;887,9;887,5;;19,6;17,3;19,8;19,5;17,7;17,3;89;87;87;133;4,1;,3;\n"
        "2023/01/01;0700 UTC;0;887,5;887,5;887,3;;19,1;17,3;19,6;19,1;17,3;17,2;89;87;89;95;4,4;1,4;\n"
        "2023/01/01;0800 UTC;0;887,6;887,6;887,5;;18,9;17,1;19,2;18,3;17,5;16,9;92;89;89;49;5,5;2,4;\n"
        "2023/01/01;0900 UTC;0;888;888;887,4;5,3;18,8;17;19,1;18,4;17,1;16,6;90;88;89;73;4,8;,6;",
        "REGIAO:;N\n"
        "UF:;AM\n"
        "ESTACAO:;COARI\n"
        "CODIGO (WMO):;A117\n"
        "LATITUDE:;-4,09749999\n"
        "LONGITUDE:;-63,14527777\n"
        "ALTITUDE:;33,84\n"
        "DATA DE FUNDACAO:;12/04/08\n"
        "Data;Hora UTC;PRECIPITAÇÃO TOTAL, HORÁRIO (mm);PRESSAO ATMOSFERICA AO NIVEL DA ESTACAO, HORARIA (mB);PRESSÃO ATMOSFERICA MAX.NA HORA ANT. (AUT) (mB);PRESSÃO ATMOSFERICA MIN. NA HORA ANT. (AUT) (mB);RADIACAO GLOBAL (Kj/m²);TEMPERATURA DO AR - BULBO SECO, HORARIA (°C);TEMPERATURA DO PONTO DE ORVALHO (°C);TEMPERATURA MÁXIMA NA HORA ANT. (AUT) (°C);TEMPERATURA MÍNIMA NA HORA ANT. (AUT) (°C);TEMPERATURA ORVALHO MAX. NA HORA ANT. (AUT) (°C);TEMPERATURA ORVALHO MIN. NA HORA ANT. (AUT) (°C);UMIDADE REL. MAX. NA HORA ANT. (AUT) (%);UMIDADE REL. MIN. NA HORA ANT. (AUT) (%);UMIDADE RELATIVA DO AR, HORARIA (%);VENTO, DIREÇÃO HORARIA (gr) (° (gr));VENTO, RAJADA MAXIMA (m/s);VENTO, VELOCIDADE HORARIA (m/s);\n"
        "/01/01;0000 UTC;;;;;;;;;;;;;;;;;;\n"
        "/01/01;0100 UTC;;;;;;;;;;;;;;;;;;\n"
        "/01/01;0200 UTC;;;;;;;;;;;;;;;;;;\n"
        "/01/01;0300 UTC;;;;;;;;;;;;;;;;;;\n"
        "/01/01;0400 UTC;;;;;;;;;;;;;;;;;;",
    ]

    create_files(temp_stage_mixed, csv_data_infos)

    yield temp_stage_mixed, temp_output_mixed

tmp_station_valid_data(tmp_path)

Create a temporary directory with valid station data for testing.

Parameters

tmp_path : py.path.local Fixture provided by pytest to create and return temporary directories.

Yields

tuple A tuple containing the path to the valid staging data and the output directory.

Source code in tests/tools/test_collectors.py
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
@pytest.fixture()
def tmp_station_valid_data(tmp_path):
    """Create a temporary directory with valid station data for testing.

    Parameters
    ----------
    tmp_path : py.path.local
        Fixture provided by pytest to create and return temporary directories.

    Yields
    ------
    tuple
        A tuple containing the path to the valid staging data and the output
        directory.
    """
    temp_stage_valid = tmp_path / "stage-valid"
    temp_stage_valid.mkdir()
    temp_output_valid = tmp_path / "output-valid"
    temp_output_valid.mkdir()
    csv_data_infos = [
        "REGIAO:;CO\n"
        "UF:;DF\n"
        "ESTACAO:;BRASILIA\n"
        "CODIGO (WMO):;A001\n"
        "LATITUDE:;-15,78944444\n"
        "LONGITUDE:;-47,92583332\n"
        "ALTITUDE:;1160,96\n"
        "DATA DE FUNDACAO:;07/05/00\n"
        "Data;Hora UTC;PRECIPITAÇÃO TOTAL, HORÁRIO (mm);PRESSAO ATMOSFERICA AO NIVEL DA ESTACAO, HORARIA (mB);PRESSÃO ATMOSFERICA MAX.NA HORA ANT. (AUT) (mB);PRESSÃO ATMOSFERICA MIN. NA HORA ANT. (AUT) (mB);RADIACAO GLOBAL (Kj/m²);TEMPERATURA DO AR - BULBO SECO, HORARIA (°C);TEMPERATURA DO PONTO DE ORVALHO (°C);TEMPERATURA MÁXIMA NA HORA ANT. (AUT) (°C);TEMPERATURA MÍNIMA NA HORA ANT. (AUT) (°C);TEMPERATURA ORVALHO MAX. NA HORA ANT. (AUT) (°C);TEMPERATURA ORVALHO MIN. NA HORA ANT. (AUT) (°C);UMIDADE REL. MAX. NA HORA ANT. (AUT) (%);UMIDADE REL. MIN. NA HORA ANT. (AUT) (%);UMIDADE RELATIVA DO AR, HORARIA (%);VENTO, DIREÇÃO HORARIA (gr) (° (gr));VENTO, RAJADA MAXIMA (m/s);VENTO, VELOCIDADE HORARIA (m/s);\n"  # noqa
        "2023/01/01;0000 UTC;0;887,7;887,7;887,2;;20,1;17,9;20,9;20;19,2;17,8;91;87;87;187;3,3;1,2;\n"
        "2023/01/01;0100 UTC;0;888,1;888,1;887,7;;19,2;17,5;20,1;19,2;17,8;17,4;90;87;90;153;2,9;,8;\n"
        "2023/01/01;0200 UTC;0;887,8;888,1;887,8;;19,3;17,6;19,5;19;17,8;17,3;90;89;90;145;2,5;1,5;\n"
        "2023/01/01;0300 UTC;0;887,8;887,9;887,7;;19,3;17,7;19,4;19,1;17,8;17,5;91;90;91;162;3,2;1,4;\n"
        "2023/01/01;0400 UTC;0;887,6;887,9;887,6;;19,7;18,1;19,7;19,1;18,1;17,4;91;90;90;140;5,7;2,7;\n"
        "2023/01/01;0500 UTC;0;886,7;887,6;886,7;;19,1;17,7;19,7;19,1;18,1;17,7;92;90;92;128;7,1;2;",
        "REGIAO:;CO\n"
        "UF:;DF\n"
        "ESTACAO:;BRAZLANDIA\n"
        "CODIGO (WMO):;A042\n"
        "LATITUDE:;-15,59972221\n"
        "LONGITUDE:;-48,1311111\n"
        "ALTITUDE:;1143\n"
        "DATA DE FUNDACAO:;19/07/17\n"
        "Data;Hora UTC;PRECIPITAÇÃO TOTAL, HORÁRIO (mm);PRESSAO ATMOSFERICA AO NIVEL DA ESTACAO, HORARIA (mB);PRESSÃO ATMOSFERICA MAX.NA HORA ANT. (AUT) (mB);PRESSÃO ATMOSFERICA MIN. NA HORA ANT. (AUT) (mB);RADIACAO GLOBAL (Kj/m²);TEMPERATURA DO AR - BULBO SECO, HORARIA (°C);TEMPERATURA DO PONTO DE ORVALHO (°C);TEMPERATURA MÁXIMA NA HORA ANT. (AUT) (°C);TEMPERATURA MÍNIMA NA HORA ANT. (AUT) (°C);TEMPERATURA ORVALHO MAX. NA HORA ANT. (AUT) (°C);TEMPERATURA ORVALHO MIN. NA HORA ANT. (AUT) (°C);UMIDADE REL. MAX. NA HORA ANT. (AUT) (%);UMIDADE REL. MIN. NA HORA ANT. (AUT) (%);UMIDADE RELATIVA DO AR, HORARIA (%);VENTO, DIREÇÃO HORARIA (gr) (° (gr));VENTO, RAJADA MAXIMA (m/s);VENTO, VELOCIDADE HORARIA (m/s);\n"  # noqa
        "2023/01/01;0000 UTC;0;888,7;888,9;888,2;;20,5;18;21;20,5;18,4;18;87;84;86;146;3,9;1,8;\n"
        "2023/01/01;0100 UTC;0;889;889;888,7;;20,4;17,5;20,5;20,3;18;17,5;86;84;84;142;4,1;1,8;\n"
        "2023/01/01;0200 UTC;0;888,9;889,1;888,9;;19,9;17,4;20,4;19,8;17,5;17,3;86;83;86;153;4;,2;\n"
        "2023/01/01;0300 UTC;0;888,7;888,9;888,7;;19,8;17,4;19,9;19,7;17,4;17,2;87;85;86;140;3,5;1,2;\n"
        "2023/01/01;0400 UTC;0;888,4;888,8;888,4;;20,1;17,3;20,1;19,8;17,5;17,3;86;84;84;139;3,3;,3;\n"
        "2023/01/01;0500 UTC;0;887,8;888,4;887,8;;19,8;17,6;20,3;19,8;17,6;17,2;87;83;87;138;5,2;1,3;\n"
        "2023/01/01;0600 UTC;0;887,5;887,9;887,5;;19,6;17,3;19,8;19,5;17,7;17,3;89;87;87;133;4,1;,3;\n"
        "2023/01/01;0700 UTC;0;887,5;887,5;887,3;;19,1;17,3;19,6;19,1;17,3;17,2;89;87;89;95;4,4;1,4;\n"
        "2023/01/01;0800 UTC;0;887,6;887,6;887,5;;18,9;17,1;19,2;18,3;17,5;16,9;92;89;89;49;5,5;2,4;\n"
        "2023/01/01;0900 UTC;0;888;888;887,4;5,3;18,8;17;19,1;18,4;17,1;16,6;90;88;89;73;4,8;,6;",
        "REGIAO:;N\n"
        "UF:;AM\n"
        "ESTACAO:;COARI\n"
        "CODIGO (WMO):;A117\n"
        "LATITUDE:;-4,09749999\n"
        "LONGITUDE:;-63,14527777\n"
        "ALTITUDE:;33,84\n"
        "DATA DE FUNDACAO:;12/04/08\n"
        "Data;Hora UTC;PRECIPITAÇÃO TOTAL, HORÁRIO (mm);PRESSAO ATMOSFERICA AO NIVEL DA ESTACAO, HORARIA (mB);PRESSÃO ATMOSFERICA MAX.NA HORA ANT. (AUT) (mB);PRESSÃO ATMOSFERICA MIN. NA HORA ANT. (AUT) (mB);RADIACAO GLOBAL (Kj/m²);TEMPERATURA DO AR - BULBO SECO, HORARIA (°C);TEMPERATURA DO PONTO DE ORVALHO (°C);TEMPERATURA MÁXIMA NA HORA ANT. (AUT) (°C);TEMPERATURA MÍNIMA NA HORA ANT. (AUT) (°C);TEMPERATURA ORVALHO MAX. NA HORA ANT. (AUT) (°C);TEMPERATURA ORVALHO MIN. NA HORA ANT. (AUT) (°C);UMIDADE REL. MAX. NA HORA ANT. (AUT) (%);UMIDADE REL. MIN. NA HORA ANT. (AUT) (%);UMIDADE RELATIVA DO AR, HORARIA (%);VENTO, DIREÇÃO HORARIA (gr) (° (gr));VENTO, RAJADA MAXIMA (m/s);VENTO, VELOCIDADE HORARIA (m/s);\n"
        "2023/01/01;0000 UTC;;;;;;;;;;;;;;;;;;\n"
        "2023/01/01;0100 UTC;;;;;;;;;;;;;;;;;;\n"
        "2023/01/01;0200 UTC;;;;;;;;;;;;;;;;;;\n"
        "2023/01/01;0300 UTC;;;;;;;;;;;;;;;;;;\n"
        "2023/01/01;0400 UTC;;;;;;;;;;;;;;;;;;",
    ]

    create_files(temp_stage_valid, csv_data_infos)

    yield temp_stage_valid, temp_output_valid