diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index bb1719c7..2c1e2e3d 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -1 +1,2 @@ @joellabes +@callum-mcdata diff --git a/.github/actions/end-to-end-test/action.yml b/.github/actions/end-to-end-test/action.yml index ef2c868d..a1dd9c2c 100644 --- a/.github/actions/end-to-end-test/action.yml +++ b/.github/actions/end-to-end-test/action.yml @@ -1,37 +1,28 @@ name: "End to end testing" description: "Set up profile and run dbt with test project" inputs: - dbt-project: - description: "Location of test project" - required: false - default: "integration_tests" - dbt-target: + dbt_target: description: "Name of target to use when running dbt" required: true - database-adapter-package: - description: "Name of database adapter to install" - required: true + runs: using: "composite" steps: + - name: Install python dependencies shell: bash run: | pip install --user --upgrade pip pip --version - pip install -r dev-requirements.txt - - - name: Setup dbt profile - shell: bash - run: | - mkdir -p $HOME/.dbt - cp ${{ github.action_path }}/sample.profiles.yml $HOME/.dbt/profiles.yml + pip install -r dev-requirements.txt - - name: Run dbt + ## Make sure to defined dbt_target as an environment variable + ## Previously we were supplying just as an input and os.environ + ## wasn't able to recognize it. + - name: Run pytest shell: bash + env: + dbt_target: ${{ inputs.dbt_target }} run: | - cd ${{ inputs.dbt-project }} - dbt deps --target ${{ inputs.dbt-target }} - dbt seed --target ${{ inputs.dbt-target }} --full-refresh - dbt build --target ${{ inputs.dbt-target }} --full-refresh + python3 -m pytest tests/functional \ No newline at end of file diff --git a/.github/actions/end-to-end-test/sample.profiles.yml b/.github/actions/end-to-end-test/sample.profiles.yml deleted file mode 100644 index f703717d..00000000 --- a/.github/actions/end-to-end-test/sample.profiles.yml +++ /dev/null @@ -1,48 +0,0 @@ -# HEY! This file is used in the dbt-utils integrations tests with GHA. -# You should __NEVER__ check credentials into version control. Thanks for reading :) - -config: - send_anonymous_usage_stats: False - use_colors: True - -dbt_metrics_integration_tests: - target: postgres - outputs: - postgres: - type: postgres - host: "{{ env_var('POSTGRES_TEST_HOST') }}" - user: "{{ env_var('POSTGRES_TEST_USER') }}" - pass: "{{ env_var('POSTGRES_TEST_PASSWORD') }}" - port: "{{ env_var('POSTGRES_TEST_PORT') | as_number }}" - dbname: "{{ env_var('POSTGRES_TEST_DB') }}" - schema: dbt_metrics_integration_tests - threads: 5 - - redshift: - type: redshift - host: "{{ env_var('REDSHIFT_TEST_HOST') }}" - user: "{{ env_var('REDSHIFT_TEST_USER') }}" - pass: "{{ env_var('REDSHIFT_TEST_PASS') }}" - dbname: "{{ env_var('REDSHIFT_TEST_DBNAME') }}" - port: "{{ env_var('REDSHIFT_TEST_PORT') | as_number }}" - schema: dbt_metrics_integration_tests - threads: 5 - - bigquery: - type: bigquery - method: service-account - keyfile: "{{ env_var('BIGQUERY_SERVICE_KEY_PATH') }}" - project: "{{ env_var('BIGQUERY_TEST_DATABASE') }}" - schema: dbt_metrics_integration_tests - threads: 10 - - snowflake: - type: snowflake - account: "{{ env_var('SNOWFLAKE_TEST_ACCOUNT') }}" - user: "{{ env_var('SNOWFLAKE_TEST_USER') }}" - password: "{{ env_var('SNOWFLAKE_TEST_PASSWORD') }}" - role: "{{ env_var('SNOWFLAKE_TEST_ROLE') }}" - database: "{{ env_var('SNOWFLAKE_TEST_DATABASE') }}" - warehouse: "{{ env_var('SNOWFLAKE_TEST_WAREHOUSE') }}" - schema: dbt_metrics_integration_tests - threads: 10 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c6cc5630..14f05d54 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -29,6 +29,8 @@ jobs: POSTGRES_USER: ${{ env.POSTGRES_TEST_USER }} POSTGRES_PASSWORD: ${{ env.POSTGRES_TEST_PASSWORD }} POSTGRES_DB: ${{ env.POSTGRES_TEST_DB }} + POSTGRES_TEST_PORT: ${{ env.POSTGRES_TEST_PORT }} + POSTGRES_TEST_HOST: ${{ env.POSTGRES_TEST_HOST }} ports: - 5432:5432 options: >- @@ -48,11 +50,10 @@ jobs: - uses: ./.github/actions/end-to-end-test with: - dbt-target: postgres - database-adapter-package: dbt-postgres + dbt_target: postgres snowflake: - # needs: postgres + needs: postgres runs-on: ubuntu-latest steps: - name: Check out the repository @@ -72,11 +73,10 @@ jobs: SNOWFLAKE_TEST_DATABASE: ${{ secrets.SNOWFLAKE_TEST_DATABASE }} SNOWFLAKE_TEST_WAREHOUSE: ${{ secrets.SNOWFLAKE_TEST_WAREHOUSE }} with: - dbt-target: snowflake - database-adapter-package: dbt-snowflake + dbt_target: snowflake redshift: - # needs: postgres + needs: postgres runs-on: ubuntu-latest steps: - name: Check out the repository @@ -95,11 +95,10 @@ jobs: REDSHIFT_TEST_DBNAME: ${{ secrets.REDSHIFT_TEST_DBNAME }} REDSHIFT_TEST_PORT: ${{ secrets.REDSHIFT_TEST_PORT }} with: - dbt-target: redshift - database-adapter-package: dbt-redshift + dbt_target: redshift bigquery: - # needs: postgres + needs: postgres runs-on: ubuntu-latest steps: - name: Check out the repository @@ -119,11 +118,10 @@ jobs: KEYFILE_PATH=$HOME/.dbt/bigquery-service-key.json echo $BIGQUERY_TEST_SERVICE_ACCOUNT_JSON > $KEYFILE_PATH echo ::set-output name=path::$KEYFILE_PATH - - uses: ./.github/actions/end-to-end-test env: BIGQUERY_SERVICE_KEY_PATH: ${{ steps.keyfile.outputs.path }} BIGQUERY_TEST_DATABASE: ${{ secrets.BIGQUERY_TEST_DATABASE }} + BIGQUERY_TEST_PROJECT: ${{ secrets.BIGQUERY_TEST_PROJECT }} with: - dbt-target: bigquery - database-adapter-package: dbt-bigquery + dbt_target: bigquery \ No newline at end of file diff --git a/.gitignore b/.gitignore index 1acc9569..d8a4a81e 100644 --- a/.gitignore +++ b/.gitignore @@ -5,4 +5,11 @@ dbt_packages/ logs/ .DS_Store integration_tests/target -model_testing/ \ No newline at end of file +model_testing/ +test.env +env/ +.venv +venv/ +.env +__pycache__ +.pytest_cache \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ef2f067e..777b9dfc 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -90,6 +90,70 @@ If you are a member of the `dbt-labs` GitHub organization, you will have push ac When you create a Pull Request (below), integration tests will automatically run. When you add new functionality or change existing functionality, please also add new tests to ensure that the project remains resilient. +## Testing locally + +### Initial setup + +Postgres offers the easiest way to test most functionality today. To run the Postgres integration tests, you'll have to do one extra step of setting up the test database: + +```shell +docker-compose up -d database +``` + +### Virtual environment + +If you are using a shell other than `zsh` or `bash`, you will need to [adjust the `activate` commands](https://docs.python.org/3/library/venv.html) below accordingly. + +
+ Platform-specific instructions for venv activation + +| **Platform** | **Shell** | **Command to activate virtual environment** | +|--------------|-----------------|---------------------------------------------| +| POSIX | bash/zsh | `$ source env/bin/activate` | +| | fish | `$ source env/bin/activate.fish` | +| | csh/tcsh | `$ source env/bin/activate.csh` | +| | PowerShell Core | `$ env/bin/Activate.ps1` | +| Windows | cmd.exe | `C:\> env\Scripts\activate.bat` | +| | PowerShell | `PS C:\> env\Scripts\Activate.ps1` | + +
+ +```shell +python -m venv env +source env/bin/activate +python3 -m pip install --upgrade pip +python3 -m pip install --pre -r dev-requirements.txt +source env/bin/activate +``` + +You can run integration tests "locally" by configuring a `test.env` file with appropriate environment variables. + +``` +cp test.env.example test.env +$EDITOR test.env +``` + +WARNING: The `test.env` file you create is `.gitignore`'d, but please be _extra_ careful to never check in credentials or other sensitive information when developing. + +### Test commands + +There are many options for invoking `pytest` and choosing which tests to execute. See [here](https://docs.pytest.org/usage.html) for the `pytest` documentation. Some common options are included below. + +#### Run all the tests +```shell +python3 -m pytest +``` + +#### Run tests in a module +```shell +python3 -m pytest tests/functional/example/test_example_failing_test.py +``` + +#### Run tests in a directory +```shell +python3 -m pytest tests/functional +``` + ## Submitting a Pull Request A `dbt_metrics` maintainer will review your PR. They may suggest code revision for style or clarity, or request that you add unit or integration test(s). These are good things! We believe that, with a little bit of help, anyone can contribute high-quality code. diff --git a/dev-requirements.txt b/dev-requirements.txt index de51dffe..099cd559 100644 --- a/dev-requirements.txt +++ b/dev-requirements.txt @@ -1,4 +1,17 @@ -git+https://github.com/dbt-labs/dbt-redshift.git@c35865b -git+https://github.com/dbt-labs/dbt-snowflake.git@a017382 -git+https://github.com/dbt-labs/dbt-bigquery.git@d52222e -git+https://github.com/dbt-labs/dbt-core.git@0db634d#egg=dbt-core&subdirectory=core \ No newline at end of file +pytest +pytest-dotenv + +# Bleeding edge +# git+https://github.com/dbt-labs/dbt-core.git@main#egg=dbt-tests-adapter&subdirectory=tests/adapter +# git+https://github.com/dbt-labs/dbt-core.git@main#egg=dbt-core&subdirectory=core +# git+https://github.com/dbt-labs/dbt-core.git@main#egg=dbt-postgres&subdirectory=plugins/postgres +# git+https://github.com/dbt-labs/dbt-redshift.git +# git+https://github.com/dbt-labs/dbt-snowflake.git +# git+https://github.com/dbt-labs/dbt-bigquery.git + +# Most recent release candidates +dbt-tests-adapter==1.2.0 +dbt-core==1.2.0 +dbt-redshift==1.2.0 +dbt-snowflake==1.2.0 +dbt-bigquery==1.2.0 \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 00000000..2e720ded --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,14 @@ +version: "3.5" +services: + database: + image: postgres + environment: + POSTGRES_USER: "root" + POSTGRES_PASSWORD: "password" + POSTGRES_DB: "dbt" + ports: + - "5432:5432" + +networks: + default: + name: dbt-net \ No newline at end of file diff --git a/integration_tests/dbt_project.yml b/integration_tests/dbt_project.yml index 780c92c9..47e084ba 100644 --- a/integration_tests/dbt_project.yml +++ b/integration_tests/dbt_project.yml @@ -6,7 +6,7 @@ version: "1.0.0" config-version: 2 # This setting configures which "profile" dbt uses for this project. -profile: "dbt_metrics_integration_tests" +profile: "dbt_metrics_integration_tests_bigquery" model-paths: ["models"] analysis-paths: ["analyses"] diff --git a/integration_tests/models/metric_definitions/base_average_metric.yml b/integration_tests/models/metric_definitions/base_average_metric.yml index c3be1605..86a631d2 100644 --- a/integration_tests/models/metric_definitions/base_average_metric.yml +++ b/integration_tests/models/metric_definitions/base_average_metric.yml @@ -4,7 +4,7 @@ metrics: model: ref('fact_orders') label: Total Discount ($) timestamp: order_date - time_grains: [day, week] + time_grains: [day, week, month] type: average sql: discount_total dimensions: diff --git a/integration_tests/models/metric_definitions/base_count_metric.yml b/integration_tests/models/metric_definitions/base_count_metric.yml index ee70daa9..69b8c2cb 100644 --- a/integration_tests/models/metric_definitions/base_count_metric.yml +++ b/integration_tests/models/metric_definitions/base_count_metric.yml @@ -1,14 +1,12 @@ version: 2 metrics: - - name: base_count_metric - label: Members of Community Slack - model: ref('seed_slack_users') - - type: count - sql: "*" - timestamp: joined_at - time_grains: [day, week, month] - - dimensions: - - is_active_past_quarter - - has_messaged \ No newline at end of file + - name: base_count_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: count + sql: order_total + dimensions: + - had_discount + - order_country \ No newline at end of file diff --git a/integration_tests/models/metric_definitions/base_sum_metric.yml b/integration_tests/models/metric_definitions/base_sum_metric.yml index 023e2094..fb1f8c4f 100644 --- a/integration_tests/models/metric_definitions/base_sum_metric.yml +++ b/integration_tests/models/metric_definitions/base_sum_metric.yml @@ -4,7 +4,7 @@ metrics: model: ref('fact_orders') label: Order Total ($) timestamp: order_date - time_grains: [day, week] + time_grains: [day, week,month] type: sum sql: order_total dimensions: diff --git a/integration_tests/models/metric_definitions/expression_metric.yml b/integration_tests/models/metric_definitions/expression_metric.yml index 810d04ef..201df43f 100644 --- a/integration_tests/models/metric_definitions/expression_metric.yml +++ b/integration_tests/models/metric_definitions/expression_metric.yml @@ -14,7 +14,7 @@ metrics: - name: ratio_metric label: Ratio ($) timestamp: order_date - time_grains: [day, week] + time_grains: [day, week,month] type: expression sql: "{{metric('base_sum_metric')}} / {{metric('base_average_metric')}}" dimensions: diff --git a/integration_tests/models/metric_testing_models/base_average_metric.sql b/integration_tests/models/metric_testing_models/base_average_metric.sql index 0f403362..3cb3767c 100644 --- a/integration_tests/models/metric_testing_models/base_average_metric.sql +++ b/integration_tests/models/metric_testing_models/base_average_metric.sql @@ -1,6 +1,6 @@ select * from {{ metrics.calculate(metric('base_average_metric'), - grain='day', + grain='month', dimensions=['had_discount']) }} \ No newline at end of file diff --git a/integration_tests/models/metric_testing_models/base_count_distinct_metric.sql b/integration_tests/models/metric_testing_models/base_count_distinct_metric.sql new file mode 100644 index 00000000..4248dbdf --- /dev/null +++ b/integration_tests/models/metric_testing_models/base_count_distinct_metric.sql @@ -0,0 +1,6 @@ +select * +from +{{ metrics.calculate(metric('base_count_distinct_metric'), + grain='month' + ) +}} \ No newline at end of file diff --git a/integration_tests/models/metric_testing_models/base_count_distinct_metric.yml b/integration_tests/models/metric_testing_models/base_count_distinct_metric.yml new file mode 100644 index 00000000..8fc500dd --- /dev/null +++ b/integration_tests/models/metric_testing_models/base_count_distinct_metric.yml @@ -0,0 +1,18 @@ +version: 2 +models: + - name: base_count_distinct_metric + tests: + - dbt_utils.equality: + compare_model: ref('base_count_distinct_metric__expected') + +metrics: + - name: base_count_distinct_metric + model: ref('fact_orders') + label: Count Distinct + timestamp: order_date + time_grains: [day, week, month] + type: count_distinct + sql: customer_id + dimensions: + - had_discount + - order_country \ No newline at end of file diff --git a/integration_tests/models/metric_testing_models/base_count_metric__no_end_date.sql b/integration_tests/models/metric_testing_models/base_count_metric__no_end_date.sql index 9cb0befa..65e1fa05 100644 --- a/integration_tests/models/metric_testing_models/base_count_metric__no_end_date.sql +++ b/integration_tests/models/metric_testing_models/base_count_metric__no_end_date.sql @@ -3,7 +3,6 @@ from {{ metrics.calculate( metric('base_count_metric'), grain='month', - dimensions=['has_messaged','is_active_past_quarter'], start_date = '2021-02-01' ) }} \ No newline at end of file diff --git a/integration_tests/models/metric_testing_models/base_count_metric__no_start_date.sql b/integration_tests/models/metric_testing_models/base_count_metric__no_start_date.sql index 37e25c03..9a30a971 100644 --- a/integration_tests/models/metric_testing_models/base_count_metric__no_start_date.sql +++ b/integration_tests/models/metric_testing_models/base_count_metric__no_start_date.sql @@ -3,7 +3,6 @@ from {{ metrics.calculate( metric('base_count_metric'), grain='month', - dimensions=['has_messaged','is_active_past_quarter'], end_date = '2021-03-01' ) }} \ No newline at end of file diff --git a/integration_tests/models/metric_testing_models/base_count_metric__secondary_calculations.sql b/integration_tests/models/metric_testing_models/base_count_metric__secondary_calculations.sql index 20078a67..905e6529 100644 --- a/integration_tests/models/metric_testing_models/base_count_metric__secondary_calculations.sql +++ b/integration_tests/models/metric_testing_models/base_count_metric__secondary_calculations.sql @@ -3,7 +3,6 @@ from {{ metrics.calculate( metric('base_count_metric'), grain='month', - dimensions=['has_messaged','is_active_past_quarter'], start_date = '2021-01-01', end_date = '2021-04-01', secondary_calculations=[ diff --git a/integration_tests/models/metric_testing_models/ratio_metric.sql b/integration_tests/models/metric_testing_models/ratio_metric.sql index 41d610c0..fc230899 100644 --- a/integration_tests/models/metric_testing_models/ratio_metric.sql +++ b/integration_tests/models/metric_testing_models/ratio_metric.sql @@ -1,9 +1,6 @@ select * from -{{ metrics.calculate( - metric('ratio_metric'), - grain='day', - dimensions=['had_discount','order_country','is_weekend'], - start_date = '2022-01-01', - end_date = '2022-01-10') +{{ metrics.calculate(metric('ratio_metric'), + grain='month' + ) }} \ No newline at end of file diff --git a/integration_tests/models/metric_testing_models/testing_metrics.sql b/integration_tests/models/metric_testing_models/testing_metrics.sql new file mode 100644 index 00000000..0322c690 --- /dev/null +++ b/integration_tests/models/metric_testing_models/testing_metrics.sql @@ -0,0 +1,6 @@ +select * +from +{{ metrics.calculate(metric('base_count_metric'), + grain='week' + ) +}} \ No newline at end of file diff --git a/integration_tests/seeds/expected/base_average_metric__expected.csv b/integration_tests/seeds/expected/base_average_metric__expected.csv index fabba4a9..0ffc1f53 100644 --- a/integration_tests/seeds/expected/base_average_metric__expected.csv +++ b/integration_tests/seeds/expected/base_average_metric__expected.csv @@ -1,303 +1,5 @@ -date_day,had_discount,base_average_metric -2022-01-01,FALSE,19.500000 -2022-01-01,TRUE,8.000000 -2022-01-02,FALSE,28.857143 -2022-01-02,TRUE,27.000000 -2022-01-03,FALSE,19.000000 -2022-01-03,TRUE,0.000000 -2022-01-05,FALSE,28.625000 -2022-01-06,FALSE,27.666667 -2022-01-07,FALSE,39.500000 -2022-01-07,TRUE,39.666667 -2022-01-08,FALSE,28.714286 -2022-01-08,TRUE,12.666667 -2022-01-09,TRUE,21.800000 -2022-01-10,FALSE,27.400000 -2022-01-10,TRUE,17.200000 -2022-01-11,TRUE,26.250000 -2022-01-14,FALSE,11.000000 -2022-01-14,TRUE,15.125000 -2022-01-17,FALSE,39.000000 -2022-01-18,FALSE,27.750000 -2022-01-19,TRUE,28.666667 -2022-01-21,TRUE,7.500000 -2022-01-22,TRUE,29.500000 -2022-01-25,TRUE,23.000000 -2022-01-26,FALSE,28.666667 -2022-01-27,FALSE,33.400000 -2022-01-31,FALSE,20.600000 -2022-02-06,TRUE,31.500000 -2022-02-07,FALSE,39.000000 -2022-02-23,TRUE,0.000000 -2022-02-24,TRUE,42.333333 -2022-03-12,FALSE,21.000000 -2022-04-04,FALSE,22.666667 -2022-01-04,TRUE,17.500000 -2022-01-13,TRUE,42.333333 -2022-01-16,FALSE,19.200000 -2022-02-13,TRUE,26.600000 -2022-02-22,TRUE,40.666667 -2022-02-26,FALSE,0.000000 -2022-01-05,TRUE,39.000000 -2022-01-15,FALSE,30.333333 -2022-01-15,TRUE,28.000000 -2022-01-19,FALSE,29.666667 -2022-01-23,TRUE,18.000000 -2022-01-24,TRUE,11.000000 -2022-01-25,FALSE,3.000000 -2022-02-11,TRUE,30.000000 -2022-02-14,FALSE,0.000000 -2022-02-28,TRUE,43.333333 -2022-03-03,TRUE,29.500000 -2022-03-08,TRUE,16.800000 -2022-03-16,FALSE,35.000000 -2022-03-21,FALSE,34.500000 -2022-02-08,FALSE,24.142857 -2022-02-17,TRUE,46.500000 -2022-04-08,TRUE,36.857143 -2022-04-15,FALSE,0.000000 -2022-04-15,TRUE,23.250000 -2022-04-20,FALSE,27.500000 -2022-01-27,TRUE,28.000000 -2022-03-19,TRUE,30.000000 -2022-05-06,FALSE,32.000000 -2022-04-03,TRUE,17.000000 -2022-05-21,TRUE,29.333333 -2022-01-06,TRUE,20.000000 -2022-01-09,FALSE,17.000000 -2022-01-22,FALSE,28.500000 -2022-01-28,TRUE,19.000000 -2022-01-30,TRUE,23.500000 -2022-01-31,TRUE,31.500000 -2022-02-04,TRUE,10.000000 -2022-02-05,FALSE,11.333333 -2022-02-11,FALSE,16.500000 -2022-02-14,TRUE,16.250000 -2022-02-19,FALSE,21.000000 -2022-02-24,FALSE,27.000000 -2022-03-02,TRUE,18.000000 -2022-05-14,FALSE,27.500000 -2022-02-16,TRUE,39.000000 -2022-02-20,FALSE,23.200000 -2022-02-21,TRUE,16.250000 -2022-04-06,TRUE,21.000000 -2022-04-13,TRUE,21.000000 -2022-04-19,TRUE,14.500000 -2022-04-20,TRUE,25.000000 -2022-04-10,TRUE,0.000000 -2022-01-17,TRUE,29.500000 -2022-01-18,TRUE,24.333333 -2022-01-20,FALSE,41.666667 -2022-01-20,TRUE,20.500000 -2022-01-26,TRUE,9.333333 -2022-01-30,FALSE,31.000000 -2022-02-01,FALSE,40.500000 -2022-02-06,FALSE,20.666667 -2022-02-07,TRUE,12.750000 -2022-02-19,TRUE,27.000000 -2022-02-25,TRUE,19.250000 -2022-03-08,FALSE,28.250000 -2022-03-11,TRUE,30.000000 -2022-03-13,FALSE,30.500000 -2022-03-19,FALSE,25.000000 -2022-03-23,TRUE,26.000000 -2022-04-04,TRUE,14.500000 -2022-04-12,FALSE,30.333333 -2022-04-12,TRUE,17.500000 -2022-04-27,FALSE,32.333333 -2022-05-02,FALSE,23.000000 -2022-05-28,TRUE,11.333333 -2022-01-12,TRUE,22.400000 -2022-01-16,TRUE,0.000000 -2022-02-08,TRUE,29.000000 -2022-02-16,FALSE,15.000000 -2022-02-26,TRUE,24.600000 -2022-03-01,FALSE,16.000000 -2022-03-01,TRUE,25.666667 -2022-03-18,FALSE,41.333333 -2022-03-18,TRUE,18.666667 -2022-03-29,FALSE,24.500000 -2022-03-29,TRUE,16.000000 -2022-03-31,FALSE,34.000000 -2022-03-31,TRUE,22.750000 -2022-04-07,FALSE,25.600000 -2022-04-22,TRUE,17.500000 -2022-04-23,FALSE,21.250000 -2022-04-25,FALSE,30.666667 -2022-02-03,TRUE,38.285714 -2022-02-18,FALSE,38.000000 -2022-03-20,FALSE,26.000000 -2022-04-01,FALSE,24.625000 -2022-04-24,FALSE,4.000000 -2022-05-17,FALSE,13.666667 -2022-05-24,TRUE,22.250000 -2022-01-29,FALSE,27.000000 -2022-02-01,TRUE,30.000000 -2022-02-05,TRUE,22.000000 -2022-02-23,FALSE,7.000000 -2022-02-28,FALSE,33.333333 -2022-03-02,FALSE,23.000000 -2022-03-03,FALSE,39.250000 -2022-03-11,FALSE,11.000000 -2022-03-16,TRUE,33.666667 -2022-05-06,TRUE,46.000000 -2022-05-18,TRUE,29.000000 -2022-02-12,FALSE,23.200000 -2022-02-15,TRUE,21.400000 -2022-02-20,TRUE,39.800000 -2022-03-17,FALSE,22.500000 -2022-03-22,FALSE,26.500000 -2022-03-30,TRUE,22.000000 -2022-04-17,FALSE,29.000000 -2022-04-21,TRUE,14.000000 -2022-04-25,TRUE,22.400000 -2022-04-29,TRUE,6.333333 -2022-05-03,FALSE,22.000000 -2022-05-04,FALSE,27.166667 -2022-05-13,TRUE,29.000000 -2022-05-16,FALSE,31.600000 -2022-05-16,TRUE,0.000000 -2022-05-20,TRUE,23.200000 -2022-05-22,FALSE,28.000000 -2022-02-10,FALSE,22.000000 -2022-03-25,TRUE,23.666667 -2022-04-05,FALSE,25.000000 -2022-05-30,FALSE,16.666667 -2022-04-10,FALSE,19.125000 -2022-03-15,FALSE,31.500000 -2022-05-26,TRUE,7.000000 -2022-05-29,FALSE,4.000000 -2022-05-07,FALSE,26.333333 -2022-01-11,FALSE,15.000000 -2022-01-23,FALSE,18.500000 -2022-01-24,FALSE,32.000000 -2022-01-28,FALSE,28.500000 -2022-01-29,TRUE,11.000000 -2022-02-25,FALSE,39.500000 -2022-03-04,FALSE,25.250000 -2022-03-12,TRUE,7.000000 -2022-03-21,TRUE,26.250000 -2022-05-02,TRUE,36.500000 -2022-01-04,FALSE,29.500000 -2022-01-13,FALSE,40.000000 -2022-02-15,FALSE,23.800000 -2022-02-17,FALSE,42.500000 -2022-02-22,FALSE,21.428571 -2022-02-27,TRUE,35.750000 -2022-03-06,FALSE,19.000000 -2022-03-30,FALSE,27.000000 -2022-04-03,FALSE,23.666667 -2022-04-13,FALSE,14.750000 -2022-04-19,FALSE,6.000000 -2022-04-28,TRUE,34.666667 -2022-04-30,TRUE,28.500000 -2022-05-01,TRUE,7.000000 -2022-05-08,FALSE,21.500000 -2022-05-08,TRUE,34.500000 -2022-05-15,FALSE,25.000000 -2022-03-07,FALSE,26.333333 -2022-03-07,TRUE,14.000000 -2022-03-24,TRUE,20.000000 -2022-04-14,FALSE,32.000000 -2022-04-14,TRUE,0.000000 -2022-05-07,TRUE,34.600000 -2022-03-27,TRUE,26.000000 -2022-02-04,FALSE,17.250000 -2022-03-13,TRUE,27.250000 -2022-05-28,FALSE,19.600000 -2022-01-12,FALSE,26.500000 -2022-02-02,FALSE,35.250000 -2022-02-02,TRUE,25.200000 -2022-02-09,FALSE,25.333333 -2022-02-13,FALSE,31.000000 -2022-02-21,FALSE,1.000000 -2022-02-27,FALSE,26.000000 -2022-03-05,FALSE,29.333333 -2022-03-06,TRUE,16.000000 -2022-03-14,TRUE,15.000000 -2022-03-15,TRUE,41.333333 -2022-03-22,TRUE,30.000000 -2022-03-26,FALSE,25.000000 -2022-03-26,TRUE,19.000000 -2022-03-28,FALSE,22.250000 -2022-04-06,FALSE,26.000000 -2022-04-08,FALSE,22.666667 -2022-04-17,TRUE,26.666667 -2022-04-18,TRUE,25.000000 -2022-04-22,FALSE,34.500000 -2022-04-23,TRUE,23.166667 -2022-04-29,FALSE,40.250000 -2022-04-30,FALSE,10.000000 -2022-05-01,FALSE,11.000000 -2022-05-04,TRUE,31.200000 -2022-05-09,FALSE,21.400000 -2022-05-09,TRUE,26.000000 -2022-05-11,FALSE,27.500000 -2022-05-12,FALSE,25.800000 -2022-05-12,TRUE,24.500000 -2022-05-23,FALSE,29.500000 -2022-05-23,TRUE,24.000000 -2022-05-26,FALSE,34.571429 -2022-05-29,TRUE,46.000000 -2022-02-03,FALSE,0.000000 -2022-02-18,TRUE,22.666667 -2022-03-09,TRUE,16.000000 -2022-03-20,TRUE,28.000000 -2022-03-24,FALSE,21.666667 -2022-03-25,FALSE,31.750000 -2022-04-01,TRUE,15.250000 -2022-04-02,FALSE,36.714286 -2022-04-02,TRUE,29.600000 -2022-04-09,FALSE,22.750000 -2022-04-11,FALSE,11.000000 -2022-04-16,TRUE,24.666667 -2022-04-24,TRUE,20.666667 -2022-05-10,FALSE,17.333333 -2022-05-10,TRUE,32.500000 -2022-05-19,FALSE,26.666667 -2022-05-25,TRUE,40.000000 -2022-05-30,TRUE,19.000000 -2022-03-10,FALSE,42.500000 -2022-05-27,TRUE,22.250000 -2022-03-04,TRUE,23.000000 -2022-04-27,TRUE,41.333333 -2022-02-09,TRUE,28.333333 -2022-02-12,TRUE,24.250000 -2022-03-05,TRUE,20.750000 -2022-03-28,TRUE,34.333333 -2022-04-18,FALSE,31.750000 -2022-04-21,FALSE,16.666667 -2022-05-03,TRUE,23.750000 -2022-05-15,TRUE,24.166667 -2022-03-09,FALSE,29.500000 -2022-05-05,FALSE,0.000000 -2022-05-17,TRUE,24.800000 -2022-05-31,FALSE,18.333333 -2022-03-10,TRUE,19.400000 -2022-05-24,FALSE,7.500000 -2022-03-14,FALSE,32.000000 -2022-04-05,TRUE,29.000000 -2022-05-27,FALSE,40.000000 -2022-01-21,FALSE,28.333333 -2022-04-07,TRUE,7.500000 -2022-04-26,TRUE,34.000000 -2022-03-23,FALSE,30.000000 -2022-05-14,TRUE,14.666667 -2022-05-18,FALSE,22.400000 -2022-03-17,TRUE,0.000000 -2022-04-28,FALSE,33.000000 -2022-05-11,TRUE,19.000000 -2022-02-10,TRUE,22.250000 -2022-04-09,TRUE,24.666667 -2022-04-16,FALSE,33.750000 -2022-04-26,FALSE,32.666667 -2022-05-05,TRUE,0.000000 -2022-05-19,TRUE,26.833333 -2022-05-21,FALSE,32.000000 -2022-05-25,FALSE,17.500000 -2022-05-13,FALSE,15.666667 -2022-05-22,TRUE,11.000000 -2022-05-31,TRUE,31.000000 -2022-03-27,FALSE,0.000000 -2022-04-11,TRUE,29.000000 -2022-05-20,FALSE,19.600000 \ No newline at end of file +date_month,had_discount,base_average_metric +2022-01-01,TRUE,1.00000000000000000000 +2022-01-01,FALSE,1.00000000000000000000 +2022-02-01,FALSE,1.00000000000000000000 +2022-02-01,TRUE,1.00000000000000000000 \ No newline at end of file diff --git a/integration_tests/seeds/expected/ratio_metric__expected.csv b/integration_tests/seeds/expected/ratio_metric__expected.csv new file mode 100644 index 00000000..8cd89f59 --- /dev/null +++ b/integration_tests/seeds/expected/ratio_metric__expected.csv @@ -0,0 +1,3 @@ +date_month,base_sum_metric,base_average_metric,ratio_metric +2022-02-01,2,1.00000000000000000000,2.00000000000000000000 +2022-01-01,8,1.00000000000000000000,8.00000000000000000000 \ No newline at end of file diff --git a/integration_tests/seeds/source/dim_customers_source.csv b/integration_tests/seeds/source/dim_customers_source.csv index c572f590..e7fa6315 100644 --- a/integration_tests/seeds/source/dim_customers_source.csv +++ b/integration_tests/seeds/source/dim_customers_source.csv @@ -1,1001 +1,6 @@ -customer_id,first_name,last_name,email,gender,is_new_customer -1,Benjie,Hills,bhills0@altervista.org,Male,FALSE -2,Myron,Coxhead,mcoxhead1@symantec.com,Genderfluid,TRUE -3,Arleen,Redish,aredish2@last.fm,Genderqueer,FALSE -4,Lona,Basant,lbasant3@dedecms.com,Female,TRUE -5,Alix,O'Kennavain,aokennavain4@smugmug.com,Female,TRUE -6,Lia,MacAfee,lmacafee5@ted.com,Agender,TRUE -7,Maximilien,Pinor,mpinor6@imgur.com,Male,TRUE -8,Tamqrah,Ace,tace7@sitemeter.com,Female,TRUE -9,Quincey,Salamon,qsalamon8@buzzfeed.com,Male,TRUE -10,Adan,Kelemen,akelemen9@angelfire.com,Male,FALSE -11,Briggs,Swetenham,bswetenhama@usgs.gov,Male,TRUE -12,Charil,Sacher,csacherb@biblegateway.com,Female,FALSE -13,Sheela,Schubart,sschubartc@kickstarter.com,Female,TRUE -14,Zora,Ellis,zellisd@paginegialle.it,Female,FALSE -15,Zachary,Hawley,zhawleye@eepurl.com,Non-binary,TRUE -16,Sheena,Kynd,skyndf@zimbio.com,Female,FALSE -17,Robby,Panner,rpannerg@blogspot.com,Female,TRUE -18,Annie,Sange,asangeh@tinypic.com,Female,FALSE -19,Aron,Dayes,adayesi@cdbaby.com,Male,TRUE -20,Margeaux,Redparth,mredparthj@pen.io,Female,FALSE -21,Haily,Colquhoun,hcolquhounk@ask.com,Female,TRUE -22,Todd,De Paepe,tdepaepel@gizmodo.com,Male,FALSE -23,Rhianna,Birkwood,rbirkwoodm@histats.com,Female,FALSE -24,Morgun,Minifie,mminifien@scribd.com,Male,FALSE -25,Fletch,Brocklesby,fbrocklesbyo@google.nl,Genderqueer,TRUE -26,Tana,Signoret,tsignoretp@china.com.cn,Female,FALSE -27,Nike,Steuhlmeyer,nsteuhlmeyerq@adobe.com,Female,TRUE -28,Gussie,Gerred,ggerredr@stanford.edu,Female,TRUE -29,Willi,Erangy,werangys@cbc.ca,Female,FALSE -30,Estella,Oakey,eoakeyt@walmart.com,Female,FALSE -31,Ruperto,Tolson,rtolsonu@apple.com,Male,FALSE -32,Zach,McEvoy,zmcevoyv@imgur.com,Male,TRUE -33,Clevey,Raybould,craybouldw@liveinternet.ru,Male,FALSE -34,Ruthanne,Joint,rjointx@wufoo.com,Female,FALSE -35,Tana,Neath,tneathy@icq.com,Female,FALSE -36,Currey,Stonebridge,cstonebridgez@jimdo.com,Male,FALSE -37,Cory,Hanselman,chanselman10@dot.gov,Male,FALSE -38,Lonnie,Fenners,lfenners11@etsy.com,Male,FALSE -39,Barnabe,Pascall,bpascall12@noaa.gov,Male,TRUE -40,Urbanus,Sharpless,usharpless13@nytimes.com,Male,FALSE -41,Brett,McIsaac,bmcisaac14@smh.com.au,Male,TRUE -42,Kristi,Boon,kboon15@t.co,Female,TRUE -43,Joy,Deeley,jdeeley16@answers.com,Female,TRUE -44,Maje,Mayho,mmayho17@netscape.com,Male,TRUE -45,Carolin,Wycliff,cwycliff18@toplist.cz,Female,TRUE -46,Kevin,New,knew19@devhub.com,Bigender,TRUE -47,Crawford,Denson,cdenson1a@ask.com,Male,FALSE -48,Orson,Moriarty,omoriarty1b@ovh.net,Male,TRUE -49,Mohandas,Telezhkin,mtelezhkin1c@comcast.net,Male,FALSE -50,Dannye,Coyne,dcoyne1d@bandcamp.com,Female,FALSE -51,Felicia,Mollindinia,fmollindinia1e@nba.com,Female,FALSE -52,Angy,Cunde,acunde1f@furl.net,Female,FALSE -53,Wynny,Latore,wlatore1g@bigcartel.com,Female,TRUE -54,Edouard,Stops,estops1h@yandex.ru,Male,FALSE -55,Rosemaria,Pakeman,rpakeman1i@foxnews.com,Female,FALSE -56,Wyn,Harly,wharly1j@rakuten.co.jp,Genderqueer,TRUE -57,Eryn,Mayoh,emayoh1k@webnode.com,Female,FALSE -58,Ellette,Bidewel,ebidewel1l@qq.com,Female,TRUE -59,Drucill,Horley,dhorley1m@php.net,Female,TRUE -60,Ellery,Growy,egrowy1n@paginegialle.it,Male,TRUE -61,Otha,Cowdry,ocowdry1o@cdbaby.com,Female,TRUE -62,Farrand,Nathan,fnathan1p@craigslist.org,Female,TRUE -63,Alleen,Croux,acroux1q@cloudflare.com,Female,FALSE -64,Joey,Batie,jbatie1r@sciencedirect.com,Male,TRUE -65,Nevin,Antoshin,nantoshin1s@google.co.uk,Male,TRUE -66,Mack,Malthouse,mmalthouse1t@ibm.com,Male,TRUE -67,Christal,Connow,cconnow1u@seattletimes.com,Agender,TRUE -68,Modesty,Sweeting,msweeting1v@shinystat.com,Female,TRUE -69,Rem,Weaver,rweaver1w@businessinsider.com,Male,FALSE -70,Donni,Pursehouse,dpursehouse1x@phpbb.com,Female,TRUE -71,Molly,Oven,moven1y@ning.com,Female,FALSE -72,Polly,Doidge,pdoidge1z@blog.com,Female,FALSE -73,Brett,Jenkison,bjenkison20@boston.com,Male,TRUE -74,Brantley,Mateescu,bmateescu21@vinaora.com,Male,TRUE -75,Darelle,Piquard,dpiquard22@last.fm,Female,TRUE -76,Carley,Beynkn,cbeynkn23@sbwire.com,Female,FALSE -77,Trumann,Shevelin,tshevelin24@twitpic.com,Male,FALSE -78,Christin,Peschke,cpeschke25@princeton.edu,Bigender,TRUE -79,Ronny,Ricardo,rricardo26@unc.edu,Male,FALSE -80,Velma,Kinglake,vkinglake27@shop-pro.jp,Female,TRUE -81,Burnaby,Domange,bdomange28@issuu.com,Genderqueer,TRUE -82,Conrad,Shepherdson,cshepherdson29@shop-pro.jp,Male,FALSE -83,Gusty,D'Adamo,gdadamo2a@nytimes.com,Female,TRUE -84,Jasper,Hughill,jhughill2b@yale.edu,Male,TRUE -85,Maxy,Gorsse,mgorsse2c@is.gd,Female,TRUE -86,Magdalen,Iggalden,miggalden2d@free.fr,Female,TRUE -87,Ky,Rosenfrucht,krosenfrucht2e@xing.com,Male,TRUE -88,Konstantin,Warrillow,kwarrillow2f@cbsnews.com,Male,FALSE -89,Neale,Lindholm,nlindholm2g@twitpic.com,Male,TRUE -90,Felicia,Shadrach,fshadrach2h@ted.com,Female,FALSE -91,Orly,Baynard,obaynard2i@nationalgeographic.com,Bigender,TRUE -92,Vicky,Kroll,vkroll2j@vk.com,Female,TRUE -93,Goddard,Freyn,gfreyn2k@nps.gov,Male,TRUE -94,Gerhardine,Malamore,gmalamore2l@apple.com,Female,TRUE -95,Vachel,Blindmann,vblindmann2m@123-reg.co.uk,Male,FALSE -96,Sheba,Dumberell,sdumberell2n@elegantthemes.com,Female,TRUE -97,Yancy,Close,yclose2o@posterous.com,Male,FALSE -98,Jess,Chaloner,jchaloner2p@weibo.com,Male,FALSE -99,Archibaldo,Manford,amanford2q@ning.com,Male,TRUE -100,Pamelina,Kielt,pkielt2r@infoseek.co.jp,Female,FALSE -101,Pauli,Jell,pjell2s@un.org,Female,FALSE -102,Melinde,Grishankov,mgrishankov2t@facebook.com,Female,TRUE -103,Phillipe,Newling,pnewling2u@mysql.com,Male,TRUE -104,Sigismund,Gartin,sgartin2v@tripadvisor.com,Male,FALSE -105,Freddy,Damiral,fdamiral2w@instagram.com,Male,FALSE -106,Minor,Hutfield,mhutfield2x@umn.edu,Agender,FALSE -107,Abbie,Dancer,adancer2y@twitter.com,Male,FALSE -108,Smith,Leppard,sleppard2z@upenn.edu,Male,TRUE -109,Mada,Digman,mdigman30@bloglines.com,Female,FALSE -110,Natividad,Antognazzi,nantognazzi31@statcounter.com,Female,FALSE -111,Noelani,Mully,nmully32@hc360.com,Female,FALSE -112,Markus,Dargue,mdargue33@dropbox.com,Male,FALSE -113,Ammamaria,Noor,anoor34@simplemachines.org,Female,FALSE -114,Obadiah,Fearnside,ofearnside35@hatena.ne.jp,Male,TRUE -115,Madalyn,Scay,mscay36@columbia.edu,Female,TRUE -116,Francisca,Avison,favison37@geocities.com,Female,FALSE -117,Giuditta,Leneve,gleneve38@indiatimes.com,Female,TRUE -118,Leila,Morson,lmorson39@hc360.com,Female,TRUE -119,Eli,Scott,escott3a@cdbaby.com,Male,FALSE -120,Davita,Umbert,dumbert3b@ebay.co.uk,Female,TRUE -121,Frederic,George,fgeorge3c@ezinearticles.com,Male,FALSE -122,Vasily,Gillie,vgillie3d@wikipedia.org,Male,FALSE -123,Shalom,Lauchlan,slauchlan3e@home.pl,Male,FALSE -124,Lindie,Kenaway,lkenaway3f@ifeng.com,Female,FALSE -125,Geneva,Caughte,gcaughte3g@wikia.com,Female,FALSE -126,Misti,Wincer,mwincer3h@desdev.cn,Female,FALSE -127,Rodolph,Noorwood,rnoorwood3i@reverbnation.com,Male,FALSE -128,Virgil,Denham,vdenham3j@hubpages.com,Male,FALSE -129,Zsazsa,Sacks,zsacks3k@youtube.com,Female,TRUE -130,Larissa,Riddall,lriddall3l@storify.com,Female,TRUE -131,Nicolle,Geal,ngeal3m@latimes.com,Female,TRUE -132,Vinnie,Pashbee,vpashbee3n@github.io,Male,FALSE -133,Corey,Goodrich,cgoodrich3o@liveinternet.ru,Male,FALSE -134,Gaby,Hughman,ghughman3p@livejournal.com,Female,FALSE -135,Ingar,Cissell,icissell3q@eepurl.com,Male,TRUE -136,Eleni,Alcott,ealcott3r@techcrunch.com,Female,TRUE -137,Jeffie,Markushkin,jmarkushkin3s@angelfire.com,Non-binary,FALSE -138,Ciro,Crockford,ccrockford3t@techcrunch.com,Male,TRUE -139,Matthias,Gladdor,mgladdor3u@booking.com,Male,TRUE -140,Reinwald,Simmers,rsimmers3v@huffingtonpost.com,Male,FALSE -141,Bud,Noonan,bnoonan3w@wired.com,Male,TRUE -142,Chad,Loweth,cloweth3x@aol.com,Male,TRUE -143,Cathryn,Johnson,cjohnson3y@ca.gov,Female,FALSE -144,Rochell,Prendiville,rprendiville3z@photobucket.com,Female,FALSE -145,Isaac,Pay,ipay40@constantcontact.com,Male,TRUE -146,Lowe,O'Brallaghan,lobrallaghan41@digg.com,Male,TRUE -147,Catharina,Marns,cmarns42@reference.com,Female,FALSE -148,Effie,Sully,esully43@google.es,Female,FALSE -149,Andi,Borland,aborland44@latimes.com,Female,TRUE -150,Antony,Jozwiak,ajozwiak45@chicagotribune.com,Male,FALSE -151,Hanna,Westmancoat,hwestmancoat46@zimbio.com,Female,TRUE -152,Olivero,Ogglebie,oogglebie47@meetup.com,Male,FALSE -153,Rasia,Lockey,rlockey48@list-manage.com,Female,FALSE -154,Darby,McCully,dmccully49@nih.gov,Female,FALSE -155,Quinton,Saul,qsaul4a@creativecommons.org,Male,FALSE -156,Matty,Mundall,mmundall4b@unc.edu,Male,TRUE -157,Amber,Godmar,agodmar4c@paypal.com,Female,TRUE -158,Jaquelyn,Mityukov,jmityukov4d@list-manage.com,Female,FALSE -159,Reena,Jellicorse,rjellicorse4e@spiegel.de,Female,FALSE -160,Rosalinda,Lebond,rlebond4f@etsy.com,Female,TRUE -161,Averil,Vondrys,avondrys4g@sogou.com,Male,FALSE -162,Dulcinea,Morilla,dmorilla4h@etsy.com,Female,FALSE -163,Yehudit,Farrand,yfarrand4i@soup.io,Male,TRUE -164,Barnabas,Samples,bsamples4j@ucoz.ru,Genderfluid,TRUE -165,Luelle,Myall,lmyall4k@ucla.edu,Female,FALSE -166,Silvia,Aldine,saldine4l@sciencedaily.com,Female,TRUE -167,Josiah,Macbane,jmacbane4m@go.com,Male,FALSE -168,Kyle,Bondar,kbondar4n@sogou.com,Male,FALSE -169,Alva,Pobjoy,apobjoy4o@vistaprint.com,Male,FALSE -170,Jasen,Whawell,jwhawell4p@geocities.jp,Male,TRUE -171,Kearney,Punyer,kpunyer4q@studiopress.com,Male,FALSE -172,Wenona,Siemons,wsiemons4r@people.com.cn,Non-binary,FALSE -173,Sibbie,Ickowics,sickowics4s@umn.edu,Female,TRUE -174,Irving,Valentinuzzi,ivalentinuzzi4t@drupal.org,Male,TRUE -175,Parry,Ham,pham4u@jugem.jp,Male,TRUE -176,Xever,Shakesby,xshakesby4v@icio.us,Male,TRUE -177,Hagen,Orys,horys4w@arstechnica.com,Male,FALSE -178,Hyacinth,Bearne,hbearne4x@dell.com,Female,TRUE -179,Lucine,Jeffree,ljeffree4y@nba.com,Female,FALSE -180,Taylor,Lange,tlange4z@phoca.cz,Male,FALSE -181,Kristofor,Fysh,kfysh50@edublogs.org,Male,TRUE -182,Symon,Isgar,sisgar51@slideshare.net,Male,TRUE -183,Adelice,Currm,acurrm52@spotify.com,Female,FALSE -184,Armin,Vizor,avizor53@photobucket.com,Male,TRUE -185,Gavan,Grinishin,ggrinishin54@comcast.net,Male,TRUE -186,Doroteya,Canete,dcanete55@yellowbook.com,Female,TRUE -187,Liesa,Rodd,lrodd56@dailymotion.com,Female,TRUE -188,Dew,Whitlow,dwhitlow57@virginia.edu,Male,TRUE -189,Kristoforo,Enticott,kenticott58@census.gov,Male,TRUE -190,Emmaline,Poxon,epoxon59@pagesperso-orange.fr,Female,TRUE -191,Alleen,Capeloff,acapeloff5a@nytimes.com,Female,TRUE -192,Orsola,Merrison,omerrison5b@walmart.com,Female,TRUE -193,Ansel,Egdal,aegdal5c@w3.org,Male,FALSE -194,Amandie,Girardot,agirardot5d@hatena.ne.jp,Female,FALSE -195,Janos,Rannells,jrannells5e@usgs.gov,Male,FALSE -196,Cori,Laval,claval5f@wix.com,Female,FALSE -197,Alysia,MacGowan,amacgowan5g@mtv.com,Female,FALSE -198,Tulley,Gamil,tgamil5h@indiatimes.com,Male,FALSE -199,Lezlie,Scotchmer,lscotchmer5i@cisco.com,Genderfluid,TRUE -200,Tamera,Itzig,titzig5j@upenn.edu,Female,TRUE -201,Daron,Varren,dvarren5k@netvibes.com,Female,FALSE -202,Jakob,Cuddehay,jcuddehay5l@usatoday.com,Male,TRUE -203,Estevan,Halpeine,ehalpeine5m@omniture.com,Male,FALSE -204,Una,Trimby,utrimby5n@pen.io,Female,TRUE -205,April,Blunden,ablunden5o@xrea.com,Female,TRUE -206,Gregoor,Heffernan,gheffernan5p@oracle.com,Male,FALSE -207,Gray,Pagden,gpagden5q@themeforest.net,Female,TRUE -208,Missy,Plaistowe,mplaistowe5r@upenn.edu,Female,FALSE -209,Matty,Cockarill,mcockarill5s@bloglovin.com,Male,FALSE -210,Brose,Cortez,bcortez5t@odnoklassniki.ru,Male,TRUE -211,Waldon,Cloke,wcloke5u@flavors.me,Male,FALSE -212,Piper,Probat,pprobat5v@economist.com,Female,FALSE -213,Harrison,Bryer,hbryer5w@scientificamerican.com,Male,TRUE -214,Lorry,Erlam,lerlam5x@ning.com,Female,TRUE -215,Obie,Delleschi,odelleschi5y@fc2.com,Male,TRUE -216,Selinda,Gianotti,sgianotti5z@usgs.gov,Female,TRUE -217,Wally,Drinkhall,wdrinkhall60@columbia.edu,Female,FALSE -218,Hyacinthia,Trudgeon,htrudgeon61@webmd.com,Female,FALSE -219,Wyatan,Norheny,wnorheny62@exblog.jp,Male,FALSE -220,Cinnamon,Ravenhills,cravenhills63@biblegateway.com,Female,TRUE -221,Dedie,Philbin,dphilbin64@blogs.com,Female,TRUE -222,Ashbey,Cramond,acramond65@bloglines.com,Male,TRUE -223,Dori,Summerlie,dsummerlie66@storify.com,Female,TRUE -224,Ellery,Maslen,emaslen67@independent.co.uk,Male,FALSE -225,Keary,Dupey,kdupey68@tumblr.com,Male,FALSE -226,Dougie,Essery,dessery69@edublogs.org,Male,TRUE -227,Drucie,Lankford,dlankford6a@mapquest.com,Female,FALSE -228,Ellwood,Evens,eevens6b@unicef.org,Male,TRUE -229,Kacy,Costi,kcosti6c@youku.com,Female,FALSE -230,Laurence,Janaway,ljanaway6d@usnews.com,Male,TRUE -231,Jeralee,Simoens,jsimoens6e@nsw.gov.au,Female,FALSE -232,Jim,Wehner,jwehner6f@photobucket.com,Male,FALSE -233,Lind,Le Bosse,llebosse6g@ucoz.com,Male,TRUE -234,Christiana,Radish,cradish6h@indiegogo.com,Female,TRUE -235,Justine,Nortunen,jnortunen6i@smh.com.au,Female,FALSE -236,Adrea,Larsen,alarsen6j@oracle.com,Female,FALSE -237,Si,Gatsby,sgatsby6k@jiathis.com,Male,FALSE -238,Richy,Cottill,rcottill6l@psu.edu,Male,FALSE -239,Adora,Warstall,awarstall6m@jugem.jp,Genderqueer,TRUE -240,Teador,Eyckelberg,teyckelberg6n@woothemes.com,Male,TRUE -241,Mimi,Crossingham,mcrossingham6o@goo.ne.jp,Female,FALSE -242,Leela,Connikie,lconnikie6p@trellian.com,Female,TRUE -243,Margarita,Oolahan,moolahan6q@bbc.co.uk,Female,TRUE -244,Tim,Keast,tkeast6r@usatoday.com,Female,TRUE -245,Anna,Fox,afox6s@unblog.fr,Female,FALSE -246,Wake,Volke,wvolke6t@list-manage.com,Male,FALSE -247,Tarrah,Mellmoth,tmellmoth6u@cdc.gov,Female,TRUE -248,Jared,Jeyes,jjeyes6v@latimes.com,Male,FALSE -249,Breanne,Fuster,bfuster6w@nih.gov,Female,FALSE -250,Gabbie,Popland,gpopland6x@barnesandnoble.com,Male,TRUE -251,Aldo,Genthner,agenthner6y@google.de,Male,TRUE -252,Yulma,Burd,yburd6z@wufoo.com,Male,FALSE -253,Dotti,Atwood,datwood70@symantec.com,Female,FALSE -254,Cecil,Broadfoot,cbroadfoot71@amazon.co.jp,Male,FALSE -255,Joanna,Tanser,jtanser72@icq.com,Female,TRUE -256,Reggy,MacConnechie,rmacconnechie73@skyrock.com,Male,TRUE -257,Trumann,Kybbye,tkybbye74@wikia.com,Male,TRUE -258,Graeme,Eales,geales75@angelfire.com,Male,TRUE -259,Jami,Brierley,jbrierley76@cdc.gov,Female,FALSE -260,Harri,Alleway,halleway77@domainmarket.com,Female,TRUE -261,Aila,McGriele,amcgriele78@ustream.tv,Polygender,TRUE -262,Rosamund,Gunda,rgunda79@issuu.com,Female,TRUE -263,Stavros,Kigelman,skigelman7a@photobucket.com,Male,FALSE -264,Ingeberg,Muehler,imuehler7b@moonfruit.com,Bigender,TRUE -265,Iggy,Licciardi,ilicciardi7c@topsy.com,Male,TRUE -266,Vina,Kempson,vkempson7d@google.nl,Female,TRUE -267,Nell,Benjamin,nbenjamin7e@123-reg.co.uk,Agender,FALSE -268,Danica,McCraw,dmccraw7f@seesaa.net,Female,TRUE -269,Saidee,Darch,sdarch7g@nps.gov,Female,FALSE -270,Scot,Deek,sdeek7h@cargocollective.com,Male,FALSE -271,Louise,Kayne,lkayne7i@delicious.com,Female,FALSE -272,Euphemia,Heino,eheino7j@omniture.com,Female,TRUE -273,Gertruda,Le Estut,gleestut7k@yolasite.com,Female,TRUE -274,Josiah,Dybald,jdybald7l@vkontakte.ru,Male,TRUE -275,Abbye,Downage,adownage7m@plala.or.jp,Female,TRUE -276,Horacio,Guise,hguise7n@networkadvertising.org,Male,FALSE -277,Cozmo,Owlner,cowlner7o@free.fr,Male,FALSE -278,Brucie,Dobrowlski,bdobrowlski7p@github.io,Male,TRUE -279,Bryce,Lapworth,blapworth7q@tinypic.com,Male,FALSE -280,Madel,Toping,mtoping7r@hp.com,Female,TRUE -281,Nels,Guidotti,nguidotti7s@comsenz.com,Male,TRUE -282,Mort,Crewes,mcrewes7t@imageshack.us,Polygender,FALSE -283,Waverly,Tolworthy,wtolworthy7u@wunderground.com,Male,FALSE -284,Anatole,Gasson,agasson7v@cocolog-nifty.com,Male,TRUE -285,Kimberli,Armsden,karmsden7w@t-online.de,Female,FALSE -286,Willi,Donisi,wdonisi7x@dot.gov,Polygender,TRUE -287,Cherise,Costock,ccostock7y@merriam-webster.com,Female,FALSE -288,Kimble,Haton,khaton7z@washington.edu,Male,TRUE -289,Wolfgang,Schuricht,wschuricht80@pagesperso-orange.fr,Male,TRUE -290,Heywood,Poytheras,hpoytheras81@pagesperso-orange.fr,Male,TRUE -291,Jase,Chesswas,jchesswas82@sbwire.com,Male,FALSE -292,Dosi,Drain,ddrain83@sun.com,Female,FALSE -293,Maximo,Yushin,myushin84@economist.com,Male,FALSE -294,Hamish,Rossey,hrossey85@mapquest.com,Male,FALSE -295,Elle,Joiris,ejoiris86@wufoo.com,Female,TRUE -296,Elyse,McElwee,emcelwee87@biblegateway.com,Female,FALSE -297,Lenora,Kinig,lkinig88@gnu.org,Female,FALSE -298,Stevie,Tabbernor,stabbernor89@technorati.com,Male,TRUE -299,Gerianna,Cribbott,gcribbott8a@ftc.gov,Female,FALSE -300,Kendre,Duinbleton,kduinbleton8b@answers.com,Polygender,TRUE -301,Nona,O'Murtagh,nomurtagh8c@taobao.com,Female,FALSE -302,Adrianna,Letixier,aletixier8d@answers.com,Female,FALSE -303,Farand,Bradmore,fbradmore8e@xrea.com,Female,FALSE -304,Jules,Girault,jgirault8f@berkeley.edu,Male,TRUE -305,Teena,Servis,tservis8g@huffingtonpost.com,Female,FALSE -306,Dewie,Braiden,dbraiden8h@quantcast.com,Male,TRUE -307,Evyn,Sturdey,esturdey8i@arstechnica.com,Male,TRUE -308,Elaina,Haggett,ehaggett8j@technorati.com,Female,TRUE -309,Nikolaus,Blazevic,nblazevic8k@odnoklassniki.ru,Male,FALSE -310,Paquito,Lethbridge,plethbridge8l@wired.com,Male,TRUE -311,Roosevelt,Nangle,rnangle8m@indiatimes.com,Male,FALSE -312,Pierce,Lowde,plowde8n@alibaba.com,Genderfluid,TRUE -313,Jackie,Clapperton,jclapperton8o@reddit.com,Male,FALSE -314,Fredrick,Treanor,ftreanor8p@php.net,Genderqueer,FALSE -315,Eimile,Hopkyns,ehopkyns8q@ucoz.com,Female,TRUE -316,Ulrika,Mourant,umourant8r@redcross.org,Female,TRUE -317,Gaspar,Brehault,gbrehault8s@seattletimes.com,Male,FALSE -318,Henrik,Petley,hpetley8t@oakley.com,Male,FALSE -319,Yovonnda,Blakden,yblakden8u@t.co,Female,TRUE -320,Caryn,Karolewski,ckarolewski8v@storify.com,Non-binary,FALSE -321,Blaine,Nevins,bnevins8w@apache.org,Male,TRUE -322,Abel,Courtier,acourtier8x@drupal.org,Male,TRUE -323,Bradley,Kuschel,bkuschel8y@infoseek.co.jp,Male,TRUE -324,Ralph,Pierro,rpierro8z@omniture.com,Male,TRUE -325,Beverly,Frome,bfrome90@seesaa.net,Female,TRUE -326,Jamie,De Brett,jdebrett91@si.edu,Female,FALSE -327,Toby,Cheeld,tcheeld92@narod.ru,Male,TRUE -328,Elbert,Stainton - Skinn,estaintonskinn93@vkontakte.ru,Male,FALSE -329,Ignatius,Hessay,ihessay94@google.com,Male,FALSE -330,Aridatha,Petre,apetre95@twitpic.com,Female,FALSE -331,Nataline,Grist,ngrist96@nbcnews.com,Female,FALSE -332,Quinta,Lis,qlis97@paginegialle.it,Female,TRUE -333,Jacques,Horche,jhorche98@comsenz.com,Male,TRUE -334,Kathie,Pycock,kpycock99@ebay.com,Female,TRUE -335,Esmaria,Chichgar,echichgar9a@over-blog.com,Female,FALSE -336,Olivette,Briddle,obriddle9b@exblog.jp,Female,FALSE -337,Cookie,Kenworthey,ckenworthey9c@google.ca,Female,TRUE -338,Andra,Beard,abeard9d@marriott.com,Female,FALSE -339,Cele,Ruben,cruben9e@washington.edu,Female,TRUE -340,Corbin,Swatman,cswatman9f@tumblr.com,Male,FALSE -341,Rasia,Burkman,rburkman9g@usgs.gov,Female,TRUE -342,Lizzie,Fillon,lfillon9h@wikimedia.org,Female,TRUE -343,Lenee,Jonk,ljonk9i@ox.ac.uk,Female,FALSE -344,Woodie,Gaskill,wgaskill9j@prweb.com,Male,TRUE -345,Norry,Gogarty,ngogarty9k@yahoo.com,Male,TRUE -346,Erhard,Maybury,emaybury9l@who.int,Male,FALSE -347,Mirabella,Khristoforov,mkhristoforov9m@google.com.hk,Female,FALSE -348,Tobie,Serck,tserck9n@timesonline.co.uk,Male,TRUE -349,Diego,Duchant,dduchant9o@sohu.com,Male,FALSE -350,Wendi,Drissell,wdrissell9p@xrea.com,Female,FALSE -351,Idalia,Bicheno,ibicheno9q@nasa.gov,Female,FALSE -352,Caitlin,Rance,crance9r@w3.org,Female,TRUE -353,Electra,Berzons,eberzons9s@oaic.gov.au,Non-binary,TRUE -354,Felic,Bartlet,fbartlet9t@blogspot.com,Male,TRUE -355,Benjamin,Reinhardt,breinhardt9u@mozilla.org,Male,TRUE -356,Nickolai,Abbatucci,nabbatucci9v@fastcompany.com,Male,TRUE -357,Stanislaw,Archdeckne,sarchdeckne9w@arstechnica.com,Male,FALSE -358,Marcus,Arrigo,marrigo9x@rambler.ru,Male,FALSE -359,Sherie,Pendergast,spendergast9y@addtoany.com,Female,FALSE -360,Camella,Bullent,cbullent9z@seesaa.net,Female,FALSE -361,Roger,Hover,rhovera0@purevolume.com,Male,FALSE -362,Madelon,Whittlesey,mwhittleseya1@unicef.org,Female,FALSE -363,Rodina,Castelot,rcastelota2@shinystat.com,Female,FALSE -364,Launce,Nelsen,lnelsena3@mashable.com,Male,TRUE -365,Carlynn,Bullan,cbullana4@stanford.edu,Female,FALSE -366,Norton,Ashman,nashmana5@tumblr.com,Male,FALSE -367,Basile,Nana,bnanaa6@technorati.com,Male,TRUE -368,Demetrius,Shepherd,dshepherda7@washington.edu,Male,FALSE -369,Martie,Skarr,mskarra8@reference.com,Female,FALSE -370,Lisa,Harbidge,lharbidgea9@google.it,Female,TRUE -371,Glenden,Hearnes,ghearnesaa@fda.gov,Male,TRUE -372,Cristi,Barrington,cbarringtonab@youku.com,Female,TRUE -373,Raphael,Oboy,roboyac@jigsy.com,Male,FALSE -374,Clayton,Knowler,cknowlerad@list-manage.com,Male,FALSE -375,Terrie,Lorenzo,tlorenzoae@google.co.jp,Female,TRUE -376,Gaspard,Breffitt,gbreffittaf@adobe.com,Male,TRUE -377,Murry,Farthin,mfarthinag@cisco.com,Male,TRUE -378,Syd,Jeff,sjeffah@deviantart.com,Male,TRUE -379,Kermie,Jessop,kjessopai@quantcast.com,Male,TRUE -380,Daron,Leafe,dleafeaj@paginegialle.it,Male,TRUE -381,Uriah,Begbie,ubegbieak@ezinearticles.com,Male,TRUE -382,Bobette,Ollerhead,bollerheadal@harvard.edu,Female,TRUE -383,Rosana,Spinello,rspinelloam@reverbnation.com,Genderfluid,FALSE -384,Bradan,Kinchington,bkinchingtonan@army.mil,Male,FALSE -385,Pauletta,Carwithim,pcarwithimao@deliciousdays.com,Female,FALSE -386,Arabela,Vail,availap@mozilla.com,Female,TRUE -387,Jerri,McCartney,jmccartneyaq@miibeian.gov.cn,Male,TRUE -388,Ellis,Buick,ebuickar@prlog.org,Male,TRUE -389,Kienan,Byer,kbyeras@cdbaby.com,Male,FALSE -390,Edythe,Chitty,echittyat@illinois.edu,Female,TRUE -391,Augy,Gabbetis,agabbetisau@biblegateway.com,Male,FALSE -392,Gunter,Keady,gkeadyav@sohu.com,Male,FALSE -393,Julius,Lascelles,jlascellesaw@army.mil,Male,FALSE -394,Donnie,Pardy,dpardyax@deliciousdays.com,Male,FALSE -395,Billie,Yesenin,byeseninay@mysql.com,Male,FALSE -396,Wade,Durrell,wdurrellaz@oracle.com,Male,FALSE -397,Obadias,Warland,owarlandb0@ocn.ne.jp,Agender,FALSE -398,Vinnie,Colthard,vcolthardb1@furl.net,Male,FALSE -399,Marne,Gatland,mgatlandb2@cafepress.com,Female,TRUE -400,Barret,Benitti,bbenittib3@nyu.edu,Male,TRUE -401,Wilhelm,Burn,wburnb4@examiner.com,Male,TRUE -402,Vasily,Simper,vsimperb5@army.mil,Male,TRUE -403,Dian,MacIlwrick,dmacilwrickb6@issuu.com,Female,TRUE -404,Mendy,Arnoldi,marnoldib7@sfgate.com,Male,FALSE -405,Crawford,Hoogendorp,choogendorpb8@msn.com,Male,FALSE -406,Brigham,Goding,bgodingb9@lycos.com,Male,FALSE -407,Coral,De Lisle,cdelisleba@princeton.edu,Female,FALSE -408,Laure,Cleynman,lcleynmanbb@yelp.com,Genderfluid,FALSE -409,Dedra,Sivess,dsivessbc@devhub.com,Genderqueer,FALSE -410,Tobiah,Stilgoe,tstilgoebd@hubpages.com,Male,FALSE -411,Baxy,Passo,bpassobe@slideshare.net,Male,FALSE -412,Pearle,Shaul,pshaulbf@loc.gov,Female,FALSE -413,Raddy,Watkins,rwatkinsbg@wordpress.com,Male,FALSE -414,Sigismondo,Gaskamp,sgaskampbh@springer.com,Male,FALSE -415,Noach,Gilhouley,ngilhouleybi@hatena.ne.jp,Male,TRUE -416,Vonnie,Orehead,voreheadbj@themeforest.net,Female,TRUE -417,Ollie,Getcliffe,ogetcliffebk@gmpg.org,Male,TRUE -418,Nahum,Cattel,ncattelbl@latimes.com,Male,TRUE -419,Bendite,Tudhope,btudhopebm@wisc.edu,Bigender,FALSE -420,Evelin,Rodger,erodgerbn@t-online.de,Genderfluid,TRUE -421,Keefer,Rene,krenebo@fotki.com,Male,FALSE -422,Tamarah,Dach,tdachbp@nyu.edu,Female,FALSE -423,Sara-ann,Mahomet,smahometbq@shinystat.com,Female,TRUE -424,Gar,Jewers,gjewersbr@livejournal.com,Male,FALSE -425,Mei,Karlicek,mkarlicekbs@uiuc.edu,Female,FALSE -426,Elayne,Storrah,estorrahbt@bloglines.com,Female,FALSE -427,Tedie,Scopham,tscophambu@blogtalkradio.com,Male,FALSE -428,Rosalyn,Ferres,rferresbv@biglobe.ne.jp,Female,TRUE -429,Sisile,Cambell,scambellbw@macromedia.com,Female,FALSE -430,Cecilia,Coath,ccoathbx@mtv.com,Genderqueer,TRUE -431,Jasper,Duffy,jduffyby@msn.com,Male,TRUE -432,Selby,Bugge,sbuggebz@tamu.edu,Male,TRUE -433,Agretha,Echallie,aechalliec0@dagondesign.com,Female,TRUE -434,Di,Silby,dsilbyc1@mac.com,Female,TRUE -435,Bryon,Wilford,bwilfordc2@livejournal.com,Male,TRUE -436,Clemmie,Tonks,ctonksc3@wufoo.com,Male,TRUE -437,Annemarie,Ascraft,aascraftc4@cornell.edu,Female,FALSE -438,Trever,Goddert.sf,tgoddertsfc5@zdnet.com,Male,TRUE -439,Bail,MacAlees,bmacaleesc6@dailymail.co.uk,Male,TRUE -440,Cynde,Nelissen,cnelissenc7@nhs.uk,Female,FALSE -441,Wenda,Boakes,wboakesc8@t-online.de,Female,FALSE -442,Sandy,Sobey,ssobeyc9@360.cn,Male,TRUE -443,Napoleon,Bazeley,nbazeleyca@photobucket.com,Male,TRUE -444,Lina,Dallison,ldallisoncb@vimeo.com,Female,FALSE -445,Monah,Curnokk,mcurnokkcc@facebook.com,Female,FALSE -446,Chilton,Greves,cgrevescd@thetimes.co.uk,Male,FALSE -447,Patrick,Burnall,pburnallce@mashable.com,Male,FALSE -448,Gae,Halwill,ghalwillcf@accuweather.com,Female,TRUE -449,Moise,Aldous,maldouscg@w3.org,Male,FALSE -450,Elnora,Marples,emarplesch@yale.edu,Female,FALSE -451,Ernestine,Pyner,epynerci@va.gov,Female,TRUE -452,Drew,Guerriero,dguerrierocj@tamu.edu,Male,FALSE -453,Tyrus,Trobe,ttrobeck@sitemeter.com,Male,TRUE -454,Fiann,Breakwell,fbreakwellcl@simplemachines.org,Female,TRUE -455,Chloette,Bisgrove,cbisgrovecm@fc2.com,Female,FALSE -456,Giraud,Margaritelli,gmargaritellicn@bloglovin.com,Male,FALSE -457,Ignacius,Assaf,iassafco@naver.com,Male,FALSE -458,Velma,Delany,vdelanycp@alibaba.com,Female,TRUE -459,Cesare,Bixley,cbixleycq@theatlantic.com,Male,FALSE -460,Claus,Rohlfing,crohlfingcr@discuz.net,Genderqueer,FALSE -461,Papagena,Drepp,pdreppcs@dyndns.org,Female,TRUE -462,Grover,Fiske,gfiskect@twitpic.com,Male,FALSE -463,Dell,Scolli,dscollicu@usda.gov,Female,TRUE -464,Ingrid,Bedells,ibedellscv@nyu.edu,Female,TRUE -465,Paola,Benmore,pbenmorecw@privacy.gov.au,Female,TRUE -466,Gerhard,Mitchelhill,gmitchelhillcx@fotki.com,Male,TRUE -467,Elonore,Yurinov,eyurinovcy@cloudflare.com,Female,FALSE -468,Rheta,Corkan,rcorkancz@mlb.com,Female,FALSE -469,Mill,Jakubowicz,mjakubowiczd0@opera.com,Bigender,FALSE -470,Denney,Penberthy,dpenberthyd1@networksolutions.com,Male,TRUE -471,Vanya,Leband,vlebandd2@berkeley.edu,Genderfluid,FALSE -472,El,Dearing,edearingd3@aboutads.info,Male,TRUE -473,Shirlene,Tassell,stasselld4@friendfeed.com,Female,TRUE -474,Dorene,Cleminshaw,dcleminshawd5@nymag.com,Genderfluid,TRUE -475,Regan,Toynbee,rtoynbeed6@woothemes.com,Male,FALSE -476,Astra,Issatt,aissattd7@unblog.fr,Bigender,FALSE -477,Pier,Kenyam,pkenyamd8@google.ru,Female,FALSE -478,Vaughn,Guntrip,vguntripd9@example.com,Male,FALSE -479,Darin,MacDearmaid,dmacdearmaidda@instagram.com,Male,TRUE -480,Mickie,Pauler,mpaulerdb@is.gd,Male,FALSE -481,Dione,Waldram,dwaldramdc@qq.com,Female,FALSE -482,Prescott,Schruyers,pschruyersdd@miibeian.gov.cn,Male,TRUE -483,Liuka,De Biasi,ldebiaside@sciencedaily.com,Female,FALSE -484,Chan,Townsend,ctownsenddf@bloglines.com,Male,FALSE -485,Manuel,Wildman,mwildmandg@oracle.com,Male,TRUE -486,Dorian,Kelloch,dkellochdh@reference.com,Male,TRUE -487,Devin,Stanyan,dstanyandi@squidoo.com,Female,FALSE -488,Catharina,Petters,cpettersdj@cnbc.com,Female,FALSE -489,Rosella,Carmody,rcarmodydk@businessinsider.com,Female,TRUE -490,Arnie,Buggs,abuggsdl@yelp.com,Male,TRUE -491,Faith,Burnep,fburnepdm@taobao.com,Female,FALSE -492,Carleton,Ridpath,cridpathdn@godaddy.com,Male,TRUE -493,Temple,Gorthy,tgorthydo@bizjournals.com,Male,TRUE -494,Rollins,Palatino,rpalatinodp@dion.ne.jp,Male,TRUE -495,Arvin,Fearenside,afearensidedq@vk.com,Male,TRUE -496,Moses,Adamik,madamikdr@arstechnica.com,Male,TRUE -497,Annecorinne,Gronw,agronwds@edublogs.org,Female,TRUE -498,Myca,Abrey,mabreydt@goo.gl,Male,TRUE -499,Donica,De Hooge,ddehoogedu@cpanel.net,Female,TRUE -500,Dalis,Robertis,drobertisdv@vk.com,Male,FALSE -501,Lothaire,Labusquiere,llabusquieredw@qq.com,Male,FALSE -502,Pip,Bertelmot,pbertelmotdx@buzzfeed.com,Male,FALSE -503,Ragnar,Clemenson,rclemensondy@sourceforge.net,Male,FALSE -504,Cordie,McGlone,cmcglonedz@about.com,Female,FALSE -505,Nessi,Blackadder,nblackaddere0@sogou.com,Female,FALSE -506,Forrester,Armal,farmale1@t-online.de,Male,TRUE -507,Demetris,Tyt,dtyte2@cyberchimps.com,Male,TRUE -508,Adella,Bateson,abatesone3@i2i.jp,Female,FALSE -509,Eunice,Picopp,epicoppe4@patch.com,Polygender,FALSE -510,Kariotta,Krystof,kkrystofe5@wsj.com,Non-binary,FALSE -511,Sergei,Steptoe,ssteptoee6@t-online.de,Agender,TRUE -512,Benn,Weddup,bweddupe7@hostgator.com,Male,TRUE -513,Anne-corinne,Akid,aakide8@cpanel.net,Female,FALSE -514,Christoph,Danbrook,cdanbrooke9@sbwire.com,Male,FALSE -515,Burton,Wadforth,bwadforthea@devhub.com,Male,FALSE -516,Danya,De Blasiis,ddeblasiiseb@theglobeandmail.com,Male,TRUE -517,Benny,Ticic,bticicec@skyrock.com,Female,FALSE -518,Karlie,Elce,kelceed@bing.com,Female,TRUE -519,Maury,Trim,mtrimee@china.com.cn,Male,TRUE -520,Rosa,Willavize,rwillavizeef@joomla.org,Female,FALSE -521,Kean,Rankcom,krankcomeg@flavors.me,Male,FALSE -522,Sandye,Print,sprinteh@seattletimes.com,Female,TRUE -523,Griffie,Schuck,gschuckei@w3.org,Male,FALSE -524,Babb,Dalligan,bdalliganej@vimeo.com,Female,FALSE -525,Andeee,Townsley,atownsleyek@quantcast.com,Female,FALSE -526,Charisse,Norris,cnorrisel@tmall.com,Female,TRUE -527,Lena,Thraves,lthravesem@sogou.com,Female,TRUE -528,Francklin,Spurgeon,fspurgeonen@senate.gov,Male,TRUE -529,Noelyn,Roughley,nroughleyeo@icq.com,Female,FALSE -530,Ursuline,Issacson,uissacsonep@ftc.gov,Female,TRUE -531,Giselle,Godmar,ggodmareq@bbc.co.uk,Female,TRUE -532,Delaney,Sweetzer,dsweetzerer@blog.com,Male,TRUE -533,Gigi,Husselbee,ghusselbeees@mail.ru,Female,TRUE -534,Wilma,MacHarg,wmacharget@cargocollective.com,Female,TRUE -535,Rozelle,Carmen,rcarmeneu@de.vu,Female,FALSE -536,Johnny,Stanistreet,jstanistreetev@infoseek.co.jp,Male,FALSE -537,Terese,Cocks,tcocksew@wired.com,Female,TRUE -538,Emmit,Gladdor,egladdorex@cargocollective.com,Male,TRUE -539,Charles,Mateo,cmateoey@msu.edu,Male,TRUE -540,Gennie,Beckhurst,gbeckhurstez@nature.com,Female,FALSE -541,Benji,Koles,bkolesf0@webnode.com,Male,TRUE -542,Kai,Dyble,kdyblef1@deliciousdays.com,Female,FALSE -543,Pedro,Meiklejohn,pmeiklejohnf2@boston.com,Male,TRUE -544,Karola,Gage,kgagef3@ebay.co.uk,Female,TRUE -545,Leanora,Felstead,lfelsteadf4@lycos.com,Female,FALSE -546,Thorstein,Dellenbrook,tdellenbrookf5@bravesites.com,Male,TRUE -547,Nickie,Vlach,nvlachf6@ca.gov,Non-binary,FALSE -548,Caspar,Isaq,cisaqf7@taobao.com,Male,FALSE -549,Lila,Denny,ldennyf8@de.vu,Female,FALSE -550,Cosimo,Wayvill,cwayvillf9@netvibes.com,Male,TRUE -551,Dorisa,Elderkin,delderkinfa@disqus.com,Female,FALSE -552,Gloriane,Gaggen,ggaggenfb@trellian.com,Agender,FALSE -553,Debbi,Ruppertz,druppertzfc@163.com,Female,TRUE -554,Justino,Kempson,jkempsonfd@weebly.com,Male,FALSE -555,Marita,Rapkins,mrapkinsfe@nature.com,Female,TRUE -556,Nan,Dewsnap,ndewsnapff@usgs.gov,Female,FALSE -557,Farrell,Allnutt,fallnuttfg@go.com,Male,TRUE -558,Earvin,Dammarell,edammarellfh@nih.gov,Male,FALSE -559,Moses,Skone,mskonefi@webnode.com,Male,FALSE -560,Joyous,MacDermid,jmacdermidfj@wiley.com,Female,FALSE -561,Gerianne,Waszczykowski,gwaszczykowskifk@newsvine.com,Female,TRUE -562,Ryun,Pow,rpowfl@trellian.com,Non-binary,FALSE -563,Arley,Loveguard,aloveguardfm@wsj.com,Male,FALSE -564,Ulick,Mussettini,umussettinifn@newsvine.com,Male,FALSE -565,Rollie,Bearns,rbearnsfo@smugmug.com,Male,FALSE -566,Augustine,Colley,acolleyfp@whitehouse.gov,Genderfluid,TRUE -567,Herby,MacMarcuis,hmacmarcuisfq@freewebs.com,Male,FALSE -568,Isidore,Priditt,ipridittfr@ox.ac.uk,Male,FALSE -569,Eugenius,Mokes,emokesfs@slate.com,Male,FALSE -570,Hana,Hardan,hhardanft@dagondesign.com,Polygender,TRUE -571,Valli,Cannell,vcannellfu@google.fr,Agender,FALSE -572,Corina,O' Finan,cofinanfv@loc.gov,Female,TRUE -573,Tammie,Scotchmer,tscotchmerfw@skype.com,Male,FALSE -574,Loralie,McCarter,lmccarterfx@blogger.com,Genderqueer,TRUE -575,Jerrie,Juszczyk,jjuszczykfy@linkedin.com,Non-binary,FALSE -576,Agnesse,Tripony,atriponyfz@theguardian.com,Female,FALSE -577,Sunny,Tindley,stindleyg0@youtu.be,Female,TRUE -578,Elbertine,Avison,eavisong1@usda.gov,Genderqueer,TRUE -579,Antoinette,Busson,abussong2@creativecommons.org,Female,FALSE -580,Gwennie,Lattimer,glattimerg3@twitpic.com,Female,FALSE -581,Adan,Casotti,acasottig4@last.fm,Female,FALSE -582,Beatrix,Seeman,bseemang5@weebly.com,Female,TRUE -583,Julio,Johnikin,jjohniking6@utexas.edu,Male,FALSE -584,Drusie,Upcott,dupcottg7@yellowpages.com,Female,TRUE -585,Hedy,Ferroli,hferrolig8@ovh.net,Female,TRUE -586,Charissa,Cordelle,ccordelleg9@google.it,Female,TRUE -587,Dayna,Moen,dmoenga@bigcartel.com,Female,TRUE -588,Darwin,Durgan,ddurgangb@webmd.com,Non-binary,TRUE -589,Florella,Balmann,fbalmanngc@cornell.edu,Female,FALSE -590,Eward,Nealon,enealongd@noaa.gov,Male,TRUE -591,Robin,Attree,rattreege@soundcloud.com,Male,TRUE -592,Natassia,Ellyatt,nellyattgf@goo.ne.jp,Female,FALSE -593,Essy,Assante,eassantegg@businessweek.com,Female,TRUE -594,Eugenius,Lante,elantegh@4shared.com,Male,FALSE -595,Tillie,Gustus,tgustusgi@prnewswire.com,Female,FALSE -596,Jeanette,McVicker,jmcvickergj@nhs.uk,Female,FALSE -597,Cam,Duinbleton,cduinbletongk@java.com,Female,FALSE -598,Rodolph,Satford,rsatfordgl@virginia.edu,Male,TRUE -599,Laney,Fedoronko,lfedoronkogm@ft.com,Female,TRUE -600,Leopold,Bryant,lbryantgn@independent.co.uk,Non-binary,TRUE -601,Abdul,Fairhead,afairheadgo@geocities.com,Male,FALSE -602,Chelsie,Heynel,cheynelgp@goo.gl,Female,FALSE -603,Nanette,Redmond,nredmondgq@deviantart.com,Female,FALSE -604,Bertine,Dunsmuir,bdunsmuirgr@sina.com.cn,Female,FALSE -605,Steffane,Thorburn,sthorburngs@amazon.com,Female,FALSE -606,Jillie,Daintith,jdaintithgt@mayoclinic.com,Female,FALSE -607,Ely,MacKenny,emackennygu@dailymail.co.uk,Male,FALSE -608,Lorianne,Mathew,lmathewgv@marketwatch.com,Female,TRUE -609,Perkin,Drache,pdrachegw@macromedia.com,Male,TRUE -610,Freeman,Mallinder,fmallindergx@taobao.com,Male,TRUE -611,Cullen,Asman,casmangy@xinhuanet.com,Male,FALSE -612,Agatha,Ellingham,aellinghamgz@cornell.edu,Female,FALSE -613,Felizio,Bolesma,fbolesmah0@instagram.com,Genderfluid,FALSE -614,Allyn,Mears,amearsh1@zdnet.com,Female,TRUE -615,Berti,Simonini,bsimoninih2@goo.ne.jp,Female,FALSE -616,Wally,Orteu,worteuh3@seesaa.net,Male,TRUE -617,Stesha,Eates,seatesh4@springer.com,Female,FALSE -618,Reade,Anand,ranandh5@nba.com,Male,TRUE -619,Eula,Maffi,emaffih6@home.pl,Genderqueer,FALSE -620,Natalie,McClean,nmccleanh7@nyu.edu,Female,TRUE -621,Bryanty,Peaurt,bpeaurth8@drupal.org,Genderqueer,FALSE -622,Tabb,Wilshin,twilshinh9@mysql.com,Male,TRUE -623,Sigvard,Fassbender,sfassbenderha@nhs.uk,Genderqueer,FALSE -624,James,Gethings,jgethingshb@posterous.com,Male,TRUE -625,Carey,Zavattari,czavattarihc@vkontakte.ru,Male,TRUE -626,Lionel,Nussgen,lnussgenhd@php.net,Male,TRUE -627,Virge,Esbrook,vesbrookhe@foxnews.com,Male,TRUE -628,Antonella,Laise,alaisehf@dropbox.com,Female,TRUE -629,Idelle,Chrystie,ichrystiehg@time.com,Female,TRUE -630,Trudie,Philipeaux,tphilipeauxhh@homestead.com,Female,FALSE -631,Jerry,O'Corren,jocorrenhi@examiner.com,Female,TRUE -632,Dasya,Yarham,dyarhamhj@marriott.com,Female,TRUE -633,Sella,Balsellie,sbalselliehk@imdb.com,Female,TRUE -634,Kally,Pring,kpringhl@devhub.com,Female,TRUE -635,Rich,Charlick,rcharlickhm@cloudflare.com,Bigender,FALSE -636,Shepard,Ogborn,sogbornhn@gmpg.org,Male,TRUE -637,Daryn,O'Towey,dotoweyho@freewebs.com,Female,FALSE -638,Nickola,Skitterel,nskitterelhp@yellowbook.com,Genderfluid,TRUE -639,Brande,Alflatt,balflatthq@illinois.edu,Female,FALSE -640,Swen,Dionisii,sdionisiihr@ibm.com,Male,FALSE -641,Pat,Butterfint,pbutterfinths@360.cn,Male,TRUE -642,Lucky,Stanlack,lstanlackht@pen.io,Female,FALSE -643,Donnell,Leipoldt,dleipoldthu@canalblog.com,Genderfluid,FALSE -644,Win,Di Biasio,wdibiasiohv@alibaba.com,Male,TRUE -645,Shalom,Branigan,sbraniganhw@rediff.com,Polygender,TRUE -646,Tadio,Klauer,tklauerhx@phpbb.com,Agender,FALSE -647,Anatollo,Crathorne,acrathornehy@cafepress.com,Male,FALSE -648,Kerrin,Lodin,klodinhz@berkeley.edu,Female,TRUE -649,Cristie,Claus,cclausi0@biblegateway.com,Female,TRUE -650,Karlotta,Denzey,kdenzeyi1@unc.edu,Female,TRUE -651,Winifield,Stollmeier,wstollmeieri2@arizona.edu,Male,TRUE -652,Hanan,Dogg,hdoggi3@senate.gov,Male,FALSE -653,Iormina,McAnalley,imcanalleyi4@google.com.hk,Female,TRUE -654,Davon,Brisse,dbrissei5@bloglovin.com,Male,TRUE -655,Anastasia,Winram,awinrami6@youku.com,Agender,TRUE -656,Murial,Hacking,mhackingi7@jiathis.com,Genderqueer,TRUE -657,Winthrop,Olphert,wolpherti8@cloudflare.com,Male,FALSE -658,Kane,Alexandre,kalexandrei9@ning.com,Male,TRUE -659,Conroy,Blinman,cblinmania@theatlantic.com,Male,FALSE -660,Chicky,Ryland,crylandib@walmart.com,Male,FALSE -661,Gayelord,Dog,gdogic@walmart.com,Male,FALSE -662,Elianore,Braunes,ebraunesid@go.com,Female,TRUE -663,Kelcey,Bowgen,kbowgenie@feedburner.com,Female,FALSE -664,Trula,Polglaze,tpolglazeif@sitemeter.com,Female,TRUE -665,Verene,Hebborn,vhebbornig@taobao.com,Female,TRUE -666,Belinda,Rubinovitch,brubinovitchih@wix.com,Female,FALSE -667,Elissa,Dallison,edallisonii@parallels.com,Female,FALSE -668,Dexter,Rugge,druggeij@adobe.com,Male,TRUE -669,Linda,Mahody,lmahodyik@miitbeian.gov.cn,Female,FALSE -670,Putnem,Schapiro,pschapiroil@princeton.edu,Agender,TRUE -671,Xenos,Van Der Weedenburg,xvanderweedenburgim@smh.com.au,Male,FALSE -672,Pippy,MacNelly,pmacnellyin@networksolutions.com,Female,FALSE -673,Patty,Keuning,pkeuningio@un.org,Female,FALSE -674,Byrle,Currm,bcurrmip@slate.com,Male,TRUE -675,Forester,Dodshon,fdodshoniq@vimeo.com,Male,FALSE -676,Giffy,Denholm,gdenholmir@topsy.com,Male,FALSE -677,Vittorio,Mangeon,vmangeonis@de.vu,Polygender,TRUE -678,Trace,Touzey,ttouzeyit@google.nl,Agender,TRUE -679,Dannie,Calabry,dcalabryiu@goo.gl,Female,TRUE -680,Em,Torres,etorresiv@si.edu,Male,FALSE -681,Timothea,Vousden,tvousdeniw@issuu.com,Female,FALSE -682,Derry,Grierson,dgriersonix@imageshack.us,Genderqueer,FALSE -683,Maryanna,Dach,mdachiy@wisc.edu,Female,TRUE -684,Corrie,Roff,croffiz@lulu.com,Non-binary,FALSE -685,Orel,Rumming,orummingj0@feedburner.com,Female,FALSE -686,Shepard,Jorin,sjorinj1@google.pl,Genderqueer,TRUE -687,Charley,Petru,cpetruj2@gnu.org,Male,FALSE -688,Rickert,Teresse,rteressej3@washington.edu,Male,FALSE -689,Rolph,Mayou,rmayouj4@quantcast.com,Male,FALSE -690,Rene,McAnalley,rmcanalleyj5@smh.com.au,Male,TRUE -691,Rogerio,Halwood,rhalwoodj6@elpais.com,Male,FALSE -692,Willow,Hymor,whymorj7@statcounter.com,Female,FALSE -693,Lorne,Labon,llabonj8@google.cn,Male,TRUE -694,Lind,Lambourn,llambournj9@senate.gov,Male,FALSE -695,Rahel,Hallworth,rhallworthja@ucoz.ru,Female,FALSE -696,Sergei,Quennell,squennelljb@cocolog-nifty.com,Non-binary,TRUE -697,Chance,Rikard,crikardjc@google.com.br,Male,FALSE -698,Donnie,Gillbee,dgillbeejd@google.co.uk,Female,FALSE -699,Hervey,Meletti,hmelettije@about.me,Male,TRUE -700,Jefferey,Parkes,jparkesjf@nbcnews.com,Male,TRUE -701,Kenon,Formie,kformiejg@bloglines.com,Male,TRUE -702,Thor,Woolerton,twoolertonjh@drupal.org,Male,FALSE -703,Blakeley,Lorryman,blorrymanji@ucsd.edu,Female,FALSE -704,Hartwell,Balden,hbaldenjj@usda.gov,Male,FALSE -705,Frants,Rosengart,frosengartjk@geocities.com,Male,TRUE -706,Hugues,Dumingo,hdumingojl@newsvine.com,Male,FALSE -707,Jasen,Treeby,jtreebyjm@noaa.gov,Male,TRUE -708,Nona,Sommerling,nsommerlingjn@youtube.com,Female,FALSE -709,Herschel,Hunsworth,hhunsworthjo@ed.gov,Male,TRUE -710,Starlin,Kubas,skubasjp@last.fm,Female,TRUE -711,Rolf,Clemits,rclemitsjq@seesaa.net,Male,FALSE -712,Bartlet,Janas,bjanasjr@newsvine.com,Male,FALSE -713,Ania,Turnor,aturnorjs@cloudflare.com,Female,TRUE -714,Angie,Parlatt,aparlattjt@bing.com,Male,FALSE -715,Jenifer,Mongin,jmonginju@163.com,Female,FALSE -716,Carin,Johananoff,cjohananoffjv@timesonline.co.uk,Female,TRUE -717,Joceline,Stive,jstivejw@nbcnews.com,Female,FALSE -718,Duane,Sturges,dsturgesjx@wix.com,Male,FALSE -719,Amie,Egginton,aeggintonjy@tamu.edu,Female,FALSE -720,Cirilo,Martell,cmartelljz@google.es,Male,FALSE -721,Lianne,Boon,lboonk0@tuttocitta.it,Polygender,FALSE -722,Orlan,Cristoforetti,ocristoforettik1@psu.edu,Male,FALSE -723,Nicol,Terrey,nterreyk2@4shared.com,Agender,TRUE -724,Alf,Bowld,abowldk3@microsoft.com,Male,FALSE -725,Barrie,Mccaull,bmccaullk4@shop-pro.jp,Male,FALSE -726,Burty,Mussington,bmussingtonk5@google.com.br,Male,TRUE -727,Dory,Deedes,ddeedesk6@facebook.com,Genderqueer,TRUE -728,Kata,Grinikhinov,kgrinikhinovk7@springer.com,Female,TRUE -729,Denys,Littefair,dlittefairk8@uol.com.br,Male,TRUE -730,Pavel,Filyakov,pfilyakovk9@simplemachines.org,Male,FALSE -731,Guntar,Cunradi,gcunradika@nifty.com,Male,FALSE -732,Vic,Lendrem,vlendremkb@virginia.edu,Male,FALSE -733,Evelyn,Sills,esillskc@rediff.com,Male,TRUE -734,Karilynn,Cornelius,kcorneliuskd@jiathis.com,Female,FALSE -735,Sena,Pabelik,spabelikke@deliciousdays.com,Female,FALSE -736,Howard,Whitehall,hwhitehallkf@marketwatch.com,Male,TRUE -737,Abigail,Bree,abreekg@census.gov,Female,TRUE -738,Ellwood,Walley,ewalleykh@tuttocitta.it,Male,FALSE -739,Leontine,Carnall,lcarnallki@histats.com,Female,TRUE -740,Sharai,Rubrow,srubrowkj@hud.gov,Female,FALSE -741,Saundra,Sturror,ssturrorkk@unc.edu,Female,TRUE -742,Chandal,Baton,cbatonkl@ebay.com,Female,TRUE -743,Norma,Delmage,ndelmagekm@marriott.com,Female,TRUE -744,Giacomo,Staneland,gstanelandkn@stumbleupon.com,Male,FALSE -745,Roslyn,Noriega,rnoriegako@hp.com,Female,TRUE -746,Maurise,Beardsworth,mbeardsworthkp@merriam-webster.com,Polygender,FALSE -747,Dillie,Laister,dlaisterkq@nasa.gov,Male,FALSE -748,Naoma,Malan,nmalankr@wisc.edu,Female,TRUE -749,Fleurette,Lochead,flocheadks@mozilla.org,Female,TRUE -750,Kleon,Giacaponi,kgiacaponikt@pbs.org,Male,FALSE -751,Alissa,Getch,agetchku@ox.ac.uk,Polygender,FALSE -752,Brew,Pietri,bpietrikv@elegantthemes.com,Male,TRUE -753,Emlyn,Lasham,elashamkw@ftc.gov,Male,TRUE -754,Marinna,Corrington,mcorringtonkx@google.pl,Female,FALSE -755,Yuma,Atty,yattyky@homestead.com,Male,FALSE -756,Amanda,Mort,amortkz@gmpg.org,Female,TRUE -757,Kylen,Jauncey,kjaunceyl0@intel.com,Bigender,FALSE -758,Tadeo,Pygott,tpygottl1@salon.com,Male,FALSE -759,Braden,Dobrovolny,bdobrovolnyl2@friendfeed.com,Bigender,FALSE -760,Ileana,Mutter,imutterl3@de.vu,Female,FALSE -761,Adella,Smalcombe,asmalcombel4@ask.com,Female,TRUE -762,Donovan,Seabright,dseabrightl5@stumbleupon.com,Non-binary,FALSE -763,Thibaud,Salters,tsaltersl6@mapquest.com,Male,TRUE -764,Patrice,Tidball,ptidballl7@psu.edu,Female,TRUE -765,Minette,Oldford,moldfordl8@typepad.com,Female,FALSE -766,Dianne,Smalecombe,dsmalecombel9@bbc.co.uk,Female,FALSE -767,Redd,Barnfield,rbarnfieldla@booking.com,Male,TRUE -768,Ronnie,Silburn,rsilburnlb@techcrunch.com,Male,TRUE -769,Hermie,Brind,hbrindlc@senate.gov,Male,TRUE -770,Elayne,Abdon,eabdonld@ibm.com,Female,TRUE -771,Addie,Jiri,ajirile@purevolume.com,Male,FALSE -772,Olly,Beahan,obeahanlf@opensource.org,Female,TRUE -773,Kat,Faber,kfaberlg@slideshare.net,Female,TRUE -774,Chrissie,Lapides,clapideslh@blogspot.com,Male,FALSE -775,Giacobo,Nicholson,gnicholsonli@discovery.com,Male,TRUE -776,Maitilde,Southerill,msoutherilllj@clickbank.net,Female,TRUE -777,Shelly,Huxham,shuxhamlk@illinois.edu,Female,TRUE -778,Jamison,Sonner,jsonnerll@abc.net.au,Male,FALSE -779,Ervin,Yeardsley,eyeardsleylm@apple.com,Male,TRUE -780,Berton,Saunderson,bsaundersonln@walmart.com,Male,TRUE -781,Lillian,De Gregario,ldegregariolo@geocities.jp,Female,TRUE -782,Bone,Hickeringill,bhickeringilllp@indiegogo.com,Male,TRUE -783,Webster,Dallimore,wdallimorelq@pen.io,Male,FALSE -784,Liz,Rowsell,lrowselllr@purevolume.com,Bigender,FALSE -785,Lizzy,Hodge,lhodgels@tamu.edu,Female,FALSE -786,Shermie,Tenman,stenmanlt@blogger.com,Male,FALSE -787,Jenilee,Strewther,jstrewtherlu@uiuc.edu,Female,FALSE -788,Berni,Ollerhad,bollerhadlv@phpbb.com,Female,FALSE -789,Maire,Oneill,moneilllw@yelp.com,Female,FALSE -790,Jo,Geraghty,jgeraghtylx@elegantthemes.com,Male,TRUE -791,Maryjane,Crysell,mcrysellly@scientificamerican.com,Female,TRUE -792,Herminia,Drinnan,hdrinnanlz@biglobe.ne.jp,Female,TRUE -793,Kent,Barwood,kbarwoodm0@paginegialle.it,Male,TRUE -794,Jeremiah,Edlestone,jedlestonem1@addthis.com,Male,TRUE -795,Vere,Sawle,vsawlem2@latimes.com,Female,TRUE -796,Erinn,Timms,etimmsm3@geocities.jp,Female,FALSE -797,Marcellina,Muckley,mmuckleym4@globo.com,Female,FALSE -798,Kath,Staveley,kstaveleym5@unc.edu,Female,TRUE -799,Bob,Hymer,bhymerm6@360.cn,Agender,TRUE -800,Herbie,Getley,hgetleym7@odnoklassniki.ru,Male,FALSE -801,Shandeigh,Dongate,sdongatem8@biblegateway.com,Female,FALSE -802,Oralle,Lawton,olawtonm9@google.fr,Female,TRUE -803,Brady,Hambrook,bhambrookma@gravatar.com,Male,FALSE -804,Ario,Laurenzi,alaurenzimb@booking.com,Male,TRUE -805,Ernest,Simmonett,esimmonettmc@ameblo.jp,Male,TRUE -806,Maggi,Buckenhill,mbuckenhillmd@umich.edu,Female,TRUE -807,Christie,Bassingham,cbassinghamme@springer.com,Female,TRUE -808,Eugenie,Ickovits,eickovitsmf@walmart.com,Female,FALSE -809,Denni,Portman,dportmanmg@devhub.com,Female,TRUE -810,Blane,Huot,bhuotmh@usda.gov,Polygender,FALSE -811,Caterina,Fulcher,cfulchermi@unblog.fr,Female,FALSE -812,Godwin,Swallwell,gswallwellmj@biglobe.ne.jp,Male,FALSE -813,Viv,Roxbee,vroxbeemk@kickstarter.com,Female,TRUE -814,Cale,Game,cgameml@foxnews.com,Male,TRUE -815,Carlina,Calvert,ccalvertmm@nydailynews.com,Female,TRUE -816,Portie,Haukey,phaukeymn@mlb.com,Male,FALSE -817,Meta,Ost,mostmo@wikimedia.org,Female,FALSE -818,Robers,Dyer,rdyermp@msn.com,Male,TRUE -819,Genia,Cufley,gcufleymq@webnode.com,Female,FALSE -820,Vernon,Reinger,vreingermr@yale.edu,Genderfluid,FALSE -821,Waite,Gillicuddy,wgillicuddyms@engadget.com,Male,FALSE -822,Travus,Redmore,tredmoremt@si.edu,Male,TRUE -823,Carmine,Treadaway,ctreadawaymu@nasa.gov,Bigender,TRUE -824,Derby,O'Moylane,domoylanemv@sun.com,Male,FALSE -825,Lynn,Petrescu,lpetrescumw@who.int,Male,FALSE -826,Carole,Loffel,cloffelmx@rambler.ru,Female,TRUE -827,Leland,Scaddon,lscaddonmy@harvard.edu,Male,FALSE -828,Adda,Stacy,astacymz@seesaa.net,Female,TRUE -829,Jocelyne,Jeenes,jjeenesn0@blog.com,Female,FALSE -830,Hartwell,Muldowney,hmuldowneyn1@cloudflare.com,Male,TRUE -831,Caitrin,Doles,cdolesn2@ihg.com,Female,FALSE -832,Olivier,Buske,obusken3@salon.com,Male,TRUE -833,Philippa,Burgwin,pburgwinn4@baidu.com,Female,TRUE -834,Barbabra,Gallahar,bgallaharn5@discovery.com,Female,FALSE -835,Alasdair,Moultrie,amoultrien6@cnet.com,Male,FALSE -836,Demetria,Chalice,dchalicen7@sciencedaily.com,Female,FALSE -837,Kip,Durman,kdurmann8@state.gov,Male,TRUE -838,Lynnette,Hartop,lhartopn9@bandcamp.com,Female,TRUE -839,Catherine,Da Costa,cdacostana@cyberchimps.com,Female,TRUE -840,Clayson,MacDaid,cmacdaidnb@xrea.com,Male,FALSE -841,Lorin,Cordrey,lcordreync@princeton.edu,Male,FALSE -842,Cami,Todd,ctoddnd@shareasale.com,Female,FALSE -843,Guillema,Degnen,gdegnenne@ezinearticles.com,Female,FALSE -844,Dixie,Foddy,dfoddynf@wordpress.com,Female,TRUE -845,Rogerio,Gioan,rgioanng@wufoo.com,Male,FALSE -846,Belinda,Kenealy,bkenealynh@sciencedirect.com,Female,TRUE -847,Lexine,Darnody,ldarnodyni@studiopress.com,Female,TRUE -848,Heall,Clausen,hclausennj@123-reg.co.uk,Male,TRUE -849,Skippy,Baumann,sbaumannnk@blogtalkradio.com,Genderqueer,FALSE -850,Amos,Mitchenson,amitchensonnl@auda.org.au,Male,TRUE -851,Trescha,Parres,tparresnm@symantec.com,Female,TRUE -852,Hersh,Sprosson,hsprossonnn@youtu.be,Male,TRUE -853,Cass,Andrews,candrewsno@163.com,Female,TRUE -854,Morty,Soles,msolesnp@devhub.com,Male,TRUE -855,Kerwin,Stemson,kstemsonnq@yahoo.co.jp,Male,TRUE -856,Merrel,Dowsey,mdowseynr@msu.edu,Male,FALSE -857,Tyler,Baltrushaitis,tbaltrushaitisns@diigo.com,Male,FALSE -858,Osbert,Kindell,okindellnt@merriam-webster.com,Male,TRUE -859,Nerti,Malcolm,nmalcolmnu@samsung.com,Female,FALSE -860,Basia,Monckman,bmonckmannv@seesaa.net,Female,TRUE -861,Amalee,Kingswood,akingswoodnw@t-online.de,Female,FALSE -862,Dalston,MacDonogh,dmacdonoghnx@mysql.com,Genderfluid,TRUE -863,Meade,Tyrwhitt,mtyrwhittny@ucsd.edu,Male,TRUE -864,Gallagher,Perry,gperrynz@google.nl,Male,FALSE -865,Bonnee,Sallery,bsalleryo0@mysql.com,Female,FALSE -866,Sheff,Gavey,sgaveyo1@cyberchimps.com,Male,TRUE -867,Petronilla,Lambrook,plambrooko2@baidu.com,Female,FALSE -868,Dieter,Facher,dfachero3@techcrunch.com,Male,FALSE -869,Adolf,Bicksteth,abickstetho4@constantcontact.com,Male,TRUE -870,Annmaria,Speakman,aspeakmano5@yahoo.com,Female,TRUE -871,Barron,Beinisch,bbeinischo6@ted.com,Male,FALSE -872,Ammamaria,Muat,amuato7@addthis.com,Female,FALSE -873,Roland,Kellick,rkellicko8@csmonitor.com,Male,FALSE -874,Felice,Piggins,fpigginso9@4shared.com,Female,FALSE -875,Maryjo,Dalyell,mdalyelloa@topsy.com,Female,TRUE -876,Geralda,Fairney,gfairneyob@a8.net,Female,TRUE -877,Riobard,Sarginson,rsarginsonoc@msu.edu,Male,TRUE -878,Ursulina,Swiffan,uswiffanod@ucoz.ru,Female,FALSE -879,Delmore,McCafferty,dmccaffertyoe@opensource.org,Male,TRUE -880,Ardelle,Blenkin,ablenkinof@privacy.gov.au,Female,TRUE -881,Neila,Mullarkey,nmullarkeyog@reverbnation.com,Female,FALSE -882,Orelle,Pym,opymoh@xrea.com,Female,FALSE -883,Carl,Danbury,cdanburyoi@yandex.ru,Male,TRUE -884,Tuckie,Warmington,twarmingtonoj@com.com,Male,TRUE -885,Randal,Toth,rtothok@soundcloud.com,Male,TRUE -886,Aviva,Erik,aerikol@salon.com,Female,FALSE -887,Kory,Ceeley,kceeleyom@is.gd,Male,TRUE -888,Garrek,Samme,gsammeon@marriott.com,Male,FALSE -889,Margaux,Kenefick,mkenefickoo@unblog.fr,Female,FALSE -890,Che,Pietrzyk,cpietrzykop@pen.io,Male,TRUE -891,Brook,Northgraves,bnorthgravesoq@cbsnews.com,Female,TRUE -892,Moritz,Walster,mwalsteror@bloglovin.com,Male,TRUE -893,Gerianna,Sier,gsieros@arizona.edu,Female,TRUE -894,Hy,McMurty,hmcmurtyot@walmart.com,Male,TRUE -895,Eadith,Hufton,ehuftonou@marriott.com,Female,TRUE -896,Krishnah,Blankley,kblankleyov@acquirethisname.com,Male,TRUE -897,Courtenay,Posse,cposseow@purevolume.com,Female,FALSE -898,Fayina,Jurca,fjurcaox@people.com.cn,Female,FALSE -899,Reinold,Gailor,rgailoroy@webmd.com,Male,TRUE -900,Genevieve,Aberchirder,gaberchirderoz@parallels.com,Female,FALSE -901,Ulrich,Frankling,ufranklingp0@ycombinator.com,Male,FALSE -902,Elfrieda,Rayner,eraynerp1@1und1.de,Genderfluid,TRUE -903,Abelard,Isoldi,aisoldip2@odnoklassniki.ru,Male,TRUE -904,Jerry,Dimitru,jdimitrup3@nih.gov,Male,FALSE -905,Nerte,Maypes,nmaypesp4@cnbc.com,Female,TRUE -906,Moses,D'Orsay,mdorsayp5@clickbank.net,Male,TRUE -907,Gerek,Skeel,gskeelp6@etsy.com,Male,TRUE -908,Gregorio,Artinstall,gartinstallp7@deviantart.com,Male,FALSE -909,Suzanne,Stendell,sstendellp8@admin.ch,Female,TRUE -910,Ange,Meece,ameecep9@techcrunch.com,Female,FALSE -911,Berke,Pavelka,bpavelkapa@csmonitor.com,Male,FALSE -912,Arlie,Spurdens,aspurdenspb@ustream.tv,Female,FALSE -913,Gabriellia,Dennistoun,gdennistounpc@bing.com,Female,TRUE -914,Nevin,Joules,njoulespd@chicagotribune.com,Male,TRUE -915,Arron,Twitty,atwittype@prlog.org,Male,TRUE -916,Jeffie,Ramsey,jramseypf@macromedia.com,Male,TRUE -917,Marlie,Field,mfieldpg@wikipedia.org,Bigender,TRUE -918,Lynna,Andrelli,landrelliph@cargocollective.com,Non-binary,TRUE -919,Nonna,Yandle,nyandlepi@samsung.com,Female,FALSE -920,Berti,Newham,bnewhampj@tinyurl.com,Female,TRUE -921,Reina,Geraudy,rgeraudypk@nbcnews.com,Female,FALSE -922,Heall,Gerrett,hgerrettpl@ycombinator.com,Male,TRUE -923,Davita,Quincee,dquinceepm@ftc.gov,Female,FALSE -924,Frants,Levermore,flevermorepn@merriam-webster.com,Male,FALSE -925,Kizzee,Sinfield,ksinfieldpo@who.int,Female,TRUE -926,Brittani,Hynde,bhyndepp@ucoz.com,Female,FALSE -927,Arluene,Knifton,akniftonpq@amazon.com,Female,FALSE -928,D'arcy,Duck,dduckpr@army.mil,Agender,TRUE -929,Kathleen,Filson,kfilsonps@sbwire.com,Female,FALSE -930,Court,Sincock,csincockpt@springer.com,Male,FALSE -931,Kort,Banford,kbanfordpu@symantec.com,Male,FALSE -932,Sophia,Lauthian,slauthianpv@earthlink.net,Female,FALSE -933,Jody,Pennyman,jpennymanpw@jimdo.com,Male,TRUE -934,Mano,Eke,mekepx@dot.gov,Male,TRUE -935,Kissiah,Challin,kchallinpy@vkontakte.ru,Female,TRUE -936,Matty,Winsome,mwinsomepz@dyndns.org,Agender,FALSE -937,Auroora,Criple,acripleq0@github.com,Female,TRUE -938,Johnny,Grebert,jgrebertq1@last.fm,Agender,TRUE -939,Bill,Pavolini,bpavoliniq2@japanpost.jp,Male,TRUE -940,Chevalier,Verrill,cverrillq3@craigslist.org,Male,TRUE -941,Tracie,Frake,tfrakeq4@ehow.com,Male,TRUE -942,Dietrich,Mulloch,dmullochq5@upenn.edu,Male,TRUE -943,Genia,Baake,gbaakeq6@163.com,Female,FALSE -944,Meghan,Layus,mlayusq7@addthis.com,Female,FALSE -945,Xerxes,Djorvic,xdjorvicq8@paypal.com,Male,TRUE -946,Aveline,Daber,adaberq9@people.com.cn,Female,TRUE -947,Zorana,Perrins,zperrinsqa@deviantart.com,Female,FALSE -948,Dorette,Rabbitt,drabbittqb@java.com,Female,FALSE -949,Damien,Van Arsdall,dvanarsdallqc@columbia.edu,Male,FALSE -950,Ambros,Kaasmann,akaasmannqd@narod.ru,Male,FALSE -951,Chase,Dammarell,cdammarellqe@dell.com,Male,FALSE -952,Vidovik,Gatfield,vgatfieldqf@4shared.com,Male,FALSE -953,Di,Fazzioli,dfazzioliqg@shop-pro.jp,Female,TRUE -954,Jerry,Kirsopp,jkirsoppqh@about.me,Female,TRUE -955,Patton,Jouhan,pjouhanqi@odnoklassniki.ru,Male,TRUE -956,Aylmar,Bridgens,abridgensqj@who.int,Male,TRUE -957,Katerine,Tooth,ktoothqk@walmart.com,Polygender,FALSE -958,Yoshiko,Trasler,ytraslerql@seesaa.net,Female,TRUE -959,Cecilio,Orsman,corsmanqm@youku.com,Male,FALSE -960,Chet,Garmons,cgarmonsqn@last.fm,Male,TRUE -961,Moyna,Walley,mwalleyqo@nps.gov,Female,TRUE -962,Willamina,Agget,waggetqp@webs.com,Female,TRUE -963,Artur,Bisseker,abissekerqq@delicious.com,Male,FALSE -964,Leslie,Toffolo,ltoffoloqr@yolasite.com,Polygender,TRUE -965,Kara-lynn,McCue,kmccueqs@indiatimes.com,Female,TRUE -966,Rebe,Francesc,rfrancescqt@cloudflare.com,Female,TRUE -967,Ernie,Harron,eharronqu@sogou.com,Male,TRUE -968,Sanders,Acuna,sacunaqv@over-blog.com,Genderfluid,TRUE -969,Neala,Esmonde,nesmondeqw@bloglovin.com,Female,TRUE -970,Brendin,Coathup,bcoathupqx@usda.gov,Male,TRUE -971,Delly,Atherley,datherleyqy@sakura.ne.jp,Female,FALSE -972,Prent,Lord,plordqz@imageshack.us,Male,FALSE -973,Andree,Parsisson,aparsissonr0@hp.com,Female,FALSE -974,Trudie,Simacek,tsimacekr1@over-blog.com,Female,FALSE -975,Dennie,Tedman,dtedmanr2@fda.gov,Male,TRUE -976,Mamie,Watters,mwattersr3@aboutads.info,Female,TRUE -977,Teodora,Phalip,tphalipr4@cpanel.net,Female,FALSE -978,Binny,Wickrath,bwickrathr5@indiegogo.com,Female,FALSE -979,Marji,Winnister,mwinnisterr6@amazon.co.uk,Female,TRUE -980,Alecia,Aris,aarisr7@cdc.gov,Female,FALSE -981,Vincenz,Lawrey,vlawreyr8@cisco.com,Male,FALSE -982,Glad,Bing,gbingr9@youtube.com,Female,TRUE -983,Delphine,Heamus,dheamusra@godaddy.com,Female,FALSE -984,Juana,Potapczuk,jpotapczukrb@wsj.com,Female,FALSE -985,Hershel,Spadotto,hspadottorc@amazonaws.com,Male,FALSE -986,Harrietta,Backs,hbacksrd@slideshare.net,Female,TRUE -987,Ginger,Mellers,gmellersre@blog.com,Male,TRUE -988,Asher,Purbrick,apurbrickrf@cornell.edu,Agender,FALSE -989,Rhiamon,Twoohy,rtwoohyrg@seesaa.net,Female,TRUE -990,Elli,Hurndall,ehurndallrh@marketwatch.com,Female,FALSE -991,Jordanna,Borth,jborthri@examiner.com,Female,FALSE -992,Lanna,Wahncke,lwahnckerj@discuz.net,Female,TRUE -993,Shani,Eblein,sebleinrk@lulu.com,Female,FALSE -994,Jaquelyn,Scraney,jscraneyrl@github.com,Female,TRUE -995,Eliza,Shallow,eshallowrm@fc2.com,Bigender,TRUE -996,Shirley,Oldred,soldredrn@pcworld.com,Female,TRUE -997,Merrili,Stephen,mstephenro@fc2.com,Female,FALSE -998,Ingelbert,Rainford,irainfordrp@bigcartel.com,Male,FALSE -999,Pepillo,Medlar,pmedlarrq@whitehouse.gov,Male,TRUE -1000,Melany,Brazil,mbrazilrr@opera.com,Female,TRUE \ No newline at end of file +customer_id,first_name,last_name,email,gender,is_new_customer,date_added +1,Geodude,Hills,bhills0@altervista.org,Male,FALSE,2022-01-01 +2,Mew,Coxhead,mcoxhead1@symantec.com,Genderfluid,TRUE,2022-01-06 +3,Mewtwo,Redish,aredish2@last.fm,Genderqueer,FALSE,2022-01-13 +4,Charizard,Basant,lbasant3@dedecms.com,Female,TRUE,2022-02-01 +5,Snorlax,Pokemon,the_email@dedecms.com,Male,TRUE,2022-02-03 \ No newline at end of file diff --git a/integration_tests/seeds/source/fact_orders_source.csv b/integration_tests/seeds/source/fact_orders_source.csv index 7b4f17df..d9fe2846 100644 --- a/integration_tests/seeds/source/fact_orders_source.csv +++ b/integration_tests/seeds/source/fact_orders_source.csv @@ -1,1001 +1,11 @@ order_id,order_country,order_total,had_discount,customer_id,order_date -1,Russia,79,false,643,2022-04-28 -2,Mauritius,88,false,84,2022-01-20 -3,Peru,16,false,802,2022-05-13 -4,Kazakhstan,27,true,803,2022-01-06 -5,Portugal,53,false,6,2022-03-08 -6,China,8,false,966,2022-01-21 -7,Germany,1,true,971,2022-04-22 -8,Greenland,82,true,789,2022-05-15 -9,Bangladesh,72,false,997,2022-03-03 -10,Sweden,98,false,92,2022-03-13 -11,Sweden,67,true,45,2022-05-21 -12,Czech Republic,57,false,83,2022-05-21 -13,Philippines,2,true,833,2022-04-25 -14,Estonia,35,true,444,2022-01-19 -15,Philippines,1,false,268,2022-02-21 -16,China,39,true,407,2022-01-18 -17,Argentina,90,true,679,2022-02-28 -18,China,94,false,631,2022-04-02 -19,China,28,false,992,2022-04-07 -20,Sweden,20,false,623,2022-04-13 -21,Indonesia,46,true,735,2022-01-22 -22,Indonesia,71,true,544,2022-05-24 -23,Colombia,44,false,285,2022-03-03 -24,Brazil,54,true,397,2022-03-19 -25,Moldova,60,false,998,2022-03-09 -26,China,10,false,422,2022-05-25 -27,Russia,93,true,737,2022-05-04 -28,Netherlands,2,false,788,2022-05-20 -29,China,32,true,816,2022-01-09 -30,China,29,true,235,2022-05-09 -31,Azerbaijan,92,true,84,2022-02-20 -32,Indonesia,47,false,113,2022-04-07 -33,Sweden,76,true,416,2022-05-15 -34,Philippines,56,true,226,2022-05-20 -35,China,76,false,212,2022-01-31 -36,Japan,44,true,594,2022-05-19 -37,China,26,true,940,2022-03-07 -38,China,74,false,298,2022-03-28 -39,Russia,77,true,301,2022-04-01 -40,Thailand,50,false,634,2022-03-12 -41,Indonesia,15,false,806,2022-01-03 -42,Sweden,95,true,477,2022-03-28 -43,France,65,false,103,2022-01-02 -44,United States,79,false,288,2022-04-26 -45,United Kingdom,91,false,425,2022-01-24 -46,Colombia,93,false,868,2022-01-28 -47,China,18,true,578,2022-02-26 -48,Indonesia,37,false,220,2022-03-14 -49,Mauritius,16,true,106,2022-02-10 -50,Russia,3,false,276,2022-05-08 -51,Indonesia,7,false,690,2022-02-08 -52,Russia,32,true,462,2022-03-06 -53,Indonesia,92,true,973,2022-05-17 -54,Spain,63,false,383,2022-05-26 -55,United States,27,true,618,2022-01-04 -56,Peru,9,false,85,2022-05-29 -57,Brazil,52,false,332,2022-05-11 -58,Macedonia,60,false,702,2022-01-03 -59,Russia,92,false,807,2022-04-10 -60,Indonesia,87,true,25,2022-02-02 -61,Ecuador,90,false,993,2022-02-01 -62,Russia,72,false,504,2022-03-19 -63,Poland,84,true,244,2022-05-02 -64,China,47,true,688,2022-01-11 -65,China,30,false,46,2022-03-24 -66,Indonesia,18,false,78,2022-05-13 -67,Guatemala,63,false,86,2022-03-18 -68,China,41,true,946,2022-02-11 -69,Panama,77,false,183,2022-01-10 -70,Portugal,72,false,75,2022-02-28 -71,China,20,false,211,2022-02-27 -72,China,89,false,693,2022-05-09 -73,China,44,true,237,2022-02-06 -74,Thailand,44,false,269,2022-04-09 -75,France,43,false,734,2022-03-09 -76,China,28,true,826,2022-05-15 -77,South Africa,84,false,1,2022-03-18 -78,Netherlands,68,true,541,2022-02-25 -79,China,10,true,387,2022-04-16 -80,Palestinian Territory,72,false,587,2022-01-13 -81,Canada,27,false,241,2022-01-19 -82,Japan,76,true,331,2022-04-18 -83,Ukraine,10,true,41,2022-04-13 -84,Russia,17,true,881,2022-03-11 -85,Germany,93,true,256,2022-01-06 -86,China,64,true,220,2022-05-30 -87,China,95,false,987,2022-04-29 -88,Honduras,27,true,698,2022-01-24 -89,Philippines,14,false,253,2022-02-24 -90,Argentina,74,true,680,2022-05-21 -91,Portugal,18,false,431,2022-02-12 -92,Indonesia,34,true,914,2022-03-25 -93,Indonesia,73,true,849,2022-01-31 -94,China,37,true,628,2022-02-05 -95,Mali,47,true,924,2022-01-12 -96,Philippines,75,false,269,2022-01-27 -97,Portugal,97,false,329,2022-04-02 -98,Kazakhstan,44,false,809,2022-05-03 -99,Russia,55,true,549,2022-05-12 -100,China,80,false,206,2022-02-11 -101,China,15,false,573,2022-04-11 -102,Russia,99,false,104,2022-01-08 -103,Indonesia,69,false,259,2022-01-04 -104,Mayotte,60,false,760,2022-01-27 -105,Sweden,56,false,816,2022-02-02 -106,Poland,9,false,974,2022-02-12 -107,Poland,35,true,289,2022-02-25 -108,Netherlands,88,false,41,2022-05-31 -109,China,57,false,506,2022-05-19 -110,Malta,87,true,963,2022-02-22 -111,Canada,95,true,240,2022-04-30 -112,Poland,7,true,470,2022-02-27 -113,Peru,44,true,318,2022-02-26 -114,China,84,false,430,2022-02-25 -115,Poland,10,true,348,2022-03-24 -116,South Korea,16,false,123,2022-02-20 -117,Canada,5,true,910,2022-04-15 -118,China,95,false,979,2022-04-08 -119,China,61,false,64,2022-02-19 -120,Iran,6,true,802,2022-02-25 -121,Brazil,23,true,644,2022-02-15 -122,Japan,76,true,615,2022-03-25 -123,Libya,37,true,654,2022-03-03 -124,Indonesia,12,true,354,2022-04-08 -125,Czech Republic,54,true,256,2022-05-31 -126,Russia,49,false,520,2022-05-17 -127,Russia,11,false,685,2022-04-19 -128,Indonesia,48,true,709,2022-01-14 -129,Philippines,5,true,551,2022-02-12 -130,South Africa,82,true,29,2022-05-10 -131,China,63,true,870,2022-01-08 -132,Philippines,75,true,264,2022-01-10 -133,Nigeria,20,true,316,2022-04-01 -134,Philippines,92,false,835,2022-04-16 -135,Brazil,24,true,41,2022-05-30 -136,Syria,27,false,227,2022-01-16 -137,Ukraine,75,false,329,2022-02-02 -138,Egypt,85,true,412,2022-03-21 -139,China,41,true,273,2022-02-21 -140,China,34,true,241,2022-03-22 -141,Argentina,93,true,540,2022-03-24 -142,Czech Republic,6,true,828,2022-05-03 -143,China,61,true,350,2022-01-27 -144,China,79,true,845,2022-04-15 -145,Tanzania,56,false,446,2022-03-21 -146,Mexico,95,true,951,2022-02-16 -147,Poland,31,false,306,2022-05-01 -148,Peru,9,false,713,2022-05-17 -149,Indonesia,56,true,947,2022-05-15 -150,China,13,false,655,2022-03-02 -151,China,58,true,152,2022-04-27 -152,China,24,true,148,2022-05-07 -153,Iran,84,true,573,2022-02-01 -154,Sweden,26,false,985,2022-03-24 -155,Indonesia,50,false,697,2022-05-21 -156,Sweden,18,true,881,2022-03-09 -157,Indonesia,7,false,711,2022-05-01 -158,Japan,27,true,714,2022-02-14 -159,Nigeria,34,false,483,2022-01-09 -160,China,44,false,640,2022-01-01 -161,Jordan,58,true,670,2022-02-13 -162,Peru,77,false,877,2022-03-19 -163,Turkey,98,true,430,2022-05-10 -164,Brazil,1,true,459,2022-01-14 -165,Sweden,13,true,597,2022-05-26 -166,China,30,false,354,2022-05-18 -167,Cyprus,52,false,476,2022-05-10 -168,China,39,true,266,2022-03-27 -169,Bosnia and Herzegovina,61,true,677,2022-04-12 -170,Sweden,6,false,301,2022-05-11 -171,Peru,25,true,558,2022-05-20 -172,Croatia,86,true,518,2022-03-11 -173,China,78,false,800,2022-01-20 -174,China,24,true,162,2022-04-07 -175,Azerbaijan,10,false,345,2022-05-26 -176,China,22,false,969,2022-03-11 -177,China,45,true,578,2022-01-12 -178,Mongolia,37,false,739,2022-03-06 -179,Chile,71,false,395,2022-02-24 -180,Portugal,42,false,912,2022-04-14 -181,China,59,false,248,2022-01-11 -182,United States,90,false,608,2022-04-01 -183,Sierra Leone,24,true,365,2022-05-14 -184,Mexico,31,false,431,2022-01-28 -185,China,13,true,2,2022-03-08 -186,Bulgaria,41,false,235,2022-02-20 -187,Indonesia,25,false,510,2022-04-18 -188,France,74,false,218,2022-03-02 -189,Bosnia and Herzegovina,3,false,844,2022-04-24 -190,Ecuador,93,false,382,2022-02-20 -191,Indonesia,91,true,896,2022-03-10 -192,China,6,false,860,2022-01-09 -193,Armenia,36,true,510,2022-05-19 -194,Indonesia,44,true,509,2022-05-08 -195,Venezuela,47,true,519,2022-04-22 -196,China,83,true,620,2022-04-16 -197,Russia,84,false,126,2022-01-30 -198,China,11,true,525,2022-04-04 -199,Madagascar,75,false,420,2022-02-08 -200,China,5,false,938,2022-04-11 -201,China,10,true,993,2022-02-09 -202,Poland,46,true,724,2022-03-09 -203,Israel,20,false,244,2022-02-08 -204,Indonesia,89,false,45,2022-04-07 -205,Philippines,28,false,870,2022-02-25 -206,China,98,false,85,2022-04-16 -207,China,54,true,963,2022-04-17 -208,China,10,true,693,2022-03-31 -209,Afghanistan,56,true,641,2022-04-26 -210,France,98,false,416,2022-03-25 -211,Finland,33,true,550,2022-04-17 -212,Croatia,20,true,897,2022-01-14 -213,China,55,false,418,2022-04-09 -214,Argentina,50,false,292,2022-03-02 -215,China,56,true,930,2022-02-08 -216,Sweden,94,false,141,2022-03-20 -217,China,67,false,999,2022-04-07 -218,Norway,2,true,387,2022-03-14 -219,Croatia,66,false,624,2022-01-21 -220,China,94,true,525,2022-05-19 -221,Cyprus,34,false,580,2022-05-28 -222,China,100,true,778,2022-01-07 -223,Poland,30,true,148,2022-01-30 -224,Poland,31,false,196,2022-04-03 -225,Philippines,27,false,110,2022-01-09 -226,Israel,32,true,650,2022-03-25 -227,Brazil,71,false,649,2022-03-09 -228,Indonesia,50,false,245,2022-04-02 -229,Nigeria,73,false,996,2022-03-24 -230,China,7,false,35,2022-01-10 -231,Greece,46,false,786,2022-05-14 -232,Brazil,34,false,940,2022-04-01 -233,Thailand,84,false,493,2022-02-12 -234,Guatemala,22,true,835,2022-05-22 -235,Poland,73,false,682,2022-02-24 -236,Greece,79,true,440,2022-02-03 -237,France,87,false,109,2022-01-15 -238,Russia,40,true,727,2022-04-23 -239,China,55,false,702,2022-03-08 -240,China,100,false,710,2022-03-05 -241,Nicaragua,38,true,249,2022-04-25 -242,Sweden,14,true,164,2022-05-10 -243,South Africa,92,false,942,2022-04-22 -244,Philippines,23,true,312,2022-02-05 -245,Sweden,12,false,97,2022-02-05 -246,China,74,true,142,2022-01-13 -247,Canada,64,true,784,2022-04-26 -248,China,16,true,778,2022-01-26 -249,Philippines,85,false,134,2022-01-02 -250,China,40,false,152,2022-03-28 -251,Thailand,51,true,34,2022-02-11 -252,Thailand,57,true,510,2022-05-21 -253,Philippines,76,false,78,2022-01-01 -254,Portugal,76,false,119,2022-04-17 -255,Portugal,20,false,284,2022-04-01 -256,China,72,false,848,2022-01-15 -257,China,77,false,25,2022-02-07 -258,China,90,false,350,2022-02-25 -259,Colombia,7,true,305,2022-04-29 -260,Philippines,86,false,432,2022-02-13 -261,Brazil,19,false,223,2022-04-10 -262,Ghana,64,true,96,2022-05-31 -263,Poland,24,true,762,2022-05-13 -264,Egypt,61,true,668,2022-04-08 -265,France,4,true,610,2022-01-15 -266,Portugal,56,true,374,2022-05-10 -267,Morocco,44,false,81,2022-02-20 -268,Poland,64,false,89,2022-04-06 -269,Russia,98,false,157,2022-03-03 -270,Indonesia,72,false,94,2022-02-02 -271,United States,54,true,370,2022-05-19 -272,Russia,8,true,720,2022-01-29 -273,Japan,24,false,915,2022-02-22 -274,Philippines,17,true,670,2022-02-21 -275,Portugal,29,false,870,2022-04-12 -276,Iran,100,false,600,2022-03-03 -277,Serbia,80,false,450,2022-04-17 -278,Sweden,33,false,820,2022-04-11 -279,Poland,63,true,393,2022-04-06 -280,Brazil,95,true,322,2022-02-27 -281,Hungary,86,true,187,2022-04-28 -282,Guatemala,9,false,448,2022-05-17 -283,China,20,true,894,2022-01-12 -284,Nigeria,67,true,279,2022-01-18 -285,Finland,49,true,89,2022-05-27 -286,China,96,false,159,2022-05-06 -287,Palestinian Territory,73,true,155,2022-02-03 -288,Russia,12,true,633,2022-01-21 -289,China,96,true,856,2022-02-03 -290,France,18,true,967,2022-02-26 -291,South Africa,36,true,903,2022-01-10 -292,Chile,27,false,766,2022-05-24 -293,China,77,true,416,2022-04-18 -294,Ukraine,1,false,711,2022-02-06 -295,Thailand,48,true,273,2022-02-15 -296,Indonesia,12,true,297,2022-03-18 -297,Brazil,45,false,964,2022-04-22 -298,Mozambique,7,false,986,2022-03-28 -299,Nepal,3,false,389,2022-02-04 -300,Russia,38,true,846,2022-01-18 -301,Sweden,73,true,399,2022-05-10 -302,Armenia,15,true,673,2022-01-10 -303,Madagascar,4,true,658,2022-01-06 -304,Vietnam,75,true,163,2022-03-05 -305,Honduras,52,true,179,2022-05-13 -306,Chad,97,false,535,2022-05-26 -307,Philippines,40,true,757,2022-04-18 -308,Swaziland,75,true,97,2022-01-15 -309,Philippines,95,true,188,2022-02-03 -310,Serbia,84,true,699,2022-04-08 -311,Sweden,79,false,351,2022-01-08 -312,China,92,true,570,2022-02-27 -313,Pakistan,90,false,410,2022-05-18 -314,China,27,true,632,2022-03-29 -315,Japan,96,true,507,2022-04-24 -316,China,31,true,663,2022-03-28 -317,China,46,false,242,2022-02-05 -318,Russia,60,true,423,2022-03-20 -319,Indonesia,66,true,36,2022-03-19 -320,Portugal,60,true,518,2022-04-09 -321,Portugal,66,true,647,2022-02-25 -322,Dominican Republic,83,true,597,2022-02-13 -323,China,2,true,451,2022-02-13 -324,Portugal,61,false,126,2022-04-13 -325,Czech Republic,74,true,917,2022-02-20 -326,Central African Republic,17,false,578,2022-03-19 -327,Thailand,22,true,5,2022-04-01 -328,Pakistan,53,true,837,2022-01-14 -329,China,52,true,858,2022-03-18 -330,Portugal,93,true,58,2022-05-29 -331,Indonesia,7,false,610,2022-01-25 -332,Russia,89,true,310,2022-05-29 -333,Russia,44,false,788,2022-02-10 -334,Indonesia,84,true,989,2022-02-03 -335,Indonesia,100,true,308,2022-04-02 -336,Slovenia,84,true,100,2022-05-03 -337,Serbia,82,true,401,2022-01-27 -338,Indonesia,14,true,624,2022-04-30 -339,Greece,30,false,970,2022-04-13 -340,Russia,54,true,452,2022-01-09 -341,China,35,false,437,2022-05-22 -342,Philippines,93,false,826,2022-03-10 -343,Indonesia,10,false,181,2022-05-30 -344,Russia,49,true,7,2022-05-14 -345,Portugal,72,false,457,2022-01-24 -346,Bulgaria,52,true,238,2022-01-22 -347,Czech Republic,29,false,42,2022-02-16 -348,Brazil,28,false,793,2022-01-24 -349,Japan,40,true,377,2022-01-30 -350,Philippines,9,true,298,2022-01-28 -351,Sweden,16,true,1,2022-02-21 -352,Indonesia,17,true,758,2022-04-23 -353,Indonesia,31,false,343,2022-03-15 -354,China,81,true,983,2022-03-01 -355,Tajikistan,50,false,681,2022-01-22 -356,Peru,95,false,467,2022-01-21 -357,France,26,false,337,2022-05-06 -358,South Africa,40,true,98,2022-02-12 -359,Poland,35,true,732,2022-04-25 -360,Serbia,51,false,94,2022-04-28 -361,Uzbekistan,95,true,771,2022-02-12 -362,China,18,true,921,2022-01-21 -363,China,56,false,945,2022-01-02 -364,United States,56,false,615,2022-01-19 -365,Indonesia,70,false,179,2022-01-05 -366,Ireland,79,true,752,2022-02-15 -367,Argentina,48,false,298,2022-01-18 -368,Egypt,75,true,680,2022-02-02 -369,Uzbekistan,21,false,683,2022-04-23 -370,Philippines,73,true,638,2022-04-23 -371,Uganda,75,true,835,2022-01-12 -372,Syria,87,true,584,2022-02-11 -373,China,60,true,389,2022-02-02 -374,Russia,60,false,937,2022-05-09 -375,Russia,100,false,921,2022-05-20 -376,Indonesia,46,true,878,2022-01-09 -377,Philippines,60,false,922,2022-01-31 -378,Indonesia,25,false,565,2022-05-17 -379,Peru,39,false,276,2022-05-20 -380,Portugal,69,true,282,2022-02-10 -381,Syria,50,false,790,2022-05-20 -382,Russia,97,false,170,2022-03-07 -383,Mauritius,94,false,417,2022-05-04 -384,Poland,88,true,443,2022-01-15 -385,Indonesia,24,false,32,2022-04-16 -386,China,6,false,515,2022-01-11 -387,Indonesia,54,true,862,2022-04-17 -388,China,92,true,629,2022-02-24 -389,France,48,true,97,2022-05-23 -390,Portugal,81,false,408,2022-05-14 -391,China,28,true,311,2022-03-21 -392,Peru,27,false,794,2022-05-12 -393,United States,28,false,841,2022-04-09 -394,United States,21,false,379,2022-04-07 -395,China,77,true,374,2022-01-05 -396,France,54,true,299,2022-04-22 -397,Indonesia,24,true,227,2022-05-04 -398,Russia,35,true,741,2022-01-28 -399,Brazil,46,false,488,2022-01-18 -400,Portugal,24,false,487,2022-01-23 -401,Russia,73,true,752,2022-02-16 -402,France,76,true,721,2022-03-11 -403,Poland,33,true,398,2022-01-20 -404,United States,68,true,501,2022-01-28 -405,Serbia,11,false,202,2022-02-11 -406,Czech Republic,67,true,77,2022-03-22 -407,China,29,true,189,2022-03-31 -408,Philippines,95,false,437,2022-01-26 -409,China,9,true,276,2022-04-18 -410,Philippines,28,true,112,2022-04-21 -411,China,71,false,440,2022-03-13 -412,Cape Verde,80,false,186,2022-04-18 -413,Sweden,47,false,283,2022-03-04 -414,Cambodia,69,true,200,2022-03-22 -415,Sweden,19,true,429,2022-02-04 -416,Ukraine,55,true,275,2022-03-14 -417,Russia,73,false,12,2022-04-27 -418,Indonesia,65,false,27,2022-03-28 -419,Russia,79,true,65,2022-04-23 -420,Philippines,93,false,208,2022-03-15 -421,China,49,true,148,2022-02-25 -422,Thailand,89,true,557,2022-02-27 -423,Indonesia,48,false,875,2022-01-08 -424,France,60,false,257,2022-01-28 -425,Brazil,96,false,538,2022-03-28 -426,China,99,false,891,2022-05-11 -427,Philippines,79,true,984,2022-02-26 -428,China,14,true,552,2022-05-14 -429,Poland,70,false,857,2022-05-12 -430,Indonesia,82,false,640,2022-05-27 -431,China,55,false,677,2022-04-16 -432,China,29,false,472,2022-05-01 -433,Dominican Republic,45,true,424,2022-04-18 -434,Philippines,41,false,811,2022-03-07 -435,Indonesia,68,false,256,2022-01-30 -436,China,60,true,123,2022-05-27 -437,Philippines,27,false,543,2022-01-26 -438,Guinea,93,false,552,2022-03-23 -439,Indonesia,70,false,418,2022-01-06 -440,Sweden,92,true,542,2022-04-08 -441,United States,25,true,411,2022-02-02 -442,Greece,52,false,850,2022-03-26 -443,China,35,false,436,2022-04-20 -444,Norway,53,false,538,2022-04-09 -445,Russia,6,true,72,2022-02-14 -446,Peru,5,true,230,2022-01-20 -447,Pakistan,91,true,614,2022-04-02 -448,Indonesia,2,false,469,2022-03-17 -449,Somalia,54,true,1,2022-03-04 -450,Canada,71,true,587,2022-04-17 -451,Indonesia,26,true,512,2022-01-06 -452,Sweden,32,true,986,2022-01-20 -453,China,72,false,386,2022-02-01 -454,Vietnam,52,false,171,2022-02-22 -455,Bhutan,73,true,969,2022-01-22 -456,Peru,23,true,156,2022-02-07 -457,Eritrea,70,false,243,2022-05-04 -458,Indonesia,76,true,412,2022-05-12 -459,Dominican Republic,77,false,362,2022-05-30 -460,Russia,12,false,341,2022-05-18 -461,Zambia,1,true,480,2022-01-25 -462,Indonesia,74,false,144,2022-05-19 -463,Peru,7,false,450,2022-05-17 -464,Moldova,37,false,733,2022-02-04 -465,Yemen,51,true,470,2022-05-18 -466,Philippines,52,false,269,2022-02-12 -467,Brazil,72,false,872,2022-05-02 -468,Japan,87,true,273,2022-02-17 -469,Bhutan,88,true,95,2022-05-20 -470,Portugal,28,false,783,2022-01-01 -471,Chile,68,false,144,2022-02-13 -472,Kuwait,85,true,399,2022-04-08 -473,Sweden,81,true,490,2022-01-07 -474,Indonesia,95,false,6,2022-01-05 -475,China,63,false,501,2022-01-22 -476,Uzbekistan,60,true,76,2022-04-20 -477,China,98,true,337,2022-02-11 -478,Indonesia,90,true,443,2022-05-07 -479,China,29,true,488,2022-03-29 -480,China,98,true,565,2022-05-13 -481,United States,36,false,349,2022-02-20 -482,Nigeria,50,false,641,2022-02-28 -483,Moldova,44,false,331,2022-05-07 -484,Sweden,2,true,551,2022-01-01 -485,China,33,true,822,2022-03-29 -486,Russia,50,false,373,2022-02-15 -487,Peru,97,true,674,2022-01-20 -488,Indonesia,76,false,53,2022-04-25 -489,Canada,44,false,833,2022-02-15 -490,Portugal,35,true,105,2022-03-29 -491,Croatia,71,true,899,2022-03-15 -492,Panama,12,true,589,2022-01-14 -493,Philippines,14,true,885,2022-02-19 -494,Philippines,52,false,694,2022-01-11 -495,Brazil,4,true,440,2022-03-10 -496,Philippines,14,true,600,2022-05-01 -497,Ukraine,28,false,746,2022-05-13 -498,China,9,false,43,2022-02-08 -499,Sweden,95,true,447,2022-01-13 -500,Philippines,45,true,623,2022-05-24 -501,China,60,false,941,2022-05-27 -502,Indonesia,63,false,321,2022-03-23 -503,Comoros,5,true,771,2022-05-17 -504,China,59,true,272,2022-03-16 -505,China,82,true,167,2022-05-10 -506,Iceland,4,false,311,2022-01-25 -507,Portugal,49,true,300,2022-02-03 -508,Portugal,78,false,373,2022-02-02 -509,France,54,false,168,2022-02-06 -510,China,36,false,13,2022-05-13 -511,Indonesia,83,true,997,2022-04-26 -512,China,80,true,412,2022-03-03 -513,Indonesia,71,false,716,2022-05-21 -514,Pakistan,14,true,16,2022-03-05 -515,Philippines,43,false,554,2022-01-18 -516,Sweden,56,true,257,2022-02-03 -517,Russia,31,false,854,2022-03-01 -518,Indonesia,68,true,266,2022-04-30 -519,Vietnam,53,false,586,2022-03-25 -520,Brazil,4,true,750,2022-04-07 -521,China,92,true,387,2022-02-09 -522,Russia,8,false,437,2022-01-31 -523,Portugal,22,false,381,2022-01-14 -524,South Korea,64,false,265,2022-03-16 -525,China,37,true,574,2022-05-11 -526,Colombia,67,true,853,2022-05-04 -527,Cape Verde,12,false,74,2022-04-24 -528,China,68,true,913,2022-05-04 -529,Philippines,72,false,684,2022-05-14 -530,Serbia,59,false,307,2022-05-25 -531,South Korea,98,true,75,2022-01-02 -532,Poland,73,false,103,2022-01-08 -533,France,72,true,38,2022-01-02 -534,China,26,false,131,2022-03-08 -535,United States,73,false,127,2022-02-04 -536,Russia,4,false,610,2022-04-10 -537,Brazil,17,true,528,2022-04-06 -538,Uganda,82,false,297,2022-03-14 -539,Macedonia,11,false,28,2022-04-30 -540,Indonesia,10,false,211,2022-02-05 -541,Greece,29,true,59,2022-03-08 -542,Japan,87,false,492,2022-05-26 -543,Indonesia,48,true,114,2022-02-18 -544,China,24,false,788,2022-04-27 -545,United States,8,false,871,2022-01-05 -546,Brazil,61,false,814,2022-05-11 -547,Finland,55,true,624,2022-01-19 -548,Burkina Faso,49,false,891,2022-04-23 -549,France,71,true,9,2022-04-25 -550,China,20,true,41,2022-02-07 -551,Indonesia,91,true,732,2022-04-08 -552,Colombia,89,false,600,2022-03-16 -553,China,29,false,524,2022-02-19 -554,Uganda,83,true,172,2022-05-10 -555,Indonesia,76,false,417,2022-01-16 -556,China,8,true,221,2022-04-12 -557,United States,81,true,72,2022-02-06 -558,Russia,10,true,607,2022-04-29 -559,China,23,true,959,2022-02-15 -560,Germany,94,false,413,2022-01-19 -561,Madagascar,39,true,394,2022-03-01 -562,Kazakhstan,42,true,478,2022-01-27 -563,Poland,37,true,556,2022-03-04 -564,China,33,true,492,2022-01-12 -565,Philippines,60,false,461,2022-05-17 -566,China,59,false,360,2022-04-01 -567,China,86,false,49,2022-04-14 -568,Philippines,23,false,440,2022-02-11 -569,Portugal,97,true,876,2022-04-27 -570,Venezuela,50,false,798,2022-04-23 -571,France,24,true,27,2022-04-16 -572,Sweden,60,true,801,2022-02-13 -573,Czech Republic,15,false,85,2022-02-11 -574,Russia,28,false,680,2022-03-29 -575,Ivory Coast,47,true,315,2022-02-05 -576,Brazil,4,true,921,2022-01-23 -577,Indonesia,53,true,520,2022-05-12 -578,Ethiopia,67,true,449,2022-01-23 -579,Philippines,37,true,429,2022-03-08 -580,Portugal,99,true,496,2022-01-17 -581,Poland,59,true,223,2022-05-02 -582,Malta,100,false,255,2022-03-18 -583,Indonesia,26,true,824,2022-05-30 -584,China,57,false,987,2022-01-08 -585,Philippines,1,true,349,2022-02-02 -586,China,74,false,9,2022-04-29 -587,Japan,59,true,866,2022-02-08 -588,Russia,15,true,753,2022-03-24 -589,Mayotte,89,true,114,2022-01-25 -590,Ecuador,21,false,163,2022-04-08 -591,China,68,false,12,2022-01-09 -592,Indonesia,2,true,579,2022-01-08 -593,United States,78,false,993,2022-05-26 -594,Russia,58,false,759,2022-02-24 -595,Pakistan,63,true,327,2022-02-16 -596,China,47,false,275,2022-04-01 -597,South Korea,88,false,999,2022-04-03 -598,Portugal,44,true,315,2022-04-19 -599,Sudan,39,false,188,2022-04-06 -600,Finland,89,false,176,2022-03-08 -601,Canada,95,true,168,2022-03-15 -602,Niger,54,true,479,2022-05-07 -603,Portugal,79,true,218,2022-03-07 -604,China,45,false,501,2022-04-02 -605,China,14,false,348,2022-01-04 -606,Poland,28,true,863,2022-05-15 -607,Poland,9,true,717,2022-01-26 -608,Uruguay,62,false,604,2022-01-02 -609,China,19,false,190,2022-01-16 -610,Kazakhstan,76,true,633,2022-04-25 -611,France,58,true,666,2022-05-04 -612,Indonesia,53,true,795,2022-02-21 -613,Bangladesh,42,false,662,2022-03-04 -614,Peru,4,true,473,2022-01-27 -615,China,56,true,858,2022-05-27 -616,China,44,false,862,2022-04-04 -617,Luxembourg,48,false,607,2022-02-08 -618,Indonesia,16,false,915,2022-05-07 -619,Gabon,40,true,992,2022-01-14 -620,China,53,false,215,2022-01-29 -621,Ukraine,29,false,314,2022-04-01 -622,China,27,false,487,2022-05-28 -623,Portugal,62,true,138,2022-03-05 -624,China,60,false,523,2022-03-05 -625,Portugal,76,true,198,2022-04-09 -626,China,20,true,579,2022-05-15 -627,Malaysia,76,false,432,2022-05-21 -628,Sweden,46,false,967,2022-01-15 -629,China,4,false,139,2022-04-04 -630,Russia,13,true,417,2022-03-12 -631,Indonesia,58,false,331,2022-05-23 -632,China,59,false,457,2022-01-27 -633,China,87,true,174,2022-02-19 -634,Kyrgyzstan,91,false,96,2022-05-06 -635,South Sudan,21,false,855,2022-03-23 -636,Thailand,87,false,10,2022-03-17 -637,China,15,true,922,2022-02-25 -638,Argentina,51,true,161,2022-05-21 -639,Chile,42,false,880,2022-03-13 -640,Indonesia,64,true,479,2022-04-03 -641,Russia,87,false,648,2022-01-13 -642,Portugal,72,false,388,2022-03-14 -643,Portugal,84,false,11,2022-04-29 -644,Portugal,41,false,17,2022-02-22 -645,Vietnam,99,true,491,2022-05-07 -646,Nigeria,42,false,717,2022-01-02 -647,Vietnam,66,true,844,2022-04-02 -648,China,53,false,148,2022-05-28 -649,China,65,false,137,2022-03-19 -650,Japan,67,true,772,2022-03-23 -651,Serbia,32,false,288,2022-04-11 -652,China,1,false,508,2022-05-09 -653,Yemen,68,false,241,2022-05-16 -654,Poland,45,true,291,2022-05-18 -655,China,19,false,651,2022-05-14 -656,Japan,63,false,436,2022-04-10 -657,Kazakhstan,72,false,807,2022-02-13 -658,China,90,false,368,2022-02-08 -659,Sweden,5,false,773,2022-04-13 -660,Sweden,67,true,79,2022-01-27 -661,Russia,70,true,506,2022-01-06 -662,China,5,true,919,2022-03-14 -663,Portugal,11,false,823,2022-04-10 -664,China,27,true,389,2022-02-07 -665,Indonesia,80,false,813,2022-01-10 -666,Malaysia,55,false,583,2022-05-22 -667,Indonesia,72,false,31,2022-01-06 -668,Finland,68,false,541,2022-02-06 -669,Philippines,42,true,149,2022-04-11 -670,China,69,false,622,2022-02-15 -671,Portugal,21,false,305,2022-02-13 -672,China,60,false,56,2022-04-21 -673,Indonesia,72,true,676,2022-02-01 -674,Albania,36,false,953,2022-01-16 -675,China,80,true,70,2022-05-25 -676,Indonesia,83,false,571,2022-04-26 -677,Brazil,98,false,639,2022-05-27 -678,Poland,68,false,976,2022-04-18 -679,Argentina,23,false,364,2022-01-06 -680,Indonesia,64,true,992,2022-03-27 -681,Philippines,9,false,550,2022-01-31 -682,Indonesia,41,true,582,2022-01-04 -683,Greece,21,true,107,2022-04-02 -684,Mexico,58,true,861,2022-04-05 -685,Haiti,56,true,830,2022-03-14 -686,China,18,true,148,2022-01-06 -687,Indonesia,16,false,558,2022-05-01 -688,Czech Republic,38,true,843,2022-02-15 -689,China,68,true,409,2022-05-31 -690,China,38,false,961,2022-05-28 -691,Sweden,52,false,304,2022-01-31 -692,China,55,true,754,2022-03-16 -693,China,29,true,639,2022-02-07 -694,Liberia,52,true,894,2022-03-10 -695,China,35,true,873,2022-04-22 -696,China,60,false,885,2022-04-01 -697,Indonesia,39,true,339,2022-05-03 -698,China,34,false,81,2022-05-15 -699,Greece,33,true,556,2022-03-08 -700,Afghanistan,52,false,280,2022-02-24 -701,China,43,true,211,2022-03-30 -702,Indonesia,23,true,812,2022-02-01 -703,Serbia,64,false,343,2022-01-27 -704,Indonesia,56,true,735,2022-05-21 -705,China,74,false,55,2022-05-16 -706,Philippines,17,false,280,2022-04-08 -707,China,85,false,98,2022-01-07 -708,Venezuela,87,true,517,2022-04-08 -709,Mexico,9,false,621,2022-01-15 -710,France,67,false,812,2022-03-31 -711,Philippines,85,false,853,2022-04-12 -712,China,46,true,351,2022-01-25 -713,Mongolia,4,false,356,2022-04-17 -714,Palestinian Territory,96,false,619,2022-03-29 -715,Poland,13,false,595,2022-04-10 -716,Philippines,8,true,973,2022-02-10 -717,Panama,14,true,719,2022-03-05 -718,Sweden,2,false,734,2022-01-23 -719,Faroe Islands,9,true,1000,2022-05-12 -720,Maldives,18,true,106,2022-04-07 -721,Brazil,82,false,7,2022-03-21 -722,Sweden,84,true,872,2022-02-22 -723,China,94,false,984,2022-02-25 -724,Russia,11,false,833,2022-05-30 -725,Portugal,73,false,237,2022-04-20 -726,Indonesia,26,false,112,2022-03-30 -727,Sweden,53,false,202,2022-01-10 -728,Bangladesh,61,true,463,2022-02-13 -729,Indonesia,22,false,242,2022-04-03 -730,Philippines,77,true,741,2022-03-28 -731,Belarus,63,false,977,2022-05-04 -732,Indonesia,2,false,635,2022-05-24 -733,Armenia,36,true,820,2022-01-29 -734,China,58,true,750,2022-03-20 -735,Egypt,35,true,794,2022-02-18 -736,South Africa,67,true,700,2022-04-06 -737,Albania,18,true,191,2022-04-24 -738,Indonesia,84,true,551,2022-03-22 -739,Russia,8,true,835,2022-04-17 -740,Russia,87,false,613,2022-04-10 -741,Colombia,55,false,731,2022-05-09 -742,Sweden,83,false,374,2022-01-02 -743,Poland,36,true,544,2022-03-23 -744,Argentina,52,false,639,2022-01-29 -745,South Korea,38,true,122,2022-02-25 -746,Czech Republic,21,false,964,2022-02-04 -747,France,80,true,878,2022-03-15 -748,Iran,33,true,352,2022-04-03 -749,Ireland,67,true,62,2022-04-16 -750,Philippines,62,true,226,2022-05-02 -751,France,9,true,546,2022-01-10 -752,Poland,87,false,17,2022-02-09 -753,Austria,4,false,905,2022-05-31 -754,Indonesia,17,true,233,2022-04-06 -755,Indonesia,51,false,618,2022-04-01 -756,Sweden,1,true,313,2022-04-03 -757,France,65,true,855,2022-02-05 -758,Portugal,60,false,236,2022-01-23 -759,Indonesia,47,true,464,2022-04-28 -760,Slovenia,97,false,23,2022-05-07 -761,Indonesia,96,false,297,2022-04-27 -762,Benin,36,true,188,2022-03-02 -763,South Sudan,76,false,420,2022-05-22 -764,Netherlands,14,true,719,2022-01-09 -765,China,85,false,318,2022-02-08 -766,Libya,24,false,797,2022-05-16 -767,Brazil,11,false,809,2022-04-10 -768,China,44,false,467,2022-02-22 -769,Bulgaria,5,false,586,2022-05-29 -770,Croatia,73,true,865,2022-05-09 -771,China,71,false,622,2022-03-22 -772,Portugal,56,false,693,2022-02-15 -773,China,27,false,527,2022-03-28 -774,Indonesia,22,true,114,2022-05-19 -775,China,6,true,54,2022-01-20 -776,Japan,1,false,642,2022-01-11 -777,France,56,true,902,2022-01-07 -778,Japan,71,false,238,2022-05-16 -779,Vietnam,16,false,959,2022-03-19 -780,United States,32,false,289,2022-04-26 -781,Indonesia,4,false,659,2022-05-20 -782,Indonesia,51,true,702,2022-03-08 -783,Indonesia,5,false,1000,2022-01-05 -784,Kazakhstan,45,true,341,2022-03-13 -785,Cameroon,72,false,417,2022-04-17 -786,New Caledonia,71,true,644,2022-05-19 -787,Cyprus,92,true,869,2022-05-06 -788,United States,63,true,166,2022-01-22 -789,Uruguay,24,false,10,2022-05-01 -790,Czech Republic,97,false,254,2022-05-26 -791,Ukraine,60,false,651,2022-01-04 -792,United States,63,false,16,2022-04-02 -793,Sweden,43,false,641,2022-01-30 -794,Afghanistan,85,false,91,2022-05-18 -795,China,29,true,150,2022-05-10 -796,Nicaragua,73,true,238,2022-04-11 -797,Peru,85,true,475,2022-05-02 -798,Thailand,10,true,752,2022-04-24 -799,Sweden,18,true,745,2022-01-17 -800,United States,14,false,767,2022-03-12 -801,China,98,true,171,2022-02-28 -802,Indonesia,16,false,570,2022-03-28 -803,Iran,85,true,386,2022-04-16 -804,Thailand,35,true,707,2022-03-10 -805,Japan,68,false,484,2022-02-12 -806,Mexico,30,true,743,2022-03-22 -807,Brazil,78,false,173,2022-02-25 -808,Ukraine,17,true,819,2022-05-28 -809,Ethiopia,16,true,150,2022-01-24 -810,Thailand,71,true,875,2022-02-22 -811,China,11,true,215,2022-04-09 -812,Canada,34,false,719,2022-02-22 -813,Armenia,15,false,901,2022-03-05 -814,Philippines,24,false,346,2022-01-08 -815,China,55,true,404,2022-05-24 -816,Philippines,1,true,571,2022-04-01 -817,France,39,false,562,2022-03-04 -818,France,60,true,758,2022-05-03 -819,Mexico,23,false,974,2022-04-25 -820,Australia,20,false,777,2022-05-15 -821,Peru,18,false,888,2022-02-15 -822,China,57,false,999,2022-01-15 -823,China,10,true,807,2022-05-28 -824,Portugal,25,true,661,2022-04-23 -825,Ukraine,31,true,668,2022-03-01 -826,Dominican Republic,48,true,648,2022-03-18 -827,Nigeria,17,false,980,2022-05-31 -828,Venezuela,76,false,203,2022-01-29 -829,China,31,true,955,2022-03-13 -830,Spain,51,true,329,2022-02-12 -831,China,41,true,481,2022-04-03 -832,Uzbekistan,68,false,934,2022-04-29 -833,United States,72,false,681,2022-03-04 -834,China,84,false,945,2022-01-20 -835,Suriname,21,false,217,2022-04-21 -836,Russia,45,true,724,2022-04-04 -837,Indonesia,44,false,76,2022-05-03 -838,Sweden,52,true,438,2022-02-18 -839,Syria,28,true,970,2022-01-02 -840,Russia,54,false,903,2022-01-10 -841,Brazil,13,false,726,2022-05-04 -842,China,51,true,539,2022-01-31 -843,Greece,58,true,203,2022-04-20 -844,Indonesia,30,true,686,2022-01-26 -845,Indonesia,66,true,797,2022-01-11 -846,Colombia,89,false,498,2022-01-05 -847,China,7,false,223,2022-01-02 -848,Iran,34,false,614,2022-03-22 -849,Russia,89,false,727,2022-01-15 -850,Portugal,27,true,427,2022-02-25 -851,Spain,91,false,190,2022-01-04 -852,Canada,43,true,613,2022-01-02 -853,China,34,false,669,2022-05-10 -854,China,83,false,71,2022-01-18 -855,Comoros,81,false,71,2022-05-13 -856,Indonesia,16,false,576,2022-03-29 -857,Russia,76,true,749,2022-02-24 -858,Portugal,86,true,935,2022-03-16 -859,Philippines,52,true,337,2022-03-23 -860,Dominican Republic,74,true,806,2022-04-28 -861,Thailand,85,true,53,2022-02-26 -862,Bosnia and Herzegovina,85,true,313,2022-01-11 -863,Kazakhstan,61,true,534,2022-04-13 -864,Serbia,74,true,508,2022-03-22 -865,China,59,false,599,2022-05-23 -866,Palestinian Territory,69,true,185,2022-01-20 -867,Mauritius,42,true,142,2022-03-13 -868,Russia,71,true,956,2022-01-09 -869,Russia,82,true,846,2022-02-20 -870,China,50,true,134,2022-04-15 -871,Russia,27,false,552,2022-05-19 -872,Indonesia,78,false,542,2022-02-28 -873,Portugal,74,true,392,2022-02-14 -874,Russia,77,false,132,2022-05-16 -875,China,28,true,315,2022-04-03 -876,Indonesia,47,true,202,2022-01-30 -877,Guatemala,27,true,409,2022-01-02 -878,China,71,false,932,2022-01-07 -879,Ukraine,76,false,476,2022-01-05 -880,Russia,8,false,485,2022-05-13 -881,Japan,59,false,98,2022-03-09 -882,Slovenia,55,false,536,2022-03-29 -883,Japan,8,false,280,2022-01-01 -884,Ivory Coast,32,false,97,2022-03-13 -885,Belarus,1,false,779,2022-03-25 -886,Brazil,33,false,627,2022-01-29 -887,Philippines,31,false,697,2022-05-12 -888,Chile,9,false,508,2022-03-20 -889,China,94,true,834,2022-05-08 -890,Finland,68,true,695,2022-02-09 -891,China,14,true,129,2022-01-14 -892,Peru,61,false,117,2022-01-23 -893,China,47,false,721,2022-04-23 -894,China,84,true,730,2022-02-10 -895,Brazil,56,false,766,2022-02-09 -896,Cuba,100,false,879,2022-03-25 -897,Indonesia,31,false,111,2022-01-16 -898,Indonesia,75,false,198,2022-02-18 -899,Bolivia,40,false,898,2022-03-12 -900,Ukraine,52,false,951,2022-01-30 -901,Indonesia,88,false,225,2022-04-04 -902,Colombia,58,true,861,2022-05-20 -903,Republic of the Congo,80,true,891,2022-01-19 -904,Sri Lanka,24,true,532,2022-04-16 -905,Sweden,41,false,340,2022-05-06 -906,Malaysia,35,false,372,2022-01-12 -907,Philippines,77,false,856,2022-02-17 -908,Norway,21,true,268,2022-02-14 -909,China,18,false,237,2022-03-07 -910,Philippines,68,true,616,2022-03-21 -911,North Korea,75,false,59,2022-04-02 -912,Armenia,77,true,429,2022-01-27 -913,China,69,false,611,2022-01-12 -914,China,50,true,795,2022-04-15 -915,China,98,true,572,2022-03-13 -916,Russia,28,false,287,2022-03-28 -917,Japan,38,false,240,2022-05-04 -918,Japan,6,false,994,2022-05-18 -919,Poland,9,true,116,2022-01-08 -920,Greece,3,true,43,2022-05-24 -921,United Arab Emirates,56,false,35,2022-03-16 -922,China,21,false,151,2022-02-23 -923,Bulgaria,60,true,452,2022-02-19 -924,China,76,false,567,2022-03-10 -925,China,20,true,196,2022-02-11 -926,Philippines,53,false,738,2022-02-22 -927,Indonesia,41,true,223,2022-01-01 -928,Portugal,84,false,857,2022-04-25 -929,Czech Republic,23,true,55,2022-05-17 -930,South Korea,81,false,485,2022-01-05 -931,Norway,43,true,489,2022-05-17 -932,Portugal,50,false,561,2022-04-05 -933,Sweden,83,true,267,2022-01-13 -934,Ukraine,78,false,24,2022-01-17 -935,Russia,3,true,965,2022-03-07 -936,China,33,false,651,2022-02-19 -937,China,98,true,476,2022-02-17 -938,Nepal,82,true,52,2022-05-17 -939,Colombia,6,false,822,2022-05-09 -940,Micronesia,96,false,993,2022-05-15 -941,China,63,false,152,2022-03-12 -942,Philippines,42,false,509,2022-01-28 -943,China,83,true,641,2022-03-20 -944,Portugal,44,true,237,2022-05-21 -945,Czech Republic,37,true,695,2022-03-26 -946,Indonesia,65,false,82,2022-04-12 -947,Russia,47,false,519,2022-03-26 -948,Slovenia,30,false,775,2022-01-05 -949,Philippines,4,true,481,2022-01-01 -950,Russia,39,true,558,2022-05-28 -951,Botswana,17,false,608,2022-04-21 -952,Philippines,53,true,900,2022-04-13 -953,China,83,false,206,2022-02-27 -954,Brazil,49,true,418,2022-04-30 -955,Ethiopia,89,true,534,2022-02-20 -956,Tunisia,60,true,585,2022-02-20 -957,Portugal,72,true,346,2022-02-28 -958,United States,45,false,757,2022-05-04 -959,Albania,51,true,607,2022-03-31 -960,Brazil,61,false,151,2022-05-12 -961,China,34,true,419,2022-01-10 -962,United States,100,false,642,2022-02-25 -963,China,47,false,869,2022-01-26 -964,China,18,false,390,2022-01-08 -965,Saudi Arabia,92,false,232,2022-02-17 -966,Indonesia,16,true,502,2022-04-02 -967,Brazil,97,true,593,2022-04-17 -968,Pakistan,4,true,132,2022-05-20 -969,United States,2,true,408,2022-03-07 -970,Sweden,31,true,963,2022-04-20 -971,Brazil,17,false,681,2022-05-10 -972,Afghanistan,66,false,254,2022-05-12 -973,Peru,20,true,171,2022-04-29 -974,Poland,69,true,317,2022-01-30 -975,Honduras,77,true,99,2022-05-07 -976,Brazil,14,true,773,2022-04-07 -977,Argentina,81,false,825,2022-03-30 -978,China,47,false,771,2022-05-26 -979,Russia,51,true,364,2022-01-14 -980,Iran,12,true,622,2022-05-27 -981,Philippines,21,true,579,2022-03-20 -982,Guyana,28,false,67,2022-04-30 -983,Denmark,50,false,138,2022-02-22 -984,China,5,false,287,2022-02-23 -985,Poland,91,true,876,2022-04-27 -986,Ukraine,10,true,969,2022-01-11 -987,United States,81,false,854,2022-05-08 -988,Indonesia,86,false,942,2022-04-02 -989,Slovenia,28,true,197,2022-03-21 -990,Nigeria,42,false,158,2022-05-28 -991,Peru,86,true,527,2022-02-24 -992,Sweden,14,true,613,2022-04-19 -993,Egypt,76,true,45,2022-05-18 -994,Pakistan,7,false,567,2022-02-09 -995,Philippines,79,false,761,2022-04-18 -996,Pakistan,40,true,17,2022-04-23 -997,Czech Republic,20,false,519,2022-05-02 -998,Morocco,10,true,919,2022-03-10 -999,Belarus,74,false,409,2022-01-27 -1000,Haiti,89,true,918,2022-03-31 \ No newline at end of file +1,Russia,2,false,1,01/28/2022 +2,Mauritius,1,false,2,01/20/2022 +3,Peru,1,false,1,01/13/2022 +4,Kazakhstan,1,true,3,01/06/2022 +5,Portugal,1,false,4,01/08/2022 +6,China,1,false,5,01/21/2022 +7,Germany,1,true,2,01/22/2022 +8,Greenland,0,true,1,02/15/2022 +9,Bangladesh,1,false,2,02/03/2022 +10,Sweden,1,false,3,02/13/2022 \ No newline at end of file diff --git a/integration_tests/seeds/source/mock_purchase_data.csv b/integration_tests/seeds/source/mock_purchase_data.csv index d59a808a..3dc68834 100644 --- a/integration_tests/seeds/source/mock_purchase_data.csv +++ b/integration_tests/seeds/source/mock_purchase_data.csv @@ -1,1001 +1,6 @@ purchased_at,payment_type,payment_total -2021-02-14 17:52:36,maestro,2418.94 -2021-02-15 04:16:50,jcb,3043.28 -2021-02-15 11:30:45,solo,1505.81 -2021-02-16 13:08:18,,1532.85 -2021-02-17 05:41:34,americanexpress,319.91 -2021-02-18 06:47:32,jcb,2143.44 -2021-02-19 01:37:09,jcb,840.1 -2021-02-19 03:38:49,jcb,1388.18 -2021-02-19 04:22:41,jcb,2834.96 -2021-02-19 13:28:50,china-unionpay,2440.98 -2021-02-19 19:02:40,diners-club-enroute,207.61 -2021-02-19 22:19:20,,3672.17 -2021-02-20 00:04:57,china-unionpay,2153.44 -2021-02-20 09:56:10,jcb,3999.56 -2021-02-20 12:43:47,diners-club-enroute,2765.95 -2021-02-21 02:58:39,americanexpress,1255.11 -2021-02-21 07:17:14,jcb,2169.95 -2021-02-21 12:47:51,maestro,2479.32 -2021-02-21 18:46:43,switch,2342.95 -2021-02-21 21:09:56,visa-electron,1393.75 -2021-02-23 07:26:46,jcb,3513.61 -2021-02-23 16:46:38,solo,1996.15 -2021-02-24 08:05:10,jcb,1559.0 -2021-02-24 12:11:11,maestro,269.15 -2021-02-24 19:35:56,,1209.48 -2021-02-24 20:10:19,switch,714.2 -2021-02-24 20:13:21,jcb,1179.38 -2021-02-24 20:14:30,maestro,3072.77 -2021-02-24 23:20:46,bankcard,3062.83 -2021-02-25 02:00:00,maestro,424.81 -2021-02-25 05:43:49,visa-electron,828.11 -2021-02-26 07:31:17,diners-club-carte-blanche,362.78 -2021-02-26 23:12:07,visa-electron,824.22 -2021-02-26 23:59:11,diners-club-enroute,312.0 -2021-02-27 02:00:25,americanexpress,2112.51 -2021-02-27 03:34:30,jcb,371.99 -2021-02-28 04:52:27,jcb,848.47 -2021-02-28 13:54:50,jcb,1433.68 -2021-03-01 00:14:02,jcb,3076.02 -2021-03-02 14:27:37,jcb,283.71 -2021-03-02 14:49:02,maestro,1235.64 -2021-03-02 16:20:33,jcb,259.72 -2021-03-02 18:55:53,laser,1673.39 -2021-03-02 23:49:50,,1268.5 -2021-03-02 23:52:14,,552.43 -2021-03-03 00:11:35,jcb,437.0 -2021-03-03 04:09:00,visa-electron,352.32 -2021-03-03 13:12:13,jcb,1713.71 -2021-03-03 18:34:12,maestro,3561.11 -2021-03-03 23:18:10,jcb,666.27 -2021-03-04 12:00:26,jcb,2320.25 -2021-03-05 03:17:20,jcb,1622.21 -2021-03-05 07:31:44,china-unionpay,783.5 -2021-03-05 13:10:14,diners-club-carte-blanche,840.56 -2021-03-05 18:45:17,jcb,491.7 -2021-03-06 11:29:16,visa,461.16 -2021-03-06 12:36:58,jcb,3638.35 -2021-03-06 23:33:00,americanexpress,3721.5 -2021-03-07 09:44:59,jcb,3870.41 -2021-03-09 01:54:46,jcb,3871.87 -2021-03-10 12:46:46,jcb,3605.29 -2021-03-10 13:10:47,china-unionpay,3717.78 -2021-03-10 18:52:29,switch,3857.97 -2021-03-10 21:07:05,instapayment,382.84 -2021-03-10 23:01:01,jcb,2086.42 -2021-03-11 02:26:37,china-unionpay,3604.97 -2021-03-11 07:17:42,china-unionpay,2976.94 -2021-03-11 20:04:16,maestro,1923.64 -2021-03-12 21:24:47,americanexpress,424.09 -2021-03-12 23:36:51,maestro,380.85 -2021-03-13 00:12:10,jcb,1125.24 -2021-03-13 08:41:56,laser,1467.4 -2021-03-13 11:45:24,visa,273.36 -2021-03-14 04:13:51,jcb,2248.19 -2021-03-14 04:56:07,mastercard,973.44 -2021-03-14 18:06:18,bankcard,243.49 -2021-03-14 18:14:52,china-unionpay,726.21 -2021-03-15 08:57:52,switch,2292.62 -2021-03-15 10:08:25,jcb,1950.46 -2021-03-15 15:19:41,americanexpress,1607.11 -2021-03-15 21:42:11,,2173.2 -2021-03-16 04:16:01,jcb,350.11 -2021-03-17 13:00:20,jcb,1631.89 -2021-03-17 15:10:47,jcb,1832.19 -2021-03-17 23:02:09,jcb,601.1 -2021-03-18 08:33:28,diners-club-carte-blanche,1130.06 -2021-03-18 10:19:35,visa,2781.34 -2021-03-18 11:09:44,jcb,630.89 -2021-03-18 19:45:40,mastercard,898.64 -2021-03-18 21:49:52,jcb,1725.51 -2021-03-18 21:56:37,china-unionpay,3240.59 -2021-03-19 02:47:58,jcb,2199.09 -2021-03-20 01:53:19,jcb,344.72 -2021-03-20 16:41:32,jcb,3660.44 -2021-03-22 21:14:27,switch,1264.79 -2021-03-23 03:41:58,mastercard,3381.85 -2021-03-23 09:28:56,jcb,982.2 -2021-03-23 20:56:28,visa-electron,3728.43 -2021-03-24 03:58:41,jcb,2089.87 -2021-03-24 07:47:20,solo,3805.18 -2021-03-25 09:57:44,,3080.15 -2021-03-27 00:15:56,jcb,2462.03 -2021-03-27 02:59:39,diners-club-international,238.62 -2021-03-27 15:36:11,china-unionpay,2524.33 -2021-03-28 02:23:07,jcb,2335.67 -2021-03-28 09:03:35,diners-club-enroute,928.24 -2021-03-28 12:22:44,solo,2049.95 -2021-03-28 13:23:48,jcb,369.65 -2021-03-29 12:15:47,jcb,2985.52 -2021-03-29 12:55:19,jcb,3627.29 -2021-03-29 15:24:34,,3232.6 -2021-03-29 20:57:42,maestro,2456.37 -2021-03-30 04:29:54,mastercard,3193.42 -2021-03-30 05:17:03,instapayment,2960.13 -2021-03-31 20:14:38,jcb,1724.65 -2021-03-31 21:19:40,maestro,3320.32 -2021-03-31 23:17:13,china-unionpay,3308.17 -2021-04-01 12:42:48,visa-electron,1495.29 -2021-04-01 17:22:02,jcb,1889.13 -2021-04-01 21:29:07,,3659.73 -2021-04-02 20:28:27,mastercard,3698.58 -2021-04-03 00:13:40,jcb,3128.7 -2021-04-03 05:52:34,jcb,3821.84 -2021-04-03 08:01:02,jcb,3942.05 -2021-04-04 00:11:38,switch,3873.52 -2021-04-04 12:37:59,bankcard,252.91 -2021-04-04 21:38:44,switch,2044.86 -2021-04-05 08:53:52,jcb,631.06 -2021-04-05 16:46:36,switch,357.88 -2021-04-06 01:35:45,jcb,447.53 -2021-04-06 02:18:55,jcb,2050.47 -2021-04-06 02:21:18,visa,3439.73 -2021-04-06 09:12:53,diners-club-carte-blanche,1231.8 -2021-04-06 11:35:03,instapayment,897.16 -2021-04-06 12:15:39,jcb,3243.76 -2021-04-06 22:05:48,,2871.08 -2021-04-07 09:23:10,jcb,800.47 -2021-04-07 11:59:57,laser,1345.42 -2021-04-07 13:24:28,mastercard,3501.27 -2021-04-07 15:10:01,bankcard,1592.46 -2021-04-08 00:28:02,china-unionpay,3404.42 -2021-04-09 05:50:17,visa-electron,1574.41 -2021-04-09 07:18:24,jcb,2317.87 -2021-04-09 08:42:16,jcb,874.84 -2021-04-09 08:49:39,,1996.64 -2021-04-10 18:48:26,jcb,1742.03 -2021-04-11 02:54:16,maestro,636.89 -2021-04-11 07:29:18,jcb,1200.19 -2021-04-11 09:54:09,,3731.82 -2021-04-11 21:19:46,bankcard,2475.93 -2021-04-12 00:10:07,maestro,1125.2 -2021-04-12 06:12:19,china-unionpay,3148.81 -2021-04-13 07:12:52,,3251.1 -2021-04-13 08:27:28,jcb,1692.49 -2021-04-14 02:12:53,diners-club-us-ca,1485.85 -2021-04-14 11:27:40,jcb,1857.71 -2021-04-14 12:15:24,jcb,1186.73 -2021-04-14 15:07:01,jcb,1330.26 -2021-04-14 20:36:06,jcb,3811.33 -2021-04-14 23:40:20,jcb,2134.14 -2021-04-15 12:04:41,maestro,483.81 -2021-04-16 04:01:59,jcb,1484.58 -2021-04-16 08:16:43,jcb,2163.39 -2021-04-16 21:34:20,jcb,1843.9 -2021-04-17 00:21:01,diners-club-us-ca,1596.23 -2021-04-18 03:13:06,switch,1754.12 -2021-04-18 07:21:22,jcb,3822.78 -2021-04-18 12:47:50,visa,1861.27 -2021-04-18 22:42:23,visa-electron,1441.46 -2021-04-18 23:19:52,diners-club-us-ca,796.17 -2021-04-19 20:40:35,jcb,2211.67 -2021-04-20 06:38:52,jcb,723.81 -2021-04-20 19:33:09,mastercard,1096.42 -2021-04-20 20:21:52,switch,3859.03 -2021-04-21 07:24:26,diners-club-enroute,1779.26 -2021-04-21 12:50:42,jcb,2595.98 -2021-04-21 16:31:56,jcb,2516.42 -2021-04-22 19:12:36,laser,2256.38 -2021-04-24 01:29:46,laser,1094.67 -2021-04-25 10:52:04,jcb,1083.73 -2021-04-25 17:29:19,mastercard,2150.6 -2021-04-26 06:01:34,,3161.54 -2021-04-26 14:06:36,jcb,2946.8 -2021-04-27 02:21:29,jcb,2640.48 -2021-04-27 13:25:56,mastercard,3405.84 -2021-04-27 19:25:06,china-unionpay,539.68 -2021-04-28 02:18:00,jcb,1680.13 -2021-04-28 04:39:26,mastercard,567.21 -2021-04-28 20:25:56,jcb,3113.52 -2021-04-29 07:10:29,jcb,3448.09 -2021-04-29 10:05:01,,3789.79 -2021-04-29 23:40:51,laser,3671.09 -2021-04-30 03:18:23,jcb,2326.71 -2021-04-30 09:58:35,jcb,2800.26 -2021-04-30 14:30:05,laser,3820.56 -2021-04-30 16:07:50,jcb,304.18 -2021-05-01 02:35:07,jcb,3618.75 -2021-05-01 02:45:43,jcb,876.05 -2021-05-01 03:24:33,jcb,1585.61 -2021-05-01 04:21:52,jcb,3317.9 -2021-05-01 07:29:18,mastercard,2611.79 -2021-05-01 19:31:30,jcb,3992.47 -2021-05-02 05:47:17,jcb,395.11 -2021-05-02 06:38:27,,1932.12 -2021-05-03 22:06:56,visa,3321.28 -2021-05-03 23:04:40,switch,1305.99 -2021-05-04 03:06:15,jcb,3720.64 -2021-05-04 19:00:08,jcb,3502.58 -2021-05-04 19:15:25,bankcard,2162.36 -2021-05-04 19:37:33,visa,2945.01 -2021-05-04 22:39:56,jcb,1304.28 -2021-05-05 20:30:28,jcb,1994.78 -2021-05-06 04:24:12,jcb,916.37 -2021-05-06 10:58:48,mastercard,2081.24 -2021-05-06 20:12:06,diners-club-carte-blanche,3257.56 -2021-05-06 22:27:21,visa-electron,326.89 -2021-05-07 04:04:27,switch,3877.33 -2021-05-07 06:49:45,jcb,1797.84 -2021-05-07 19:32:36,jcb,2537.5 -2021-05-07 22:10:11,jcb,3648.43 -2021-05-09 06:22:46,jcb,1665.27 -2021-05-09 15:23:24,jcb,787.08 -2021-05-10 11:10:41,diners-club-enroute,2053.71 -2021-05-10 22:58:56,maestro,3258.71 -2021-05-11 03:40:40,jcb,454.0 -2021-05-11 13:42:38,maestro,1437.79 -2021-05-11 19:32:12,maestro,748.91 -2021-05-12 11:28:21,china-unionpay,2249.07 -2021-05-12 22:07:13,jcb,3133.2 -2021-05-12 23:01:58,china-unionpay,2733.24 -2021-05-13 00:17:36,jcb,2703.58 -2021-05-13 03:47:22,switch,1864.91 -2021-05-13 06:39:19,maestro,1825.31 -2021-05-13 08:36:44,jcb,534.35 -2021-05-13 12:11:24,maestro,3194.79 -2021-05-13 13:09:47,maestro,3429.67 -2021-05-13 17:29:06,,1199.8 -2021-05-15 00:58:45,china-unionpay,3826.6 -2021-05-15 05:46:47,maestro,3110.62 -2021-05-15 10:31:48,visa-electron,229.54 -2021-05-15 13:01:30,jcb,567.6 -2021-05-15 19:46:45,americanexpress,3062.99 -2021-05-16 03:47:02,jcb,2602.48 -2021-05-16 07:15:43,diners-club-carte-blanche,2783.44 -2021-05-16 18:25:59,jcb,2580.61 -2021-05-17 01:15:27,jcb,1371.73 -2021-05-17 02:23:55,jcb,2294.88 -2021-05-17 06:03:37,americanexpress,3221.07 -2021-05-17 17:45:12,,1396.33 -2021-05-17 17:48:51,diners-club-carte-blanche,3998.25 -2021-05-17 23:31:28,jcb,715.42 -2021-05-18 08:09:58,jcb,1358.62 -2021-05-18 09:48:00,,1778.05 -2021-05-18 21:53:41,diners-club-enroute,2358.68 -2021-05-18 22:28:20,,2986.01 -2021-05-19 17:13:20,jcb,2655.57 -2021-05-22 08:41:50,maestro,2008.41 -2021-05-22 23:24:08,instapayment,1701.26 -2021-05-23 06:00:10,diners-club-carte-blanche,3422.89 -2021-05-23 18:02:02,mastercard,1955.63 -2021-05-24 04:59:55,,917.17 -2021-05-24 06:18:58,jcb,3114.27 -2021-05-24 13:58:29,bankcard,669.85 -2021-05-24 14:21:27,jcb,3241.18 -2021-05-25 13:52:16,visa-electron,582.37 -2021-05-25 20:42:54,diners-club-enroute,1276.37 -2021-05-25 23:16:31,mastercard,2252.59 -2021-05-25 23:40:40,jcb,2483.3 -2021-05-26 14:17:17,jcb,1672.31 -2021-05-27 16:38:13,jcb,3648.71 -2021-05-27 22:46:32,jcb,3711.8 -2021-05-28 13:15:58,jcb,210.47 -2021-05-28 13:28:52,china-unionpay,3683.46 -2021-05-28 14:28:32,jcb,1830.68 -2021-05-29 07:27:01,jcb,2205.58 -2021-05-29 08:10:57,,2574.02 -2021-05-29 16:20:54,jcb,1458.67 -2021-05-29 18:36:52,switch,1522.64 -2021-05-29 21:23:22,maestro,229.28 -2021-05-30 03:23:07,,752.37 -2021-05-31 07:53:00,jcb,2878.48 -2021-05-31 19:03:28,jcb,3781.51 -2021-05-31 19:48:19,maestro,510.54 -2021-06-01 04:38:55,china-unionpay,2698.74 -2021-06-01 15:06:02,china-unionpay,1290.66 -2021-06-01 20:00:10,diners-club-international,283.07 -2021-06-01 23:16:57,jcb,3610.5 -2021-06-02 03:32:36,jcb,3721.09 -2021-06-02 18:05:47,americanexpress,2787.93 -2021-06-03 11:44:30,switch,3459.37 -2021-06-03 20:57:21,americanexpress,3690.21 -2021-06-04 05:08:16,maestro,665.94 -2021-06-04 07:45:18,jcb,3029.4 -2021-06-04 12:04:35,switch,3196.82 -2021-06-05 07:59:24,,490.24 -2021-06-05 11:03:11,china-unionpay,2697.2 -2021-06-05 11:49:46,mastercard,1643.29 -2021-06-05 16:00:50,diners-club-carte-blanche,1646.28 -2021-06-05 18:16:29,laser,1342.22 -2021-06-06 20:43:01,mastercard,3279.49 -2021-06-07 00:22:22,jcb,3637.36 -2021-06-07 14:12:04,mastercard,2927.73 -2021-06-07 18:49:41,jcb,1575.17 -2021-06-07 19:20:03,jcb,1551.45 -2021-06-08 12:11:39,jcb,1094.77 -2021-06-09 05:58:57,jcb,644.67 -2021-06-09 14:19:20,,2232.0 -2021-06-09 19:13:04,visa,3478.12 -2021-06-09 21:46:00,maestro,580.51 -2021-06-10 03:38:29,jcb,2203.81 -2021-06-10 04:20:34,jcb,1695.39 -2021-06-10 04:38:20,jcb,2427.41 -2021-06-10 08:25:11,jcb,1571.72 -2021-06-10 12:59:03,jcb,3831.83 -2021-06-10 18:52:35,jcb,3766.04 -2021-06-10 23:32:30,mastercard,2072.64 -2021-06-11 03:54:55,maestro,551.22 -2021-06-11 08:46:20,jcb,3096.84 -2021-06-11 14:43:29,switch,3885.14 -2021-06-12 11:35:23,mastercard,1767.31 -2021-06-12 23:57:36,visa-electron,1553.45 -2021-06-13 00:22:40,diners-club-enroute,1320.72 -2021-06-13 06:42:57,bankcard,441.94 -2021-06-13 21:45:49,visa-electron,1142.07 -2021-06-13 22:47:29,china-unionpay,1684.71 -2021-06-14 05:06:07,switch,989.1 -2021-06-14 05:25:10,instapayment,3261.34 -2021-06-14 20:37:32,laser,2147.91 -2021-06-15 04:15:04,jcb,2724.28 -2021-06-15 08:50:14,maestro,3535.05 -2021-06-15 19:23:36,diners-club-international,2563.06 -2021-06-15 23:32:38,bankcard,3642.62 -2021-06-16 04:56:53,,1869.97 -2021-06-16 08:27:55,switch,1161.11 -2021-06-17 02:39:05,china-unionpay,383.33 -2021-06-17 03:41:56,switch,864.29 -2021-06-17 18:01:07,laser,1798.48 -2021-06-17 21:47:23,mastercard,1496.08 -2021-06-18 11:18:35,,3543.09 -2021-06-18 13:31:11,laser,1564.75 -2021-06-18 14:52:34,switch,3322.7 -2021-06-19 19:20:29,maestro,3993.48 -2021-06-20 00:38:53,,743.98 -2021-06-20 05:27:19,diners-club-enroute,976.51 -2021-06-21 13:24:47,diners-club-enroute,3479.83 -2021-06-21 13:50:13,jcb,3422.95 -2021-06-21 17:33:26,diners-club-carte-blanche,1114.87 -2021-06-21 20:46:05,jcb,1064.0 -2021-06-21 22:29:06,solo,3950.84 -2021-06-22 00:40:34,visa-electron,2973.7 -2021-06-22 01:21:51,bankcard,2837.43 -2021-06-22 03:13:20,diners-club-carte-blanche,3641.32 -2021-06-22 06:38:12,visa-electron,2296.36 -2021-06-22 07:15:16,,2011.23 -2021-06-22 10:46:08,diners-club-enroute,2693.44 -2021-06-22 12:13:43,jcb,2721.12 -2021-06-22 18:07:25,jcb,3715.59 -2021-06-23 12:57:52,jcb,1224.24 -2021-06-23 15:09:51,,3447.63 -2021-06-23 22:53:10,americanexpress,1862.82 -2021-06-24 03:16:39,jcb,2656.84 -2021-06-24 15:07:12,visa-electron,2942.76 -2021-06-25 00:17:39,jcb,1655.2 -2021-06-25 06:20:48,diners-club-enroute,2071.53 -2021-06-25 06:56:19,mastercard,1908.84 -2021-06-26 02:01:13,diners-club-enroute,1052.55 -2021-06-26 06:45:11,diners-club-enroute,1306.35 -2021-06-27 12:12:04,laser,874.94 -2021-06-27 16:05:46,,1444.2 -2021-06-27 19:19:13,jcb,619.66 -2021-06-27 23:55:42,diners-club-enroute,509.8 -2021-06-28 03:48:00,jcb,1912.41 -2021-06-28 03:52:42,jcb,3135.62 -2021-06-28 11:20:13,visa-electron,2973.91 -2021-06-29 15:02:07,diners-club-us-ca,1678.62 -2021-06-30 00:23:55,switch,719.33 -2021-06-30 08:26:54,,1254.24 -2021-07-01 04:42:50,mastercard,1578.15 -2021-07-01 09:07:40,,1059.88 -2021-07-01 10:37:51,switch,373.27 -2021-07-01 19:03:42,jcb,705.31 -2021-07-02 03:20:19,diners-club-us-ca,319.7 -2021-07-03 00:07:37,jcb,3760.74 -2021-07-03 04:58:49,jcb,1815.63 -2021-07-03 09:25:43,switch,2454.96 -2021-07-03 12:11:02,jcb,3835.12 -2021-07-04 01:38:05,jcb,2064.4 -2021-07-04 11:31:24,jcb,2902.39 -2021-07-04 19:12:49,jcb,550.88 -2021-07-04 23:16:32,switch,2814.37 -2021-07-05 12:24:49,,1686.33 -2021-07-06 06:31:38,diners-club-carte-blanche,3476.71 -2021-07-06 08:12:22,china-unionpay,1536.87 -2021-07-06 10:16:34,mastercard,3142.55 -2021-07-07 13:35:18,maestro,2421.28 -2021-07-07 18:33:46,jcb,3169.92 -2021-07-08 13:10:06,maestro,885.76 -2021-07-08 14:13:41,china-unionpay,1732.45 -2021-07-09 12:34:25,jcb,2764.45 -2021-07-10 09:49:28,diners-club-enroute,2952.23 -2021-07-10 13:09:50,americanexpress,3429.61 -2021-07-10 21:53:56,mastercard,3953.44 -2021-07-10 21:59:49,mastercard,776.45 -2021-07-11 19:38:36,mastercard,723.85 -2021-07-11 19:40:15,jcb,3024.17 -2021-07-11 22:48:47,switch,2992.17 -2021-07-12 00:13:49,switch,444.84 -2021-07-12 19:24:50,china-unionpay,1220.38 -2021-07-12 20:04:56,jcb,492.19 -2021-07-13 02:10:24,jcb,2694.56 -2021-07-13 14:18:57,jcb,3488.4 -2021-07-13 16:33:36,diners-club-carte-blanche,3352.39 -2021-07-13 20:24:33,bankcard,909.59 -2021-07-14 06:24:59,americanexpress,1220.75 -2021-07-14 19:30:39,americanexpress,2935.13 -2021-07-14 22:34:32,diners-club-carte-blanche,1964.28 -2021-07-15 09:59:29,jcb,3083.06 -2021-07-15 17:27:05,instapayment,3850.38 -2021-07-15 23:26:53,diners-club-carte-blanche,783.4 -2021-07-16 12:21:21,mastercard,2313.37 -2021-07-17 17:36:15,switch,3201.56 -2021-07-17 22:04:11,maestro,547.59 -2021-07-18 23:48:04,bankcard,464.0 -2021-07-19 03:04:40,jcb,2418.4 -2021-07-19 05:32:06,diners-club-international,2035.42 -2021-07-20 00:39:38,,2471.68 -2021-07-20 05:17:57,maestro,1163.58 -2021-07-20 11:34:56,jcb,3690.31 -2021-07-20 16:30:03,switch,2019.48 -2021-07-20 17:37:36,mastercard,3266.27 -2021-07-20 18:01:53,americanexpress,2069.35 -2021-07-20 21:22:10,jcb,2670.57 -2021-07-21 13:51:34,china-unionpay,2464.23 -2021-07-21 23:38:43,maestro,1676.45 -2021-07-22 05:27:20,maestro,1688.43 -2021-07-22 16:32:30,diners-club-us-ca,290.02 -2021-07-22 22:24:10,jcb,2778.02 -2021-07-23 11:33:16,mastercard,2857.96 -2021-07-23 14:28:57,diners-club-carte-blanche,2050.84 -2021-07-24 02:52:27,jcb,2343.23 -2021-07-24 04:00:57,jcb,763.26 -2021-07-24 10:19:13,maestro,1453.69 -2021-07-24 14:23:25,jcb,554.09 -2021-07-26 03:15:12,jcb,1843.18 -2021-07-26 12:54:16,jcb,1632.54 -2021-07-27 02:36:20,,3474.85 -2021-07-27 04:44:59,maestro,2019.39 -2021-07-27 07:02:37,maestro,975.17 -2021-07-28 01:43:55,jcb,3690.29 -2021-07-28 03:42:23,mastercard,1532.15 -2021-07-28 05:36:32,jcb,1298.47 -2021-07-28 07:37:49,jcb,490.5 -2021-07-28 13:15:45,diners-club-us-ca,3054.03 -2021-07-29 14:46:39,maestro,1539.48 -2021-07-30 00:34:16,jcb,331.52 -2021-07-30 08:34:43,visa-electron,3331.49 -2021-07-30 13:30:11,jcb,2981.68 -2021-07-30 20:05:03,china-unionpay,961.83 -2021-07-30 23:11:03,diners-club-enroute,2122.79 -2021-08-01 02:58:34,visa-electron,2675.75 -2021-08-02 05:48:50,switch,1880.9 -2021-08-02 08:56:52,maestro,212.4 -2021-08-03 00:27:46,jcb,2304.46 -2021-08-03 03:59:53,mastercard,3154.77 -2021-08-03 07:21:32,americanexpress,767.35 -2021-08-03 18:18:55,maestro,1689.05 -2021-08-03 22:53:43,jcb,1664.85 -2021-08-04 04:27:09,,290.54 -2021-08-04 16:48:19,instapayment,2253.24 -2021-08-04 22:03:11,switch,2626.11 -2021-08-04 23:27:44,diners-club-enroute,1542.05 -2021-08-05 17:00:38,jcb,3952.38 -2021-08-05 20:23:07,mastercard,2405.44 -2021-08-06 16:01:52,jcb,335.88 -2021-08-06 22:48:42,maestro,648.03 -2021-08-07 13:46:49,jcb,3621.06 -2021-08-08 02:33:28,maestro,3652.91 -2021-08-08 13:12:45,switch,290.13 -2021-08-08 14:57:00,jcb,3621.4 -2021-08-08 16:10:25,mastercard,1253.23 -2021-08-09 09:04:04,bankcard,2086.46 -2021-08-10 09:31:16,china-unionpay,2285.57 -2021-08-10 14:32:19,jcb,459.83 -2021-08-10 17:34:06,americanexpress,293.34 -2021-08-11 08:03:01,jcb,2895.56 -2021-08-11 16:32:37,diners-club-carte-blanche,2045.8 -2021-08-11 18:38:17,switch,2531.35 -2021-08-12 02:40:19,switch,1268.86 -2021-08-12 11:36:15,visa-electron,3271.38 -2021-08-12 12:04:26,americanexpress,2907.71 -2021-08-12 12:14:42,jcb,1825.42 -2021-08-13 05:33:22,mastercard,1718.48 -2021-08-13 05:47:13,diners-club-enroute,1043.93 -2021-08-13 07:51:14,mastercard,3589.45 -2021-08-13 16:26:42,mastercard,3135.59 -2021-08-14 22:01:50,jcb,1235.88 -2021-08-15 13:38:19,mastercard,2202.87 -2021-08-15 15:37:42,switch,3301.97 -2021-08-16 10:13:33,jcb,3083.57 -2021-08-16 19:34:27,jcb,2945.24 -2021-08-17 11:03:25,visa-electron,3805.84 -2021-08-17 12:08:14,jcb,2901.22 -2021-08-17 12:30:36,,2469.01 -2021-08-17 18:40:57,jcb,878.86 -2021-08-18 01:48:14,bankcard,1536.41 -2021-08-18 01:57:58,jcb,3725.2 -2021-08-18 06:16:58,jcb,3214.19 -2021-08-18 12:13:47,mastercard,2844.77 -2021-08-18 14:28:25,jcb,3363.9 -2021-08-18 15:10:58,jcb,1782.79 -2021-08-18 17:59:55,jcb,2034.74 -2021-08-19 08:39:27,switch,2809.27 -2021-08-20 11:38:46,mastercard,2178.54 -2021-08-20 15:53:21,jcb,3652.1 -2021-08-20 19:48:22,diners-club-enroute,1786.14 -2021-08-20 21:29:16,mastercard,2357.5 -2021-08-21 12:52:24,bankcard,688.94 -2021-08-21 18:41:15,jcb,796.68 -2021-08-21 22:13:59,visa,3181.61 -2021-08-22 00:14:43,instapayment,1958.24 -2021-08-22 08:16:18,jcb,1340.81 -2021-08-22 09:05:53,jcb,2464.56 -2021-08-22 16:17:03,maestro,3912.48 -2021-08-22 20:47:22,jcb,1499.06 -2021-08-23 02:17:01,jcb,1504.61 -2021-08-23 03:47:18,maestro,1703.08 -2021-08-23 06:01:49,instapayment,2930.42 -2021-08-24 22:29:56,diners-club-international,3931.6 -2021-08-26 10:05:15,americanexpress,2056.4 -2021-08-26 10:39:47,jcb,2246.72 -2021-08-26 14:06:15,jcb,3944.2 -2021-08-26 18:25:59,,598.63 -2021-08-26 20:33:30,jcb,1705.16 -2021-08-27 20:29:36,diners-club-us-ca,1109.29 -2021-08-28 19:30:00,mastercard,1895.89 -2021-08-29 12:18:56,,998.04 -2021-08-29 21:27:45,diners-club-carte-blanche,2636.01 -2021-08-29 22:25:26,switch,2772.31 -2021-08-30 12:24:15,jcb,3105.38 -2021-08-30 12:45:23,mastercard,3274.28 -2021-08-30 14:37:42,americanexpress,3281.45 -2021-08-30 15:10:03,jcb,3363.87 -2021-08-31 19:19:23,mastercard,525.25 -2021-08-31 19:38:30,jcb,3746.16 -2021-09-01 05:48:54,mastercard,2942.57 -2021-09-02 03:22:20,jcb,2780.14 -2021-09-02 18:40:54,,2661.14 -2021-09-03 09:33:42,jcb,1785.73 -2021-09-03 12:00:01,,2382.25 -2021-09-03 15:27:50,solo,3435.33 -2021-09-03 18:26:57,jcb,3933.43 -2021-09-04 00:10:21,jcb,1054.78 -2021-09-04 01:31:38,mastercard,3322.41 -2021-09-04 11:29:43,jcb,3258.22 -2021-09-04 13:33:31,jcb,3843.05 -2021-09-04 15:23:30,jcb,3146.0 -2021-09-04 20:57:03,diners-club-us-ca,3114.73 -2021-09-05 00:38:31,bankcard,3283.13 -2021-09-05 09:17:15,jcb,1240.97 -2021-09-06 07:54:19,jcb,2675.81 -2021-09-06 09:25:05,china-unionpay,881.11 -2021-09-06 18:42:47,mastercard,482.19 -2021-09-06 22:35:39,diners-club-enroute,3345.74 -2021-09-07 09:51:13,jcb,1495.04 -2021-09-08 04:11:28,visa-electron,2655.63 -2021-09-08 22:05:47,diners-club-carte-blanche,1198.58 -2021-09-09 12:15:09,jcb,2545.11 -2021-09-09 18:06:33,maestro,3242.2 -2021-09-09 19:24:43,jcb,1626.16 -2021-09-09 23:09:05,jcb,598.94 -2021-09-09 23:26:13,jcb,886.74 -2021-09-10 23:35:24,diners-club-enroute,3377.99 -2021-09-12 12:28:18,jcb,1410.65 -2021-09-12 16:10:48,,848.22 -2021-09-12 20:11:12,mastercard,2299.73 -2021-09-13 01:22:09,switch,272.5 -2021-09-13 14:05:30,maestro,1939.32 -2021-09-13 22:44:15,americanexpress,3108.6 -2021-09-14 16:51:31,diners-club-carte-blanche,233.12 -2021-09-16 06:11:32,instapayment,755.89 -2021-09-16 13:39:12,china-unionpay,2582.61 -2021-09-16 15:57:12,china-unionpay,476.29 -2021-09-16 16:11:20,jcb,2712.91 -2021-09-17 04:33:00,maestro,427.7 -2021-09-17 05:48:52,mastercard,434.55 -2021-09-17 18:46:10,jcb,3374.48 -2021-09-17 21:29:31,mastercard,3504.72 -2021-09-18 00:06:29,jcb,3300.72 -2021-09-18 14:59:49,maestro,347.81 -2021-09-18 19:20:32,jcb,2228.13 -2021-09-18 21:39:23,switch,701.17 -2021-09-19 04:28:26,china-unionpay,1662.81 -2021-09-19 08:06:44,,3264.51 -2021-09-19 08:51:31,jcb,1820.22 -2021-09-20 08:07:37,jcb,235.45 -2021-09-20 20:37:23,jcb,3457.97 -2021-09-21 00:03:16,diners-club-enroute,3860.2 -2021-09-21 14:06:20,,3042.73 -2021-09-21 15:28:24,,994.6 -2021-09-22 05:30:39,jcb,1752.93 -2021-09-22 19:06:26,jcb,1546.62 -2021-09-23 12:02:45,jcb,3351.65 -2021-09-24 17:15:23,americanexpress,3814.48 -2021-09-24 22:39:33,diners-club-enroute,1126.4 -2021-09-25 00:17:52,diners-club-carte-blanche,3749.37 -2021-09-25 03:53:13,americanexpress,1432.91 -2021-09-25 04:50:02,jcb,1364.59 -2021-09-25 07:04:48,,904.09 -2021-09-25 08:49:17,mastercard,1451.08 -2021-09-26 05:09:39,jcb,2490.91 -2021-09-26 15:44:37,diners-club-carte-blanche,621.15 -2021-09-26 18:32:55,bankcard,2566.7 -2021-09-27 13:48:33,jcb,1478.19 -2021-09-27 15:28:40,,2564.97 -2021-09-27 18:10:21,,629.08 -2021-09-27 22:36:30,laser,2879.4 -2021-09-28 01:14:36,maestro,3202.53 -2021-09-28 07:53:23,jcb,3826.62 -2021-09-29 21:06:07,laser,2180.47 -2021-09-29 22:11:28,,862.64 -2021-09-29 23:03:20,jcb,1693.44 -2021-09-30 04:36:51,visa-electron,1012.49 -2021-09-30 12:50:32,visa-electron,2549.26 -2021-09-30 21:26:57,laser,3869.69 -2021-10-01 07:48:52,diners-club-enroute,263.4 -2021-10-01 08:48:39,diners-club-enroute,3768.44 -2021-10-01 17:42:36,,2012.7 -2021-10-02 09:25:55,jcb,3408.88 -2021-10-02 19:38:47,diners-club-us-ca,3457.86 -2021-10-02 22:14:42,maestro,3990.25 -2021-10-03 05:45:11,jcb,555.39 -2021-10-03 14:32:07,jcb,877.71 -2021-10-04 11:57:20,diners-club-enroute,414.99 -2021-10-04 12:30:21,visa-electron,2820.43 -2021-10-04 17:05:33,jcb,2534.69 -2021-10-05 01:03:57,jcb,416.31 -2021-10-06 09:24:01,jcb,1156.87 -2021-10-06 11:22:54,maestro,2367.68 -2021-10-06 18:47:17,diners-club-carte-blanche,594.84 -2021-10-08 12:05:35,jcb,714.16 -2021-10-09 11:44:36,diners-club-enroute,2873.57 -2021-10-09 19:09:56,visa-electron,2004.25 -2021-10-10 03:39:14,jcb,1164.9 -2021-10-10 10:30:39,laser,2942.9 -2021-10-10 14:42:03,jcb,709.71 -2021-10-10 17:40:55,,2989.25 -2021-10-10 22:20:10,,2167.55 -2021-10-11 11:32:13,jcb,2788.86 -2021-10-11 18:31:04,switch,3433.99 -2021-10-11 21:19:22,jcb,846.71 -2021-10-12 00:26:10,jcb,2783.07 -2021-10-12 18:53:27,mastercard,1174.93 -2021-10-12 23:04:26,diners-club-carte-blanche,425.33 -2021-10-13 02:47:21,jcb,2773.06 -2021-10-13 08:36:26,diners-club-carte-blanche,1221.64 -2021-10-13 09:00:20,jcb,3721.14 -2021-10-13 12:41:29,,1266.41 -2021-10-13 22:28:15,mastercard,3553.82 -2021-10-13 22:38:40,americanexpress,3180.16 -2021-10-13 22:55:52,visa-electron,261.72 -2021-10-15 03:33:52,visa,1686.41 -2021-10-15 14:28:08,maestro,2397.38 -2021-10-16 11:59:31,jcb,1633.01 -2021-10-16 15:10:24,jcb,251.61 -2021-10-17 12:32:10,visa-electron,903.39 -2021-10-17 12:45:42,mastercard,2922.77 -2021-10-17 13:57:01,,1819.21 -2021-10-17 14:20:18,instapayment,3071.5 -2021-10-18 11:18:37,diners-club-enroute,3529.53 -2021-10-18 12:06:52,maestro,3422.83 -2021-10-19 23:46:33,,720.18 -2021-10-20 12:48:46,visa,2291.99 -2021-10-21 08:26:01,diners-club-enroute,243.9 -2021-10-21 16:36:27,switch,2861.78 -2021-10-21 17:54:29,jcb,2656.86 -2021-10-21 17:54:59,jcb,2616.86 -2021-10-21 21:36:15,maestro,1253.94 -2021-10-22 08:20:52,jcb,827.87 -2021-10-24 00:51:55,jcb,739.84 -2021-10-24 06:54:36,americanexpress,3649.25 -2021-10-24 16:57:04,solo,809.45 -2021-10-25 14:22:48,mastercard,1425.32 -2021-10-26 09:38:20,maestro,3588.1 -2021-10-26 10:40:43,jcb,3335.58 -2021-10-27 08:29:19,jcb,3843.77 -2021-10-27 14:16:38,,3907.82 -2021-10-27 14:33:15,jcb,553.05 -2021-10-29 05:58:55,americanexpress,3062.78 -2021-10-29 20:30:16,jcb,2769.49 -2021-10-30 01:08:35,maestro,2296.34 -2021-10-30 01:31:40,jcb,3687.6 -2021-10-30 02:21:05,maestro,2017.22 -2021-10-30 05:42:59,jcb,298.84 -2021-10-31 07:02:37,jcb,3997.56 -2021-10-31 07:19:07,jcb,217.39 -2021-10-31 11:54:29,,1249.87 -2021-11-01 12:20:56,visa-electron,2343.0 -2021-11-01 23:27:44,diners-club-us-ca,519.99 -2021-11-02 16:09:49,switch,1428.06 -2021-11-03 02:29:31,jcb,1217.55 -2021-11-03 12:29:17,jcb,3172.54 -2021-11-03 22:16:09,switch,3930.03 -2021-11-04 00:11:58,jcb,2486.08 -2021-11-04 07:26:12,jcb,416.38 -2021-11-04 12:58:14,china-unionpay,734.72 -2021-11-05 11:10:56,jcb,3909.43 -2021-11-05 11:31:30,maestro,2988.49 -2021-11-06 12:25:55,diners-club-carte-blanche,1960.27 -2021-11-06 15:48:53,,1852.25 -2021-11-08 05:23:25,maestro,2759.47 -2021-11-08 07:20:03,jcb,1517.15 -2021-11-08 09:23:16,jcb,1874.99 -2021-11-08 11:00:43,maestro,1001.5 -2021-11-08 14:50:50,jcb,889.15 -2021-11-08 21:13:58,jcb,2269.77 -2021-11-10 04:06:41,jcb,3994.32 -2021-11-10 17:09:19,,3708.21 -2021-11-10 19:46:31,bankcard,2032.78 -2021-11-11 06:47:06,switch,2485.27 -2021-11-11 09:13:07,bankcard,2012.8 -2021-11-11 09:33:51,diners-club-us-ca,2715.41 -2021-11-11 18:02:04,visa,1574.41 -2021-11-11 23:21:58,visa,3461.45 -2021-11-12 09:08:56,americanexpress,707.59 -2021-11-13 10:39:35,instapayment,2916.11 -2021-11-13 20:51:16,jcb,3844.49 -2021-11-13 23:29:50,china-unionpay,2443.29 -2021-11-14 18:58:30,,2902.65 -2021-11-14 19:30:02,jcb,274.24 -2021-11-14 20:04:11,jcb,300.92 -2021-11-15 15:17:22,americanexpress,1807.56 -2021-11-16 12:14:48,,3750.4 -2021-11-17 03:39:22,maestro,2374.96 -2021-11-17 06:57:09,china-unionpay,1014.08 -2021-11-17 11:12:48,jcb,1256.81 -2021-11-18 04:50:02,switch,2306.53 -2021-11-18 12:24:46,mastercard,997.76 -2021-11-18 12:38:26,jcb,1620.75 -2021-11-18 20:43:31,mastercard,3295.0 -2021-11-20 01:25:40,jcb,966.5 -2021-11-20 01:54:36,jcb,262.61 -2021-11-20 13:42:18,diners-club-enroute,704.06 -2021-11-20 22:41:07,jcb,3333.04 -2021-11-21 02:03:13,jcb,2039.55 -2021-11-21 04:22:55,diners-club-enroute,2300.09 -2021-11-21 12:16:46,jcb,3013.27 -2021-11-22 01:07:16,jcb,3554.34 -2021-11-22 21:30:14,jcb,623.76 -2021-11-23 02:52:17,jcb,3255.74 -2021-11-23 20:53:48,maestro,2982.37 -2021-11-24 00:29:10,jcb,1941.5 -2021-11-24 02:08:01,jcb,3346.24 -2021-11-24 12:15:48,jcb,1947.28 -2021-11-24 21:34:35,,1980.8 -2021-11-25 09:01:36,maestro,314.45 -2021-11-25 11:02:22,diners-club-us-ca,439.78 -2021-11-25 15:50:56,bankcard,2328.14 -2021-11-25 17:03:08,maestro,2523.48 -2021-11-25 18:01:59,jcb,731.65 -2021-11-25 21:19:14,jcb,597.26 -2021-11-26 04:22:17,visa-electron,2808.18 -2021-11-26 18:01:53,diners-club-carte-blanche,1040.51 -2021-11-26 19:52:40,jcb,2969.05 -2021-11-27 19:26:57,visa-electron,3444.85 -2021-11-28 21:27:21,jcb,2639.02 -2021-11-29 07:44:07,switch,755.6 -2021-11-29 08:36:09,bankcard,3317.18 -2021-11-29 15:26:12,,459.68 -2021-11-29 16:29:53,diners-club-international,2458.5 -2021-11-30 22:11:02,laser,625.78 -2021-12-01 04:13:03,jcb,2003.57 -2021-12-01 16:08:20,diners-club-enroute,3401.74 -2021-12-02 09:43:43,,3227.73 -2021-12-02 10:55:28,jcb,3561.5 -2021-12-02 11:06:17,jcb,1997.43 -2021-12-02 22:10:06,jcb,2989.83 -2021-12-03 10:23:35,mastercard,1413.42 -2021-12-04 21:14:57,jcb,3658.8 -2021-12-04 23:39:24,switch,3408.26 -2021-12-05 09:12:08,,2414.17 -2021-12-05 13:53:05,mastercard,3366.37 -2021-12-05 15:20:46,switch,2894.09 -2021-12-05 18:17:47,visa,3327.24 -2021-12-06 04:54:19,,3286.34 -2021-12-06 07:51:44,mastercard,1988.13 -2021-12-06 08:11:27,jcb,1296.06 -2021-12-06 18:39:26,jcb,2269.71 -2021-12-06 19:17:55,diners-club-carte-blanche,2522.87 -2021-12-08 10:10:58,china-unionpay,1896.32 -2021-12-08 14:46:09,diners-club-international,3619.8 -2021-12-08 18:00:04,jcb,1506.11 -2021-12-08 22:52:49,diners-club-enroute,3054.21 -2021-12-08 23:59:10,bankcard,1100.94 -2021-12-09 01:08:17,jcb,2480.56 -2021-12-09 08:11:56,instapayment,2465.37 -2021-12-09 08:41:05,,2774.98 -2021-12-09 12:41:39,laser,3944.15 -2021-12-09 16:18:30,diners-club-carte-blanche,3503.31 -2021-12-09 17:42:35,bankcard,2851.52 -2021-12-09 19:45:54,jcb,2266.09 -2021-12-10 06:24:02,jcb,450.65 -2021-12-10 08:16:31,diners-club-enroute,2707.36 -2021-12-10 13:08:15,,326.12 -2021-12-12 07:45:11,jcb,1102.28 -2021-12-12 23:00:52,jcb,2897.32 -2021-12-13 01:07:52,jcb,3830.19 -2021-12-13 05:17:21,,1088.1 -2021-12-14 01:52:57,china-unionpay,2306.85 -2021-12-14 04:11:47,bankcard,2631.44 -2021-12-14 05:43:48,,399.19 -2021-12-15 08:08:31,jcb,2152.66 -2021-12-15 10:07:17,visa-electron,2297.97 -2021-12-15 12:36:54,mastercard,3729.93 -2021-12-15 13:25:02,maestro,787.94 -2021-12-15 21:24:19,visa-electron,3503.98 -2021-12-16 03:59:36,jcb,942.02 -2021-12-16 04:24:09,diners-club-carte-blanche,1713.22 -2021-12-16 05:54:37,maestro,3268.08 -2021-12-16 08:19:37,visa,793.91 -2021-12-17 00:15:47,bankcard,231.33 -2021-12-17 02:48:46,bankcard,2354.56 -2021-12-17 12:16:00,china-unionpay,3591.64 -2021-12-17 13:27:30,jcb,2626.6 -2021-12-17 23:28:17,mastercard,2110.07 -2021-12-18 03:53:22,maestro,2234.9 -2021-12-18 18:46:02,visa-electron,3851.25 -2021-12-18 19:54:05,jcb,1375.78 -2021-12-18 21:53:56,bankcard,2638.25 -2021-12-19 00:30:21,,2335.3 -2021-12-19 05:06:28,laser,1093.17 -2021-12-19 15:17:48,,830.61 -2021-12-20 01:14:52,visa,300.19 -2021-12-20 06:37:37,jcb,444.02 -2021-12-20 14:01:12,switch,3641.61 -2021-12-21 15:30:43,instapayment,2344.89 -2021-12-21 20:25:46,diners-club-enroute,973.47 -2021-12-22 06:57:34,instapayment,3871.35 -2021-12-23 06:19:50,jcb,2848.07 -2021-12-23 09:55:42,jcb,1383.4 -2021-12-23 21:41:55,mastercard,2478.82 -2021-12-23 23:38:46,diners-club-enroute,2704.78 -2021-12-24 03:13:01,switch,2684.75 -2021-12-24 03:25:45,switch,3269.43 -2021-12-24 12:05:30,mastercard,2195.4 -2021-12-24 23:13:51,bankcard,949.57 -2021-12-25 08:20:16,mastercard,3143.16 -2021-12-25 18:59:09,jcb,3606.39 -2021-12-26 09:39:36,diners-club-enroute,1165.64 -2021-12-26 09:42:25,diners-club-enroute,3530.67 -2021-12-26 09:51:27,solo,941.91 -2021-12-28 02:34:23,bankcard,3558.32 -2021-12-28 03:20:50,diners-club-carte-blanche,728.13 -2021-12-28 22:15:00,jcb,763.58 -2021-12-29 09:34:36,jcb,2887.92 -2021-12-29 15:26:47,diners-club-enroute,398.8 -2021-12-29 16:32:56,americanexpress,3521.08 -2021-12-30 00:04:48,visa-electron,2065.2 -2021-12-30 12:54:40,jcb,2241.51 -2021-12-31 04:12:33,laser,764.27 -2021-12-31 09:58:47,jcb,2542.03 -2021-12-31 16:47:13,jcb,1992.9 -2022-01-01 01:05:50,solo,3159.16 -2022-01-01 09:37:03,diners-club-enroute,2891.76 -2022-01-01 12:36:27,china-unionpay,681.75 -2022-01-02 03:55:35,jcb,2144.06 -2022-01-02 14:46:47,laser,2896.77 -2022-01-02 21:42:29,mastercard,1527.66 -2022-01-03 20:41:23,americanexpress,2423.07 -2022-01-03 21:18:53,jcb,937.29 -2022-01-04 23:57:29,diners-club-enroute,1428.46 -2022-01-05 07:25:58,jcb,3092.61 -2022-01-05 15:51:06,switch,331.37 -2022-01-05 16:17:08,jcb,3975.42 -2022-01-05 19:49:52,china-unionpay,2081.41 -2022-01-05 21:28:32,switch,3212.21 -2022-01-06 10:27:08,jcb,3591.48 -2022-01-06 11:39:00,jcb,3599.19 -2022-01-06 12:11:08,mastercard,3803.13 -2022-01-06 20:24:44,visa-electron,3937.09 -2022-01-07 10:01:56,mastercard,1506.98 -2022-01-07 11:38:32,maestro,2064.05 -2022-01-07 17:07:56,visa,697.52 -2022-01-07 23:36:09,diners-club-enroute,3611.96 -2022-01-09 06:01:19,maestro,2149.4 -2022-01-09 06:39:29,diners-club-carte-blanche,1477.3 -2022-01-09 18:22:29,switch,683.49 -2022-01-09 22:40:57,maestro,3836.22 -2022-01-10 07:16:59,jcb,3381.81 -2022-01-10 11:39:19,jcb,329.53 -2022-01-10 19:55:09,,1948.57 -2022-01-11 06:49:25,jcb,515.06 -2022-01-11 09:29:51,jcb,1922.1 -2022-01-11 16:35:19,jcb,3893.78 -2022-01-11 22:08:37,jcb,400.95 -2022-01-12 01:01:08,diners-club-us-ca,1349.51 -2022-01-12 04:43:59,diners-club-international,1371.51 -2022-01-12 09:47:55,diners-club-carte-blanche,1031.59 -2022-01-12 13:28:53,visa,455.53 -2022-01-12 15:30:54,china-unionpay,1373.01 -2022-01-12 17:00:15,visa,2920.52 -2022-01-12 17:01:19,switch,339.23 -2022-01-13 00:12:03,mastercard,1186.38 -2022-01-13 04:52:01,jcb,3020.59 -2022-01-13 11:43:28,solo,935.21 -2022-01-13 17:00:31,diners-club-carte-blanche,3470.14 -2022-01-13 22:21:26,visa-electron,3310.62 -2022-01-14 06:57:21,jcb,1209.29 -2022-01-14 13:07:29,jcb,717.26 -2022-01-15 17:13:02,solo,3078.0 -2022-01-15 19:37:23,diners-club-enroute,2080.04 -2022-01-15 21:33:29,jcb,2365.57 -2022-01-15 21:36:30,jcb,2056.59 -2022-01-16 07:48:42,jcb,3231.73 -2022-01-16 10:30:58,bankcard,789.11 -2022-01-16 17:57:17,jcb,3532.14 -2022-01-17 00:50:18,maestro,2997.38 -2022-01-17 10:03:40,jcb,2101.24 -2022-01-17 14:08:46,bankcard,2940.12 -2022-01-17 16:15:42,jcb,598.51 -2022-01-17 17:13:10,visa,2598.26 -2022-01-17 21:26:11,jcb,1691.84 -2022-01-17 23:22:58,visa,2478.17 -2022-01-18 12:08:53,jcb,1803.13 -2022-01-19 05:33:12,maestro,2545.11 -2022-01-19 09:07:13,instapayment,3122.07 -2022-01-20 04:14:54,jcb,3106.68 -2022-01-20 04:30:09,instapayment,2645.07 -2022-01-20 10:28:10,instapayment,3786.63 -2022-01-20 18:20:04,mastercard,2640.43 -2022-01-21 13:47:18,jcb,3318.7 -2022-01-22 14:05:54,switch,2258.88 -2022-01-22 14:33:30,jcb,555.03 -2022-01-22 22:15:38,solo,1925.06 -2022-01-22 22:20:53,,1239.8 -2022-01-23 00:42:38,jcb,1396.7 -2022-01-23 17:35:42,,1782.37 -2022-01-23 19:27:32,visa-electron,1766.91 -2022-01-24 06:08:43,jcb,2126.74 -2022-01-24 10:49:43,maestro,1233.73 -2022-01-24 11:46:23,laser,1290.36 -2022-01-24 14:55:23,jcb,1911.51 -2022-01-25 00:43:20,diners-club-enroute,710.04 -2022-01-25 19:59:15,,2103.39 -2022-01-26 13:05:03,jcb,1382.06 -2022-01-26 18:25:16,jcb,696.04 -2022-01-26 21:35:52,maestro,1381.44 -2022-01-26 22:30:30,instapayment,2165.57 -2022-01-26 22:47:25,mastercard,2122.51 -2022-01-26 23:39:32,jcb,2304.53 -2022-01-27 03:38:39,bankcard,3528.37 -2022-01-27 05:42:01,switch,3928.68 -2022-01-28 01:19:08,jcb,3459.4 -2022-01-28 02:56:34,,1112.78 -2022-01-28 09:11:45,bankcard,3324.31 -2022-01-28 15:14:58,jcb,2220.51 -2022-01-28 19:55:01,solo,3457.66 -2022-01-29 01:53:13,maestro,632.89 -2022-01-29 03:44:30,jcb,481.24 -2022-01-29 09:48:31,switch,892.53 -2022-01-29 10:32:07,china-unionpay,1316.93 -2022-01-30 15:36:00,,352.25 -2022-01-31 04:30:30,switch,2725.62 -2022-01-31 09:24:25,jcb,1583.56 -2022-01-31 11:19:34,jcb,2445.25 -2022-01-31 11:51:20,americanexpress,845.43 -2022-01-31 22:17:36,,3936.23 -2022-02-01 12:50:25,jcb,3308.96 -2022-02-02 02:12:32,visa-electron,3141.63 -2022-02-02 07:24:53,diners-club-enroute,2450.03 -2022-02-02 18:38:54,americanexpress,2063.8 -2022-02-02 19:18:22,americanexpress,2652.11 -2022-02-02 22:57:05,visa-electron,3620.64 -2022-02-02 23:18:14,bankcard,3297.76 -2022-02-03 00:41:37,bankcard,955.28 -2022-02-03 11:27:51,jcb,1625.3 -2022-02-04 01:01:25,jcb,370.13 -2022-02-04 04:33:03,mastercard,960.88 -2022-02-04 13:41:20,diners-club-enroute,1792.35 -2022-02-04 20:43:37,jcb,3996.19 -2022-02-05 03:08:22,mastercard,525.29 -2022-02-05 11:13:25,jcb,1114.83 -2022-02-05 13:50:52,jcb,3201.77 -2022-02-05 23:56:22,jcb,1713.43 -2022-02-06 06:08:05,,2288.49 -2022-02-06 21:53:43,visa,1239.05 -2022-02-07 16:46:03,diners-club-carte-blanche,3320.14 -2022-02-07 17:02:13,jcb,2228.16 -2022-02-09 03:10:14,,1030.24 -2022-02-09 04:45:30,visa-electron,507.27 -2022-02-10 12:19:48,,3263.54 -2022-02-10 20:48:05,americanexpress,3919.08 -2022-02-11 00:24:47,jcb,606.65 -2022-02-11 05:12:23,diners-club-enroute,3199.34 -2022-02-11 06:45:39,visa-electron,1914.37 -2022-02-11 16:42:35,jcb,3592.14 -2022-02-11 18:02:51,china-unionpay,790.62 -2022-02-12 10:38:31,diners-club-carte-blanche,3189.65 -2022-02-13 13:39:29,jcb,2321.5 -2022-02-13 23:23:47,jcb,345.55 -2022-02-13 23:37:34,visa-electron,699.41 \ No newline at end of file +2021-02-14 17:52:36,maestro,10 +2021-02-15 04:16:50,jcb,10 +2021-02-15 11:30:45,solo,10 +2021-02-16 13:08:18,americanexpress,10 +2021-02-17 05:41:34,americanexpress,10 \ No newline at end of file diff --git a/macros/secondary_calculations/secondary_calculation_period_over_period.sql b/macros/secondary_calculations/secondary_calculation_period_over_period.sql index c0a2aec1..812e135b 100644 --- a/macros/secondary_calculations/secondary_calculation_period_over_period.sql +++ b/macros/secondary_calculations/secondary_calculation_period_over_period.sql @@ -28,7 +28,7 @@ {% endmacro %} {% macro default__metric_comparison_strategy_ratio(metric_name, calc_sql) %} - cast(coalesce({{ metric_name }}, 0) / nullif({{ calc_sql }}, 0) as {{ dbt_utils.type_float() }}) + cast(coalesce({{ metric_name }}, 0) as {{ dbt_utils.type_float() }}) / nullif({{ calc_sql }}, 0) {% endmacro %} {% macro period_over_period(comparison_strategy, interval, alias) %} diff --git a/macros/sql_gen/gen_joined_metrics_cte.sql b/macros/sql_gen/gen_joined_metrics_cte.sql index f6d64a49..e60a9b39 100644 --- a/macros/sql_gen/gen_joined_metrics_cte.sql +++ b/macros/sql_gen/gen_joined_metrics_cte.sql @@ -21,39 +21,47 @@ ,first_join_metrics as ( select - date_{{grain}}, + date_{{grain}} {% for calendar_dim in calendar_dimensions %} - coalesce( + ,coalesce( {% for metric_name in leaf_set %} {{metric_name}}__final.{{ calendar_dim }} {% if not loop.last %},{% endif %} + {% if leaf_set | length == 1 %} + ,NULL + {% endif %} {% endfor %} - ) as {{calendar_dim}}, + ) as {{calendar_dim}} {%- endfor %} {% for period in relevant_periods %} - coalesce( + ,coalesce( {% for metric_name in leaf_set %} {{metric_name}}__final.date_{{ period }} {% if not loop.last %},{% endif %} + {% if leaf_set | length == 1 %} + ,NULL + {% endif %} {% endfor %} - ) as date_{{period}}, + ) as date_{{period}} {% endfor %} {% for dim in dimensions %} - coalesce( + ,coalesce( {% for metric_name in leaf_set %} {{metric_name}}__final.{{ dim }} {% if not loop.last %},{% endif %} + {% if leaf_set | length == 1 %} + ,NULL + {% endif %} {% endfor %} - ) as {{dim}}, + ) as {{dim}} {%- endfor %} {% for metric_name in leaf_set %} - nullif({{metric_name}},0) as {{metric_name}} - {% if not loop.last %},{%endif%} + ,nullif({{metric_name}},0) as {{metric_name}} {% endfor %} from diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 00000000..29e6e859 --- /dev/null +++ b/pytest.ini @@ -0,0 +1,9 @@ +[pytest] +filterwarnings = + ignore:.*'soft_unicode' has been renamed to 'soft_str'*:DeprecationWarning + ignore:unclosed file .*:ResourceWarning +env_override_existing_values = 1 +env_files = + test.env +testpaths = + tests/functional \ No newline at end of file diff --git a/test.env.example b/test.env.example new file mode 100644 index 00000000..5f24aabf --- /dev/null +++ b/test.env.example @@ -0,0 +1,5 @@ +POSTGRES_TEST_HOST=localhost +POSTGRES_TEST_USER=root +POSTGRES_TEST_PASS=password +POSTGRES_TEST_PORT=5432 +POSTGRES_TEST_DBNAME=dbt \ No newline at end of file diff --git a/tests/conftest.py b/tests/conftest.py new file mode 100644 index 00000000..0b0dfe00 --- /dev/null +++ b/tests/conftest.py @@ -0,0 +1,59 @@ +import pytest +import os + +# Import the standard functional fixtures as a plugin +# Note: fixtures with session scope need to be local +pytest_plugins = ["dbt.tests.fixtures.project"] + +# The profile dictionary, used to write out profiles.yml +# dbt will supply a unique schema per test, so we do not specify 'schema' here + +# We use os.environ here instead of os.getenv because environ with [] input will +# return a KeyError exception instead of None or Default Value. It's better to know +# when the error is from the environment variables and not have it potentially lead +# you down a red herring path with other issues. +@pytest.fixture(scope="class") +def dbt_profile_target(): + + if os.environ['dbt_target'] == 'postgres': + return { + 'type': 'postgres', + 'threads': 1, + 'host': os.environ['POSTGRES_TEST_HOST'], + 'user': os.environ['POSTGRES_TEST_USER'], + 'password': os.environ['POSTGRES_TEST_PASSWORD'], + 'port': int(os.environ['POSTGRES_TEST_PORT']), + 'database': os.environ['POSTGRES_TEST_DB'], + } + + if os.environ['dbt_target'] == 'redshift': + return { + 'type': 'redshift', + 'threads': 1, + 'host': os.environ['REDSHIFT_TEST_HOST'], + 'user': os.environ['REDSHIFT_TEST_USER'], + 'pass': os.environ['REDSHIFT_TEST_PASS'], + 'dbname': os.environ['REDSHIFT_TEST_DBNAME'], + 'port': int(os.environ['REDSHIFT_TEST_PORT']), + } + + if os.environ['dbt_target'] == 'snowflake': + return { + 'type': 'snowflake', + 'threads': 1, + 'account': os.environ['SNOWFLAKE_TEST_ACCOUNT'], + 'user': os.environ['SNOWFLAKE_TEST_USER'], + 'password': os.environ['SNOWFLAKE_TEST_PASSWORD'], + 'role': os.environ['SNOWFLAKE_TEST_ROLE'], + 'database': os.environ['SNOWFLAKE_TEST_DATABASE'], + 'warehouse': os.environ['SNOWFLAKE_TEST_WAREHOUSE'], + } + + if os.environ['dbt_target'] == 'bigquery': + return { + 'type': 'bigquery', + 'threads': 1, + 'method': 'service-account', + 'project': os.environ['BIGQUERY_TEST_PROJECT'], + 'keyfile': os.environ['BIGQUERY_SERVICE_KEY_PATH'], + } \ No newline at end of file diff --git a/tests/functional/base_metric_types/test_base_average_metric.py b/tests/functional/base_metric_types/test_base_average_metric.py new file mode 100644 index 00000000..d39539f9 --- /dev/null +++ b/tests/functional/base_metric_types/test_base_average_metric.py @@ -0,0 +1,146 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/base_average_metric.sql +base_average_metric_sql = """ +select * +from +{{ metrics.calculate(metric('base_average_metric'), + grain='month' + ) +}} +""" + +# models/base_average_metric.yml +base_average_metric_yml = """ +version: 2 +models: + - name: base_average_metric + tests: + - dbt_utils.equality: + compare_model: ref('base_average_metric__expected') +metrics: + - name: base_average_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: average + sql: discount_total + dimensions: + - had_discount + - order_country +""" + +# seeds/base_average_metric__expected.csv +if os.getenv('dbt_target') == 'postgres': + base_average_metric__expected_csv = """ +date_month,base_average_metric +2022-01-01,1.00000000000000000000 +2022-02-01,1.3333333333333333 +""".lstrip() + +# seeds/base_average_metric__expected.csv +if os.getenv('dbt_target') == 'redshift': + base_average_metric__expected_csv = """ +date_month,base_average_metric +2022-01-01,1.00000000000000000000 +2022-02-01,1.3333333333333333 +""".lstrip() + +# seeds/base_average_metric__expected.csv +if os.getenv('dbt_target') == 'snowflake': + base_average_metric__expected_csv = """ +date_month,base_average_metric +2022-01-01,1.000000 +2022-02-01,1.333333 +""".lstrip() + +# seeds/base_average_metric__expected.csv +if os.getenv('dbt_target') == 'bigquery': + base_average_metric__expected_csv = """ +date_month,base_average_metric +2022-01-01,1.00000000000000000000 +2022-02-01,1.3333333333333333 +""".lstrip() + +# seeds/base_average_metric___expected.yml +if os.getenv('dbt_target') == 'bigquery': + base_average_metric__expected_yml = """ +version: 2 +seeds: + - name: base_average_metric__expected + config: + column_types: + date_month: date + base_average_metric: FLOAT64 +""".lstrip() +else: + base_average_metric__expected_yml = """""" + +class TestBaseAverageMetric: + # configuration in dbt_project.yml + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "base_average_metric__expected.csv": base_average_metric__expected_csv, + "base_average_metric__expected.yml": base_average_metric__expected_yml + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "base_average_metric.sql": base_average_metric_sql, + "base_average_metric.yml": base_average_metric_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/base_metric_types/test_base_count_distinct_metric.py b/tests/functional/base_metric_types/test_base_count_distinct_metric.py new file mode 100644 index 00000000..ac43ba6b --- /dev/null +++ b/tests/functional/base_metric_types/test_base_count_distinct_metric.py @@ -0,0 +1,108 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml +) + +# models/base_count_distinct_metric.sql +base_count_distinct_metric_sql = """ +select * +from +{{ metrics.calculate(metric('base_count_distinct_metric'), + grain='month' + ) +}} +""" + +# models/base_count_distinct_metric.yml +base_count_distinct_metric_yml = """ +version: 2 +models: + - name: base_count_distinct_metric + tests: + - dbt_utils.equality: + compare_model: ref('base_count_distinct_metric__expected') + +metrics: + - name: base_count_distinct_metric + model: ref('fact_orders') + label: Count Distinct + timestamp: order_date + time_grains: [day, week, month] + type: count_distinct + sql: customer_id + dimensions: + - had_discount + - order_country +""" + +# seeds/base_count_distinct_metric__expected.csv +base_count_distinct_metric__expected_csv = """ +date_month,base_count_distinct_metric +2022-01-01,5 +2022-02-01,3 +""".lstrip() + +class TestBaseCountDistinctMetric: + + # configuration in dbt_project.yml + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "base_count_distinct_metric__expected.csv": base_count_distinct_metric__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "base_count_distinct_metric.sql": base_count_distinct_metric_sql, + "base_count_distinct_metric.yml": base_count_distinct_metric_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/base_metric_types/test_base_count_metric.py b/tests/functional/base_metric_types/test_base_count_metric.py new file mode 100644 index 00000000..3b084ddf --- /dev/null +++ b/tests/functional/base_metric_types/test_base_count_metric.py @@ -0,0 +1,107 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/base_count_metric.sql +base_count_metric_sql = """ +select * +from +{{ metrics.calculate(metric('base_count_metric'), + grain='month' + ) +}} +""" + +# models/base_count_metric.yml +base_count_metric_yml = """ +version: 2 +models: + - name: base_count_metric + tests: + - dbt_utils.equality: + compare_model: ref('base_count_metric__expected') +metrics: + - name: base_count_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: count + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# seeds/base_count_metric__expected.csv +base_count_metric__expected_csv = """ +date_month,base_count_metric +2022-01-01,7 +2022-02-01,3 +""".lstrip() + +class TestBaseCountMetric: + + # configuration in dbt_project.yml + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "base_count_metric__expected.csv": base_count_metric__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "base_count_metric.sql": base_count_metric_sql, + "base_count_metric.yml": base_count_metric_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/base_metric_types/test_base_max_metric.py b/tests/functional/base_metric_types/test_base_max_metric.py new file mode 100644 index 00000000..03059903 --- /dev/null +++ b/tests/functional/base_metric_types/test_base_max_metric.py @@ -0,0 +1,107 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/base_max_metric.sql +base_max_metric_sql = """ +select * +from +{{ metrics.calculate(metric('base_max_metric'), + grain='month' + ) +}} +""" + +# models/base_max_metric.yml +base_max_metric_yml = """ +version: 2 +models: + - name: base_max_metric + tests: + - dbt_utils.equality: + compare_model: ref('base_max_metric__expected') +metrics: + - name: base_max_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: max + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# seeds/base_max_metric__expected.csv +base_max_metric__expected_csv = """ +date_month,base_max_metric +2022-01-01,2 +2022-02-01,4 +""".lstrip() + +class TestBaseMaxMetric: + + # configuration in dbt_project.yml + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "base_max_metric__expected.csv": base_max_metric__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "base_max_metric.sql": base_max_metric_sql, + "base_max_metric.yml": base_max_metric_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/base_metric_types/test_base_min_metric.py b/tests/functional/base_metric_types/test_base_min_metric.py new file mode 100644 index 00000000..d4f0ddea --- /dev/null +++ b/tests/functional/base_metric_types/test_base_min_metric.py @@ -0,0 +1,107 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/base_min_metric.sql +base_min_metric_sql = """ +select * +from +{{ metrics.calculate(metric('base_min_metric'), + grain='month' + ) +}} +""" + +# models/base_min_metric.yml +base_min_metric_yml = """ +version: 2 +models: + - name: base_min_metric + tests: + - dbt_utils.equality: + compare_model: ref('base_min_metric__expected') +metrics: + - name: base_min_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: min + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# seeds/base_min_metric__expected.csv +base_min_metric__expected_csv = """ +date_month,base_min_metric +2022-01-01,1 +2022-02-01,1 +""".lstrip() + +class TestBaseMinMetric: + + # configuration in dbt_project.yml + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "base_min_metric__expected.csv": base_min_metric__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "base_min_metric.sql": base_min_metric_sql, + "base_min_metric.yml": base_min_metric_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/base_metric_types/test_base_sum_metric.py b/tests/functional/base_metric_types/test_base_sum_metric.py new file mode 100644 index 00000000..2b32838d --- /dev/null +++ b/tests/functional/base_metric_types/test_base_sum_metric.py @@ -0,0 +1,107 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/base_sum_metric.sql +base_sum_metric_sql = """ +select * +from +{{ metrics.calculate(metric('base_sum_metric'), + grain='month' + ) +}} +""" + +# models/base_sum_metric.yml +base_sum_metric_yml = """ +version: 2 +models: + - name: base_sum_metric + tests: + - dbt_utils.equality: + compare_model: ref('base_sum_metric__expected') +metrics: + - name: base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# seeds/base_sum_metric__expected.csv +base_sum_metric__expected_csv = """ +date_month,base_sum_metric +2022-01-01,8 +2022-02-01,6 +""".lstrip() + +class TestBaseSumMetric: + + # configuration in dbt_project.yml + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "base_sum_metric__expected.csv": base_sum_metric__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "base_sum_metric.sql": base_sum_metric_sql, + "base_sum_metric.yml": base_sum_metric_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/expression_metric_types/test_expression_metric.py b/tests/functional/expression_metric_types/test_expression_metric.py new file mode 100644 index 00000000..c0b6ec5a --- /dev/null +++ b/tests/functional/expression_metric_types/test_expression_metric.py @@ -0,0 +1,123 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/expression_metric.sql +expression_metric_sql = """ +select * +from +{{ metrics.calculate(metric('expression_metric'), + grain='month' + ) +}} +""" + +# models/base_sum_metric.yml +base_sum_metric_yml = """ +version: 2 +metrics: + - name: base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# models/expression_metric.yml +expression_metric_yml = """ +version: 2 +models: + - name: expression_metric + tests: + - dbt_utils.equality: + compare_model: ref('expression_metric__expected') +metrics: + - name: expression_metric + label: Expression ($) + timestamp: order_date + time_grains: [day, week, month] + type: expression + sql: "{{metric('base_sum_metric')}} + 1" + dimensions: + - had_discount + - order_country +""" + +# seeds/expression_metric__expected.csv +expression_metric__expected_csv = """ +date_month,base_sum_metric,expression_metric +2022-02-01,6,7 +2022-01-01,8,9 +""".lstrip() + +class TestExpressionMetric: + + # configuration in dbt_project.yml + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "expression_metric__expected.csv": expression_metric__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.yml": fact_orders_yml, + "base_sum_metric.yml": base_sum_metric_yml, + "expression_metric.yml": expression_metric_yml, + "fact_orders.sql": fact_orders_sql, + "expression_metric.sql": expression_metric_sql + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/expression_metric_types/test_metric_on_expression_metric.py b/tests/functional/expression_metric_types/test_metric_on_expression_metric.py new file mode 100644 index 00000000..6f03a915 --- /dev/null +++ b/tests/functional/expression_metric_types/test_metric_on_expression_metric.py @@ -0,0 +1,133 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/metric_on_expression_metric.sql +metric_on_expression_metric_sql = """ +select * +from +{{ metrics.calculate(metric('metric_on_expression_metric'), + grain='month' + ) +}} +""" + +# models/base_sum_metric.yml +base_sum_metric_yml = """ +version: 2 +metrics: + - name: base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# models/expression_metric.yml +metric_on_expression_metric_yml = """ +version: 2 +models: + - name: metric_on_expression_metric + tests: + - dbt_utils.equality: + compare_model: ref('metric_on_expression_metric__expected') +metrics: + - name: expression_metric + label: Expression ($) + timestamp: order_date + time_grains: [day, week, month] + type: expression + sql: "{{metric('base_sum_metric')}} + 1" + dimensions: + - had_discount + - order_country + + - name: metric_on_expression_metric + label: Expression ($) + timestamp: order_date + time_grains: [day, week, month] + type: expression + sql: "{{metric('expression_metric')}} + 1" + dimensions: + - had_discount + - order_country +""" + +# seeds/metric_on_expression_metric__expected.csv +metric_on_expression_metric__expected_csv = """ +date_month,base_sum_metric,expression_metric,metric_on_expression_metric +2022-02-01,6,7,8 +2022-01-01,8,9,10 +""".lstrip() + +class TestMetricOnExpressionMetric: + + # configuration in dbt_project.yml + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "metric_on_expression_metric__expected.csv": metric_on_expression_metric__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.yml": fact_orders_yml, + "base_sum_metric.yml": base_sum_metric_yml, + "metric_on_expression_metric.yml": metric_on_expression_metric_yml, + "fact_orders.sql": fact_orders_sql, + "metric_on_expression_metric.sql": metric_on_expression_metric_sql + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/expression_metric_types/test_ratio_metric.py b/tests/functional/expression_metric_types/test_ratio_metric.py new file mode 100644 index 00000000..c85604ff --- /dev/null +++ b/tests/functional/expression_metric_types/test_ratio_metric.py @@ -0,0 +1,182 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/ratio_metric.sql +ratio_metric_sql = """ +select * +from +{{ metrics.calculate(metric('ratio_metric'), + grain='month' + ) +}} +""" + +# models/base_sum_metric.yml +base_sum_metric_yml = """ +version: 2 +metrics: + - name: base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# models/base_average_metric.yml +base_average_metric_yml = """ +version: 2 +metrics: + - name: base_average_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: average + sql: discount_total + dimensions: + - had_discount + - order_country +""" + +# models/ratio_metric.yml +ratio_metric_yml = """ +version: 2 +models: + - name: ratio_metric + tests: + - dbt_utils.equality: + compare_model: ref('ratio_metric__expected') +metrics: + - name: ratio_metric + label: Ratio ($) + timestamp: order_date + time_grains: [day, week, month] + type: expression + sql: "{{metric('base_sum_metric')}} / {{metric('base_average_metric')}}" + dimensions: + - had_discount + - order_country +""" + +# seeds/ratio_metric__expected.csv +if os.getenv('dbt_target') == 'postgres': + ratio_metric__expected_csv = """ +date_month,base_sum_metric,base_average_metric,ratio_metric +2022-02-01,6,1.3333333333333333,4.5 +2022-01-01,8,1.0,8.0 +""".lstrip() + +# seeds/ratio_metric__expected.csv +if os.getenv('dbt_target') == 'redshift': + ratio_metric__expected_csv = """ +date_month,base_sum_metric,base_average_metric,ratio_metric +2022-02-01,6,1.3333333333333333,4.5 +2022-01-01,8,1.0,8.0 +""".lstrip() + +# seeds/ratio_metric__expected.csv +if os.getenv('dbt_target') == 'snowflake': + ratio_metric__expected_csv = """ +date_month,base_sum_metric,base_average_metric,ratio_metric +2022-02-01,6,1.333333,4.500001 +2022-01-01,8,1.000000,8.000000 +""".lstrip() + +# seeds/ratio_metric__expected.csv +if os.getenv('dbt_target') == 'bigquery': + ratio_metric__expected_csv = """ +date_month,base_sum_metric,base_average_metric,ratio_metric +2022-02-01,6,1.3333333333333333,4.5 +2022-01-01,8,1.0,8.0 +""".lstrip() + +# seeds/ratio_metric___expected.yml +if os.getenv('dbt_target') == 'bigquery': + ratio_metric__expected_yml = """ +version: 2 +seeds: + - name: ratio_metric__expected + config: + column_types: + date_month: date + base_sum_metric: INT64 + base_average_metric: FLOAT64 + ratio_metric: FLOAT64 +""".lstrip() +else: + ratio_metric__expected_yml = """""" + +class TestRatioMetric: + + # configuration in dbt_project.yml + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"}, + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "ratio_metric__expected.csv": ratio_metric__expected_csv, + "ratio_metric__expected.yml": ratio_metric__expected_yml + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.yml": fact_orders_yml, + "base_average_metric.yml": base_average_metric_yml, + "base_sum_metric.yml": base_sum_metric_yml, + "ratio_metric.yml": ratio_metric_yml, + "fact_orders.sql": fact_orders_sql, + "ratio_metric.sql": ratio_metric_sql + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/fixtures.py b/tests/functional/fixtures.py new file mode 100644 index 00000000..4ab0ca77 --- /dev/null +++ b/tests/functional/fixtures.py @@ -0,0 +1,122 @@ +# seeds/seed_slack_users.csv +seed_slack_users_csv = """ +user_id,joined_at,is_active_past_quarter,has_messaged +1,2021-01-01,true,true +2,2021-02-03,false,true +3,2021-04-01,false,false +4,2021-04-08,false,false +""".lstrip() + +# seeds/fact_orders_source.csv +fact_orders_source_csv = """ +order_id,order_country,order_total,had_discount,customer_id,order_date +4,France,1,true,3,2022-01-06 +5,France,1,false,4,2022-01-08 +3,France,1,false,1,2022-01-13 +2,Japan,1,false,2,2022-01-20 +6,Japan,1,false,5,2022-01-21 +7,Japan,1,true,2,2022-01-22 +1,France,2,false,1,2022-01-28 +9,Japan,1,false,2,2022-02-03 +10,Japan,1,false,3,2022-02-13 +8,France,4,true,1,2022-02-15 +""".lstrip() + +# seeds/dim_customers_source.csv +dim_customers_source_csv = """ +customer_id,first_name,last_name,email,gender,is_new_customer,date_added +1,Geodude,Hills,bhills0@altervista.org,Male,FALSE,2022-01-01 +2,Mew,Coxhead,mcoxhead1@symantec.com,Genderfluid,TRUE,2022-01-06 +3,Mewtwo,Redish,aredish2@last.fm,Genderqueer,FALSE,2022-01-13 +4,Charizard,Basant,lbasant3@dedecms.com,Female,TRUE,2022-02-01 +5,Snorlax,Pokemon,the_email@dedecms.com,Male,TRUE,2022-02-03 +""".lstrip() + +# seeds/mock_purchase_data.csv +mock_purchase_data_csv = """ +purchased_at,payment_type,payment_total +2021-02-14,maestro,10 +2021-02-15,jcb,10 +2021-02-15,solo,10 +2021-02-16,americanexpress,10 +2021-02-17,americanexpress,10 +""".lstrip() + +# models/fact_orders.sql +fact_orders_sql = """ +select + * + ,round(order_total - (order_total/2)) as discount_total +from {{ref('fact_orders_source')}} +""" + +# models/dim_customers.sql +dim_customers_sql = """ +select * from {{ref('dim_customers_source')}} +""" + +# models/combined__orders_customers.sql +combined__orders_customers_sql = """ +with orders as ( + select * from {{ ref('fact_orders') }} +) +, +customers as ( + select * from {{ ref('dim_customers') }} +) +, +final as ( + select * + from orders + left join customers using (customer_id) +) +select * from final +""" + + +# models/fact_orders.yml +fact_orders_yml = """ +version: 2 +models: + - name: fact_orders + columns: + - name: order_id + description: TBD + - name: order_country + description: TBD + - name: order_total + description: TBD + - name: had_discount + description: TBD + - name: customer_id + description: TBD + - name: order_date + description: TBD +""" + +# models/dim_customers.yml +dim_customers_yml = """ +version: 2 +models: + - name: dim_customers + columns: + - name: customer_id + description: TBD + - name: first_name + description: TBD + - name: last_name + description: TBD + - name: email + description: TBD + - name: gender + description: TBD + + - name: is_new_customer + description: TBD +""" + +# packages.yml +packages_yml = """ + - package: calogica/dbt_expectations + version: [">=0.5.0", "<0.6.0"] +""" \ No newline at end of file diff --git a/tests/functional/invalid_configs/test_invalid_dimension.py b/tests/functional/invalid_configs/test_invalid_dimension.py new file mode 100644 index 00000000..afc4aeff --- /dev/null +++ b/tests/functional/invalid_configs/test_invalid_dimension.py @@ -0,0 +1,136 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/invalid_dimension.sql +invalid_dimension_sql = """ +select * +from +{{ metrics.calculate(metric('invalid_dimension'), + grain='year', + dimensions=['invalid_dimension_name'] + ) +}} +""" + +# models/multiple_metrics.sql +multiple_metrics_sql = """ +select * +from +{{ metrics.calculate( + [metric('base_sum_metric'), metric('base_count_metric')], + grain='month', + dimensions=['invalid_dimension_name'] + ) +}} +""" + +# models/invalid_dimension.yml +invalid_dimension_yml = """ +version: 2 +models: + - name: invalid_dimension + +metrics: + - name: invalid_dimension + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: count + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# models/multiple_metrics.yml +multiple_metrics_yml = """ +version: 2 +models: + - name: multiple_metrics + tests: + - dbt_utils.equality: + compare_model: ref('multiple_metrics__expected') +metrics: + - name: base_count_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: count + sql: order_total + dimensions: + - had_discount + - order_country + + - name: base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +class TestInvalidDimension: + + # configuration in dbt_project.yml + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "invalid_dimension.sql": invalid_dimension_sql, + "invalid_dimension.yml": invalid_dimension_yml, + "multiple_metrics.yml": multiple_metrics_yml, + "multiple_metrics.sql": multiple_metrics_sql + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 1 + + # Here we expect the run to fail because the incorrect + # time grain won't allow it to compile + results = run_dbt(["run"], expect_pass = False) \ No newline at end of file diff --git a/tests/functional/invalid_configs/test_invalid_expression_metric.py b/tests/functional/invalid_configs/test_invalid_expression_metric.py new file mode 100644 index 00000000..316bd814 --- /dev/null +++ b/tests/functional/invalid_configs/test_invalid_expression_metric.py @@ -0,0 +1,89 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt +from dbt.exceptions import CompilationException, ParsingException + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/invalid_expression_metric.sql +invalid_expression_metric_sql = """ +select * +from +{{ metrics.calculate(metric('invalid_expression_metric'), + grain='month' + ) +}} +""" + +# models/invalid_expression_metric.yml +invalid_expression_metric_yml = """ +version: 2 +models: + - name: invalid_expression_metric + +metrics: + - name: invalid_expression_metric + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: expression + sql: order_total + dimensions: + - had_discount + - order_country +""" + +class TestInvalidExpressionMetric: + + # configuration in dbt_project.yml + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "invalid_expression_metric.sql": invalid_expression_metric_sql, + "invalid_expression_metric.yml": invalid_expression_metric_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 1 + + # Here we expect the run to fail because the incorrect + # config won't allow it to compile + results = run_dbt(["run"], expect_pass = False) \ No newline at end of file diff --git a/tests/functional/invalid_configs/test_invalid_metric_name.py b/tests/functional/invalid_configs/test_invalid_metric_name.py new file mode 100644 index 00000000..b6e34dcf --- /dev/null +++ b/tests/functional/invalid_configs/test_invalid_metric_name.py @@ -0,0 +1,85 @@ +from configparser import ParsingError +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt +from dbt.exceptions import CompilationException, ParsingException + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/invalid_metric_name.sql +invalid_metric_name_sql = """ +select * +from +{{ metrics.calculate(metric('invalid metric name'), + grain='month' + ) +}} +""" + +# models/invalid_metric_name.yml +invalid_metric_name_yml = """ +version: 2 +models: + - name: invalid_metric_name + +metrics: + - name: invalid metric name + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: count + sql: order_total + dimensions: + - had_discount + - order_country +""" + +class TestInvalidMetricName: + + # configuration in dbt_project.yml + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "invalid_metric_name.sql": invalid_metric_name_sql, + "invalid_metric_name.yml": invalid_metric_name_yml + } + + def test_model_name(self,project,): + # initial run + with pytest.raises(ParsingException): + run_dbt(["deps"]) + run_dbt(["run"]) \ No newline at end of file diff --git a/tests/functional/invalid_configs/test_invalid_period_to_date_average.py b/tests/functional/invalid_configs/test_invalid_period_to_date_average.py new file mode 100644 index 00000000..2366ba1a --- /dev/null +++ b/tests/functional/invalid_configs/test_invalid_period_to_date_average.py @@ -0,0 +1,93 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/invalid_period_to_date_average.sql +invalid_period_to_date_average_sql = """ +select * +from +{{ metrics.calculate(metric('invalid_period_to_date_average'), + grain='month', + secondary_calculations=[ + metrics.period_to_date(aggregate="average", period="year", alias="this_year_average") + ] + ) +}} +""" + +# models/invalid_period_to_date_average.yml +invalid_period_to_date_average_yml = """ +version: 2 +models: + - name: invalid_period_to_date_average + tests: + - dbt_utils.equality: + compare_model: ref('invalid_period_to_date_average__expected') +metrics: + - name: invalid_period_to_date_average + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: average + sql: discount_total + dimensions: + - had_discount + - order_country +""" + +class TestInvalidPeriodToDateAverage: + + # configuration in dbt_project.yml + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "invalid_period_to_date_average.sql": invalid_period_to_date_average_sql, + "invalid_period_to_date_average.yml": invalid_period_to_date_average_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 1 + + # initial run + results = run_dbt(["run"], expect_pass = False) diff --git a/tests/functional/invalid_configs/test_invalid_time_grain.py b/tests/functional/invalid_configs/test_invalid_time_grain.py new file mode 100644 index 00000000..a9313c82 --- /dev/null +++ b/tests/functional/invalid_configs/test_invalid_time_grain.py @@ -0,0 +1,135 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/invalid_time_grain.sql +invalid_time_grain_sql = """ +select * +from +{{ metrics.calculate(metric('invalid_time_grain'), + grain='year' + ) +}} +""" + +# models/multiple_metrics.sql +multiple_metrics_sql = """ +select * +from +{{ metrics.calculate( + [metric('base_sum_metric'), metric('base_count_metric')], + grain='year' + ) +}} +""" + + +# models/invalid_time_grain.yml +invalid_time_grain_yml = """ +version: 2 +models: + - name: invalid_time_grain + +metrics: + - name: invalid_time_grain + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: count + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# models/multiple_metrics.yml +multiple_metrics_yml = """ +version: 2 +models: + - name: multiple_metrics + tests: + - dbt_utils.equality: + compare_model: ref('multiple_metrics__expected') +metrics: + - name: base_count_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: count + sql: order_total + dimensions: + - had_discount + - order_country + + - name: base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month, year] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +class TestInvalidTimeGrain: + + # configuration in dbt_project.yml + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "invalid_time_grain.sql": invalid_time_grain_sql, + "invalid_time_grain.yml": invalid_time_grain_yml, + "multiple_metrics.sql": multiple_metrics_sql, + "multiple_metrics.yml": multiple_metrics_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 1 + + # Here we expect the run to fail because the incorrect + # time grain won't allow it to compile + results = run_dbt(["run"], expect_pass = False) \ No newline at end of file diff --git a/tests/functional/invalid_configs/test_undefined_metric.py b/tests/functional/invalid_configs/test_undefined_metric.py new file mode 100644 index 00000000..66fb70b4 --- /dev/null +++ b/tests/functional/invalid_configs/test_undefined_metric.py @@ -0,0 +1,87 @@ +from configparser import ParsingError +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt +from dbt.exceptions import CompilationException, ParsingException + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/undefined_metric.sql +undefined_metric_sql = """ +select * +from +{{ metrics.calculate(metric('undefined_metric'), + grain='month' + ) +}} +""" + +# models/undefined_metric.yml +undefined_metric_yml = """ +version: 2 +models: + - name: undefined_metric + +metrics: + - name: not_undefined_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: count + sql: order_total + dimensions: + - had_discount + - order_country +""" + +class TestUndefinedMetric: + + # configuration in dbt_project.yml + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "undefined_metric.sql": undefined_metric_sql, + "undefined_metric.yml": undefined_metric_yml + } + + def test_undefined_metric(self,project,): + results = run_dbt(["deps"]) + # Here we expect the run to fail because the macro is calling + # an undefined metric + with pytest.raises(CompilationException): + run_dbt(["seed"]) + run_dbt(["run"]) \ No newline at end of file diff --git a/tests/functional/metric_options/date_grains/test_day_grain.py b/tests/functional/metric_options/date_grains/test_day_grain.py new file mode 100644 index 00000000..187f49b7 --- /dev/null +++ b/tests/functional/metric_options/date_grains/test_day_grain.py @@ -0,0 +1,154 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/day_grain_metric.sql +day_grain_metric_sql = """ +select * +from +{{ metrics.calculate(metric('day_grain_metric'), + grain='day' + ) +}} +""" + +# models/day_grain_metric.yml +day_grain_metric_yml = """ +version: 2 +models: + - name: day_grain_metric + tests: + - dbt_utils.equality: + compare_model: ref('day_grain__expected') +metrics: + - name: day_grain_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: count + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# seeds/day_grain__expected.csv +day_grain__expected_csv = """ +date_day,day_grain_metric +2022-02-15,1 +2022-02-14,0 +2022-02-13,1 +2022-02-12,0 +2022-02-11,0 +2022-02-10,0 +2022-02-09,0 +2022-02-08,0 +2022-02-07,0 +2022-02-06,0 +2022-02-05,0 +2022-02-04,0 +2022-02-03,1 +2022-02-02,0 +2022-02-01,0 +2022-01-31,0 +2022-01-30,0 +2022-01-29,0 +2022-01-28,1 +2022-01-27,0 +2022-01-26,0 +2022-01-25,0 +2022-01-24,0 +2022-01-23,0 +2022-01-22,1 +2022-01-21,1 +2022-01-20,1 +2022-01-19,0 +2022-01-18,0 +2022-01-17,0 +2022-01-16,0 +2022-01-15,0 +2022-01-14,0 +2022-01-13,1 +2022-01-12,0 +2022-01-11,0 +2022-01-10,0 +2022-01-09,0 +2022-01-08,1 +2022-01-07,0 +2022-01-06,1 +""".lstrip() + +class TestDayGrain: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "day_grain__expected.csv": day_grain__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "day_grain_metric.sql": day_grain_metric_sql, + "day_grain_metric.yml": day_grain_metric_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/date_grains/test_month_grain.py b/tests/functional/metric_options/date_grains/test_month_grain.py new file mode 100644 index 00000000..d8c2236b --- /dev/null +++ b/tests/functional/metric_options/date_grains/test_month_grain.py @@ -0,0 +1,114 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/month_grain_metric.sql +month_grain_metric_sql = """ +select * +from +{{ metrics.calculate(metric('month_grain_metric'), + grain='month' + ) +}} +""" + +# models/month_grain_metric.yml +month_grain_metric_yml = """ +version: 2 +models: + - name: month_grain_metric + tests: + - dbt_utils.equality: + compare_model: ref('month_grain__expected') +metrics: + - name: month_grain_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: count + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# seeds/month_grain__expected.csv +month_grain__expected_csv = """ +date_month,month_grain_metric +2022-02-01,3 +2022-01-01,7 +""".lstrip() + +class TestmonthGrain: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "month_grain__expected.csv": month_grain__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "month_grain_metric.sql": month_grain_metric_sql, + "month_grain_metric.yml": month_grain_metric_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/date_grains/test_week_grain.py b/tests/functional/metric_options/date_grains/test_week_grain.py new file mode 100644 index 00000000..a8763822 --- /dev/null +++ b/tests/functional/metric_options/date_grains/test_week_grain.py @@ -0,0 +1,133 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/week_grain_metric.sql +week_grain_metric_sql = """ +select * +from +{{ metrics.calculate(metric('week_grain_metric'), + grain='week' + ) +}} +""" + +# models/week_grain_metric.yml +week_grain_metric_yml = """ +version: 2 +models: + - name: week_grain_metric + tests: + - dbt_utils.equality: + compare_model: ref('week_grain__expected') +metrics: + - name: week_grain_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: count + sql: order_total + dimensions: + - had_discount + - order_country +""" + +if os.getenv('dbt_target') == 'bigquery': + # seeds/week_grain__expected.csv + week_grain__expected_csv = """ +date_week,week_grain_metric +2022-02-13,2 +2022-02-06,0 +2022-01-30,1 +2022-01-23,1 +2022-01-16,3 +2022-01-09,1 +2022-01-02,2 +""".lstrip() +else: + # seeds/week_grain__expected.csv + week_grain__expected_csv = """ +date_week,week_grain_metric +2022-02-14,1 +2022-02-07,1 +2022-01-31,1 +2022-01-24,1 +2022-01-17,3 +2022-01-10,1 +2022-01-03,2 +""".lstrip() + +class TestWeekGrain: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "week_grain__expected.csv": week_grain__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "week_grain_metric.sql": week_grain_metric_sql, + "week_grain_metric.yml": week_grain_metric_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/dimensions/test_multi_dimension_base_metric.py b/tests/functional/metric_options/dimensions/test_multi_dimension_base_metric.py new file mode 100644 index 00000000..e99aa02d --- /dev/null +++ b/tests/functional/metric_options/dimensions/test_multi_dimension_base_metric.py @@ -0,0 +1,122 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/multi_dimension_base_sum_metric.sql +multi_dimension_base_sum_metric_sql = """ +select * +from +{{ metrics.calculate(metric('multi_dimension_base_sum_metric'), + grain='month', + dimensions=['had_discount','order_country'] + ) +}} +""" + +# models/multi_dimension_base_sum_metric.yml +multi_dimension_base_sum_metric_yml = """ +version: 2 +models: + - name: multi_dimension_base_sum_metric + tests: + - dbt_utils.equality: + compare_model: ref('multi_dimension_base_sum_metric__expected') +metrics: + - name: multi_dimension_base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# seeds/multi_dimension_base_sum_metric__expected.csv +multi_dimension_base_sum_metric__expected_csv = """ +date_month,had_discount,order_country,multi_dimension_base_sum_metric +2022-01-01,TRUE,France,1 +2022-01-01,TRUE,Japan,1 +2022-01-01,FALSE,France,4 +2022-01-01,FALSE,Japan,2 +2022-02-01,TRUE,France,4 +2022-02-01,FALSE,France,0 +2022-02-01,FALSE,Japan,2 +2022-02-01,TRUE,Japan,0 +""".lstrip() + +class TestMultiDimensionBaseSumMetric: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "multi_dimension_base_sum_metric__expected.csv": multi_dimension_base_sum_metric__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "multi_dimension_base_sum_metric.sql": multi_dimension_base_sum_metric_sql, + "multi_dimension_base_sum_metric.yml": multi_dimension_base_sum_metric_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/dimensions/test_multi_dimension_expression_metric.py b/tests/functional/metric_options/dimensions/test_multi_dimension_expression_metric.py new file mode 100644 index 00000000..86566992 --- /dev/null +++ b/tests/functional/metric_options/dimensions/test_multi_dimension_expression_metric.py @@ -0,0 +1,138 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/multi_dimension_expression_metric.sql +multi_dimension_expression_metric_sql = """ +select * +from +{{ metrics.calculate(metric('multi_dimension_expression_metric'), + grain='month', + dimensions=['had_discount','order_country'] + ) +}} +""" + +# models/base_sum_metric.yml +base_sum_metric_yml = """ +version: 2 +metrics: + - name: base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# models/multi_dimension_expression_metric.yml +multi_dimension_expression_metric_yml = """ +version: 2 +models: + - name: multi_dimension_expression_metric + tests: + - dbt_utils.equality: + compare_model: ref('multi_dimension_expression_metric__expected') +metrics: + - name: multi_dimension_expression_metric + label: Expression ($) + timestamp: order_date + time_grains: [day, week, month] + type: expression + sql: "{{metric('base_sum_metric')}} + 1" + dimensions: + - had_discount + - order_country +""" + +# seeds/multi_dimension_expression_metric__expected.csv +multi_dimension_expression_metric__expected_csv = """ +date_month,had_discount,order_country,base_sum_metric,multi_dimension_expression_metric +2022-01-01,TRUE,France,1,2 +2022-01-01,TRUE,Japan,1,2 +2022-01-01,FALSE,France,4,5 +2022-01-01,FALSE,Japan,2,3 +2022-02-01,TRUE,France,4,5 +2022-02-01,FALSE,France,0, +2022-02-01,FALSE,Japan,2,3 +2022-02-01,TRUE,Japan,0, +""".lstrip() + +class TestMultiDimensionExpressionMetric: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "multi_dimension_expression_metric__expected.csv": multi_dimension_expression_metric__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.yml": fact_orders_yml, + "base_sum_metric.yml": base_sum_metric_yml, + "multi_dimension_expression_metric.yml": multi_dimension_expression_metric_yml, + "fact_orders.sql": fact_orders_sql, + "multi_dimension_expression_metric.sql": multi_dimension_expression_metric_sql + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/dimensions/test_single_dimension_base_metric.py b/tests/functional/metric_options/dimensions/test_single_dimension_base_metric.py new file mode 100644 index 00000000..db19a4fb --- /dev/null +++ b/tests/functional/metric_options/dimensions/test_single_dimension_base_metric.py @@ -0,0 +1,118 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/single_dimension_base_sum_metric.sql +single_dimension_base_sum_metric_sql = """ +select * +from +{{ metrics.calculate(metric('single_dimension_base_sum_metric'), + grain='month', + dimensions=['had_discount'] + ) +}} +""" + +# models/single_dimension_base_sum_metric.yml +single_dimension_base_sum_metric_yml = """ +version: 2 +models: + - name: single_dimension_base_sum_metric + tests: + - dbt_utils.equality: + compare_model: ref('single_dimension_base_sum_metric__expected') +metrics: + - name: single_dimension_base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# seeds/single_dimension_base_sum_metric__expected.csv +single_dimension_base_sum_metric__expected_csv = """ +date_month,had_discount,single_dimension_base_sum_metric +2022-01-01,TRUE,2 +2022-01-01,FALSE,6 +2022-02-01,TRUE,4 +2022-02-01,FALSE,2 +""".lstrip() + +class TestSingleDimensionBaseSumMetric: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "single_dimension_base_sum_metric__expected.csv": single_dimension_base_sum_metric__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "single_dimension_base_sum_metric.sql": single_dimension_base_sum_metric_sql, + "single_dimension_base_sum_metric.yml": single_dimension_base_sum_metric_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/dimensions/test_single_dimension_expression_metric.py b/tests/functional/metric_options/dimensions/test_single_dimension_expression_metric.py new file mode 100644 index 00000000..594c9259 --- /dev/null +++ b/tests/functional/metric_options/dimensions/test_single_dimension_expression_metric.py @@ -0,0 +1,134 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/single_dimension_expression_metric.sql +single_dimension_expression_metric_sql = """ +select * +from +{{ metrics.calculate(metric('single_dimension_expression_metric'), + grain='month', + dimensions=['had_discount'] + ) +}} +""" + +# models/base_sum_metric.yml +base_sum_metric_yml = """ +version: 2 +metrics: + - name: base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# models/single_dimension_expression_metric.yml +single_dimension_expression_metric_yml = """ +version: 2 +models: + - name: single_dimension_expression_metric + tests: + - dbt_utils.equality: + compare_model: ref('single_dimension_expression_metric__expected') +metrics: + - name: single_dimension_expression_metric + label: Expression ($) + timestamp: order_date + time_grains: [day, week, month] + type: expression + sql: "{{metric('base_sum_metric')}} + 1" + dimensions: + - had_discount + - order_country +""" + +# seeds/single_dimension_expression_metric__expected.csv +single_dimension_expression_metric__expected_csv = """ +date_month,had_discount,base_sum_metric,single_dimension_expression_metric +2022-01-01,TRUE,2,3 +2022-01-01,FALSE,6,7 +2022-02-01,TRUE,4,5 +2022-02-01,FALSE,2,3 +""".lstrip() + +class TestSingleDimensionExpressionMetric: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "single_dimension_expression_metric__expected.csv": single_dimension_expression_metric__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.yml": fact_orders_yml, + "base_sum_metric.yml": base_sum_metric_yml, + "single_dimension_expression_metric.yml": single_dimension_expression_metric_yml, + "fact_orders.sql": fact_orders_sql, + "single_dimension_expression_metric.sql": single_dimension_expression_metric_sql + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/end_date/test_early_end_date_base_metric.py b/tests/functional/metric_options/end_date/test_early_end_date_base_metric.py new file mode 100644 index 00000000..d41a39cd --- /dev/null +++ b/tests/functional/metric_options/end_date/test_early_end_date_base_metric.py @@ -0,0 +1,115 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/early_end_date_base_sum_metric.sql +early_end_date_base_sum_metric_sql = """ +select * +from +{{ metrics.calculate(metric('early_end_date_base_sum_metric'), + grain='month', + end_date='2022-01-27' + ) +}} +""" + +# models/early_end_date_base_sum_metric.yml +early_end_date_base_sum_metric_yml = """ +version: 2 +models: + - name: early_end_date_base_sum_metric + tests: + - dbt_utils.equality: + compare_model: ref('early_end_date_base_sum_metric__expected') +metrics: + - name: early_end_date_base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# seeds/early_end_date_base_sum_metric__expected.csv +early_end_date_base_sum_metric__expected_csv = """ +date_month,early_end_date_base_sum_metric +2022-01-01,6 +""".lstrip() + +class TestEarlyEndDateBaseSumMetric: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "early_end_date_base_sum_metric__expected.csv": early_end_date_base_sum_metric__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "early_end_date_base_sum_metric.sql": early_end_date_base_sum_metric_sql, + "early_end_date_base_sum_metric.yml": early_end_date_base_sum_metric_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/end_date/test_early_end_date_expression_metric.py b/tests/functional/metric_options/end_date/test_early_end_date_expression_metric.py new file mode 100644 index 00000000..61012c14 --- /dev/null +++ b/tests/functional/metric_options/end_date/test_early_end_date_expression_metric.py @@ -0,0 +1,131 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/end_date_expression_metric.sql +end_date_expression_metric_sql = """ +select * +from +{{ metrics.calculate(metric('end_date_expression_metric'), + grain='month', + end_date='2022-01-27' + ) +}} +""" + +# models/base_sum_metric.yml +base_sum_metric_yml = """ +version: 2 +metrics: + - name: base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# models/end_date_expression_metric.yml +end_date_expression_metric_yml = """ +version: 2 +models: + - name: end_date_expression_metric + tests: + - dbt_utils.equality: + compare_model: ref('end_date_expression_metric__expected') +metrics: + - name: end_date_expression_metric + label: Expression ($) + timestamp: order_date + time_grains: [day, week, month] + type: expression + sql: "{{metric('base_sum_metric')}} + 1" + dimensions: + - had_discount + - order_country +""" + +# seeds/end_date_expression_metric__expected.csv +end_date_expression_metric__expected_csv = """ +date_month,base_sum_metric,end_date_expression_metric +2022-01-01,6,7 +""".lstrip() + +class TestEndDateExpressionMetric: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "end_date_expression_metric__expected.csv": end_date_expression_metric__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.yml": fact_orders_yml, + "base_sum_metric.yml": base_sum_metric_yml, + "end_date_expression_metric.yml": end_date_expression_metric_yml, + "fact_orders.sql": fact_orders_sql, + "end_date_expression_metric.sql": end_date_expression_metric_sql + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/end_date/test_end_date_base_metric.py b/tests/functional/metric_options/end_date/test_end_date_base_metric.py new file mode 100644 index 00000000..de0fe492 --- /dev/null +++ b/tests/functional/metric_options/end_date/test_end_date_base_metric.py @@ -0,0 +1,115 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/end_date_base_sum_metric.sql +end_date_base_sum_metric_sql = """ +select * +from +{{ metrics.calculate(metric('end_date_base_sum_metric'), + grain='month', + end_date='2022-01-31' + ) +}} +""" + +# models/end_date_base_sum_metric.yml +end_date_base_sum_metric_yml = """ +version: 2 +models: + - name: end_date_base_sum_metric + tests: + - dbt_utils.equality: + compare_model: ref('end_date_base_sum_metric__expected') +metrics: + - name: end_date_base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# seeds/end_date_base_sum_metric__expected.csv +end_date_base_sum_metric__expected_csv = """ +date_month,end_date_base_sum_metric +2022-01-01,8 +""".lstrip() + +class TestEndDateBaseSumMetric: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "end_date_base_sum_metric__expected.csv": end_date_base_sum_metric__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "end_date_base_sum_metric.sql": end_date_base_sum_metric_sql, + "end_date_base_sum_metric.yml": end_date_base_sum_metric_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/end_date/test_end_date_expression_metric.py b/tests/functional/metric_options/end_date/test_end_date_expression_metric.py new file mode 100644 index 00000000..e20d525e --- /dev/null +++ b/tests/functional/metric_options/end_date/test_end_date_expression_metric.py @@ -0,0 +1,131 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/end_date_expression_metric.sql +end_date_expression_metric_sql = """ +select * +from +{{ metrics.calculate(metric('end_date_expression_metric'), + grain='month', + end_date='2022-01-31' + ) +}} +""" + +# models/base_sum_metric.yml +base_sum_metric_yml = """ +version: 2 +metrics: + - name: base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# models/end_date_expression_metric.yml +end_date_expression_metric_yml = """ +version: 2 +models: + - name: end_date_expression_metric + tests: + - dbt_utils.equality: + compare_model: ref('end_date_expression_metric__expected') +metrics: + - name: end_date_expression_metric + label: Expression ($) + timestamp: order_date + time_grains: [day, week, month] + type: expression + sql: "{{metric('base_sum_metric')}} + 1" + dimensions: + - had_discount + - order_country +""" + +# seeds/end_date_expression_metric__expected.csv +end_date_expression_metric__expected_csv = """ +date_month,base_sum_metric,end_date_expression_metric +2022-01-01,8,9 +""".lstrip() + +class TestEndDateExpressionMetric: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "end_date_expression_metric__expected.csv": end_date_expression_metric__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.yml": fact_orders_yml, + "base_sum_metric.yml": base_sum_metric_yml, + "end_date_expression_metric.yml": end_date_expression_metric_yml, + "fact_orders.sql": fact_orders_sql, + "end_date_expression_metric.sql": end_date_expression_metric_sql + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/multiple_metrics/test_multiple_metrics_base_types.py b/tests/functional/metric_options/multiple_metrics/test_multiple_metrics_base_types.py new file mode 100644 index 00000000..53ee90bc --- /dev/null +++ b/tests/functional/metric_options/multiple_metrics/test_multiple_metrics_base_types.py @@ -0,0 +1,127 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/multiple_metrics.sql +multiple_metrics_sql = """ +select * +from +{{ metrics.calculate( + [metric('base_sum_metric'), metric('base_count_metric')], + grain='month' + ) +}} +""" + +# models/multiple_metrics.yml +multiple_metrics_yml = """ +version: 2 +models: + - name: multiple_metrics + tests: + - dbt_utils.equality: + compare_model: ref('multiple_metrics__expected') +metrics: + - name: base_count_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: count + sql: order_total + dimensions: + - had_discount + - order_country + + - name: base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# seeds/multiple_metrics__expected.csv +multiple_metrics__expected_csv = """ +date_month,base_sum_metric,base_count_metric +2022-01-01,8,7 +2022-02-01,6,3 +""".lstrip() + +class TestMultipleMetrics: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "multiple_metrics__expected.csv": multiple_metrics__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "multiple_metrics.sql": multiple_metrics_sql, + "multiple_metrics.yml": multiple_metrics_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/multiple_metrics/test_multiple_metrics_base_types_dimensions.py b/tests/functional/metric_options/multiple_metrics/test_multiple_metrics_base_types_dimensions.py new file mode 100644 index 00000000..cabe4197 --- /dev/null +++ b/tests/functional/metric_options/multiple_metrics/test_multiple_metrics_base_types_dimensions.py @@ -0,0 +1,130 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/multiple_metrics.sql +multiple_metrics_sql = """ +select * +from +{{ metrics.calculate( + [metric('base_sum_metric'), metric('base_count_metric')], + grain='month', + dimensions=['had_discount'] + ) +}} +""" + +# models/multiple_metrics.yml +multiple_metrics_yml = """ +version: 2 +models: + - name: multiple_metrics + tests: + - dbt_utils.equality: + compare_model: ref('multiple_metrics__expected') +metrics: + - name: base_count_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: count + sql: order_total + dimensions: + - had_discount + - order_country + + - name: base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# seeds/multiple_metrics__expected.csv +multiple_metrics__expected_csv = """ +date_month,had_discount,base_sum_metric,base_count_metric +2022-01-01,TRUE,2,2 +2022-01-01,FALSE,6,5 +2022-02-01,TRUE,4,1 +2022-02-01,FALSE,2,2 +""".lstrip() + +class TestMultipleMetricsWithDimension: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "multiple_metrics__expected.csv": multiple_metrics__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "multiple_metrics.sql": multiple_metrics_sql, + "multiple_metrics.yml": multiple_metrics_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/multiple_metrics/test_multiple_metrics_expression_types.py b/tests/functional/metric_options/multiple_metrics/test_multiple_metrics_expression_types.py new file mode 100644 index 00000000..af16d6a7 --- /dev/null +++ b/tests/functional/metric_options/multiple_metrics/test_multiple_metrics_expression_types.py @@ -0,0 +1,126 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/multiple_metrics.sql +multiple_metrics_sql = """ +select * +from +{{ metrics.calculate( + [metric('base_sum_metric'), metric('expression_metric')], + grain='month' + ) +}} +""" + +# models/multiple_metrics.yml +multiple_metrics_yml = """ +version: 2 +models: + - name: multiple_metrics + tests: + - dbt_utils.equality: + compare_model: ref('multiple_metrics__expected') +metrics: + - name: expression_metric + label: Expression ($) + timestamp: order_date + time_grains: [day, week, month] + type: expression + sql: "{{metric('base_sum_metric')}} + 1" + dimensions: + - had_discount + - order_country + + - name: base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# seeds/multiple_metrics__expected.csv +multiple_metrics__expected_csv = """ +date_month,base_sum_metric,expression_metric +2022-01-01,8,9 +2022-02-01,6,7 +""".lstrip() + +class TestMultipleMetricsWithExpression: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "multiple_metrics__expected.csv": multiple_metrics__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "multiple_metrics.sql": multiple_metrics_sql, + "multiple_metrics.yml": multiple_metrics_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/multiple_metrics/test_multiple_metrics_expression_types_dimensions.py b/tests/functional/metric_options/multiple_metrics/test_multiple_metrics_expression_types_dimensions.py new file mode 100644 index 00000000..88bb5ec0 --- /dev/null +++ b/tests/functional/metric_options/multiple_metrics/test_multiple_metrics_expression_types_dimensions.py @@ -0,0 +1,129 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/multiple_metrics.sql +multiple_metrics_sql = """ +select * +from +{{ metrics.calculate( + [metric('base_sum_metric'), metric('expression_metric')], + grain='month', + dimensions=['had_discount'] + ) +}} +""" + +# models/multiple_metrics.yml +multiple_metrics_yml = """ +version: 2 +models: + - name: multiple_metrics + tests: + - dbt_utils.equality: + compare_model: ref('multiple_metrics__expected') +metrics: + - name: expression_metric + label: Expression ($) + timestamp: order_date + time_grains: [day, week, month] + type: expression + sql: "{{metric('base_sum_metric')}} + 1" + dimensions: + - had_discount + - order_country + + - name: base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# seeds/multiple_metrics__expected.csv +multiple_metrics__expected_csv = """ +date_month,had_discount,base_sum_metric,expression_metric +2022-01-01,TRUE,2,3 +2022-01-01,FALSE,6,7 +2022-02-01,TRUE,4,5 +2022-02-01,FALSE,2,3 +""".lstrip() + +class TestMultipleMetricsWithExpressionAndDimension: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "multiple_metrics__expected.csv": multiple_metrics__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "multiple_metrics.sql": multiple_metrics_sql, + "multiple_metrics.yml": multiple_metrics_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/secondary_calculations/period_over_period/test_period_over_period_difference.py b/tests/functional/metric_options/secondary_calculations/period_over_period/test_period_over_period_difference.py new file mode 100644 index 00000000..c08086a0 --- /dev/null +++ b/tests/functional/metric_options/secondary_calculations/period_over_period/test_period_over_period_difference.py @@ -0,0 +1,160 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/period_over_period_difference.sql +period_over_period_difference_sql = """ +select * +from +{{ metrics.calculate(metric('period_over_period_difference'), + grain='month', + secondary_calculations=[ + metrics.period_over_period(comparison_strategy="difference", interval=1, alias = "1mth") + ] + ) +}} +""" + +# models/period_over_period_difference.yml +period_over_period_difference_yml = """ +version: 2 +models: + - name: period_over_period_difference + tests: + - dbt_utils.equality: + compare_model: ref('period_over_period_difference__expected') +metrics: + - name: period_over_period_difference + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# seeds/period_over_period_difference__expected.csv +if os.getenv('dbt_target') == 'postgres': + period_over_period_difference__expected_csv = """ +date_month,period_over_period_difference,period_over_period_difference_1mth +2022-01-01,8,8 +2022-02-01,6,-2 +""".lstrip() + +# seeds/period_over_period_difference__expected.csv +if os.getenv('dbt_target') == 'redshift': + period_over_period_difference__expected_csv = """ +date_month,period_over_period_difference,period_over_period_difference_1mth +2022-01-01,8,8 +2022-02-01,6,-2 +""".lstrip() + +# seeds/period_over_period_difference__expected.csv +if os.getenv('dbt_target') == 'snowflake': + period_over_period_difference__expected_csv = """ +date_month,period_over_period_difference,period_over_period_difference_1mth +2022-01-01,8,8 +2022-02-01,6,-2 +""".lstrip() + +# seeds/period_over_period_difference__expected.csv +if os.getenv('dbt_target') == 'bigquery': + period_over_period_difference__expected_csv = """ +date_month,period_over_period_difference,period_over_period_difference_1mth +2022-01-01,8,8 +2022-02-01,6,-2 +""".lstrip() + +# seeds/period_to_period_difference___expected.yml +if os.getenv('dbt_target') == 'bigquery': + period_over_period_difference__expected_yml = """ +version: 2 +seeds: + - name: period_over_period_difference__expected + config: + column_types: + date_month: date + period_over_period_difference: INT64 + period_over_period_difference_1mth: INT64 +""".lstrip() +else: + period_over_period_difference__expected_yml = """""" + + +class TestPeriodOverPeriodDifference: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "period_over_period_difference__expected.csv": period_over_period_difference__expected_csv, + "period_over_period_difference__expected.yml": period_over_period_difference__expected_yml + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "period_over_period_difference.sql": period_over_period_difference_sql, + "period_over_period_difference.yml": period_over_period_difference_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/secondary_calculations/period_over_period/test_period_over_period_ratio.py b/tests/functional/metric_options/secondary_calculations/period_over_period/test_period_over_period_ratio.py new file mode 100644 index 00000000..6d1de913 --- /dev/null +++ b/tests/functional/metric_options/secondary_calculations/period_over_period/test_period_over_period_ratio.py @@ -0,0 +1,134 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/period_over_period_ratio.sql +period_over_period_ratio_sql = """ +select * +from +{{ metrics.calculate(metric('period_over_period_ratio'), + grain='month', + secondary_calculations=[ + metrics.period_over_period(comparison_strategy="ratio", interval=1, alias = "1mth") + ] + ) +}} +""" + +# models/period_over_period_ratio.yml +period_over_period_ratio_yml = """ +version: 2 +models: + - name: period_over_period_ratio + tests: + - dbt_utils.equality: + compare_model: ref('period_over_period_ratio__expected') +metrics: + - name: period_over_period_ratio + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# seeds/period_over_period_ratio__expected.csv +period_over_period_ratio__expected_csv = """ +date_month,period_over_period_ratio,period_over_period_ratio_1mth +2022-01-01,8, +2022-02-01,6,0.75 +""".lstrip() + +# seeds/period_over_period_ratio___expected.yml +if os.getenv('dbt_target') == 'bigquery': + period_over_period_ratio__expected_yml = """ +version: 2 +seeds: + - name: period_over_period_ratio__expected + config: + column_types: + date_month: date + period_over_period_ratio: INT64 + period_over_period_ratio_1mth: FLOAT64 +""".lstrip() +else: + period_over_period_ratio__expected_yml = """""" + +class TestPeriodOverPeriodRatio: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "period_over_period_ratio__expected.csv": period_over_period_ratio__expected_csv, + "period_over_period_ratio__expected.yml": period_over_period_ratio__expected_yml + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "period_over_period_ratio.sql": period_over_period_ratio_sql, + "period_over_period_ratio.yml": period_over_period_ratio_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/secondary_calculations/period_to_date/test_period_to_date_average.py b/tests/functional/metric_options/secondary_calculations/period_to_date/test_period_to_date_average.py new file mode 100644 index 00000000..42f5a971 --- /dev/null +++ b/tests/functional/metric_options/secondary_calculations/period_to_date/test_period_to_date_average.py @@ -0,0 +1,163 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/period_to_date_average.sql +period_to_date_average_sql = """ +select * +from +{{ metrics.calculate(metric('period_to_date_average'), + grain='month', + secondary_calculations=[ + metrics.period_to_date(aggregate="min", period="year", alias="this_year_min"), + metrics.period_to_date(aggregate="max", period="year"), + ] + ) +}} +""" + +# models/period_to_date_average.yml +period_to_date_average_yml = """ +version: 2 +models: + - name: period_to_date_average + tests: + - dbt_utils.equality: + compare_model: ref('period_to_date_average__expected') +metrics: + - name: period_to_date_average + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: average + sql: discount_total + dimensions: + - had_discount + - order_country +""" + +# seeds/period_to_date_average__expected.csv +if os.getenv('dbt_target') == 'postgres': + period_to_date_average__expected_csv = """ +date_month,date_year,period_to_date_average,period_to_date_average_this_year_min,period_to_date_average_max_for_year +2022-01-01,2022-01-01,1.00000000000000000000,1,1 +2022-02-01,2022-01-01,1.3333333333333333,1,1.3333333333333333 +""".lstrip() + +# seeds/period_to_date_average__expected.csv +if os.getenv('dbt_target') == 'redshift': + period_to_date_average__expected_csv = """ +date_month,date_year,period_to_date_average,period_to_date_average_this_year_min,period_to_date_average_max_for_year +2022-01-01,2022-01-01,1.00000000000000000000,1,1 +2022-02-01,2022-01-01,1.3333333333333333,1,1.3333333333333333 +""".lstrip() + +# seeds/period_to_date_average__expected.csv +if os.getenv('dbt_target') == 'snowflake': + period_to_date_average__expected_csv = """ +date_month,date_year,period_to_date_average,period_to_date_average_this_year_min,period_to_date_average_max_for_year +2022-01-01,2022-01-01,1.000000,1,1 +2022-02-01,2022-01-01,1.333333,1,1.333333 +""".lstrip() + +# seeds/period_to_date_average__expected.csv +if os.getenv('dbt_target') == 'bigquery': + period_to_date_average__expected_csv = """ +date_month,date_year,period_to_date_average,period_to_date_average_this_year_min,period_to_date_average_max_for_year +2022-01-01,2022-01-01,1.00000000000000000000,1,1 +2022-02-01,2022-01-01,1.3333333333333333,1,1.3333333333333333 +""".lstrip() + +# seeds/period_to_date_average__expected.yml +if os.getenv('dbt_target') == 'bigquery': + period_to_date_average__expected_yml = """ +version: 2 +seeds: + - name: period_to_date_average__expected + config: + column_types: + date_month: date + date_year: date + period_to_date_average: FLOAT64 + period_to_date_average_this_year_min: INT64 + period_to_date_average_max_for_year: FLOAT64 +""".lstrip() +else: + period_to_date_average__expected_yml = """""" + + +class TestPeriodToDateAverage: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "period_to_date_average__expected.csv": period_to_date_average__expected_csv, + "period_to_date_average__expected.yml": period_to_date_average__expected_yml + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "period_to_date_average.sql": period_to_date_average_sql, + "period_to_date_average.yml": period_to_date_average_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/secondary_calculations/period_to_date/test_period_to_date_count.py b/tests/functional/metric_options/secondary_calculations/period_to_date/test_period_to_date_count.py new file mode 100644 index 00000000..920e7091 --- /dev/null +++ b/tests/functional/metric_options/secondary_calculations/period_to_date/test_period_to_date_count.py @@ -0,0 +1,165 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/period_to_date_count.sql +period_to_date_count_sql = """ +select * +from +{{ metrics.calculate(metric('period_to_date_count'), + grain='month', + secondary_calculations=[ + metrics.period_to_date(aggregate="min", period="year", alias="this_year_min"), + metrics.period_to_date(aggregate="max", period="year"), + metrics.period_to_date(aggregate="sum", period="year"), + metrics.period_to_date(aggregate="average", period="year"), + ] + ) +}} +""" + +# models/period_to_date_count.yml +period_to_date_count_yml = """ +version: 2 +models: + - name: period_to_date_count + tests: + - dbt_utils.equality: + compare_model: ref('period_to_date_count__expected') +metrics: + - name: period_to_date_count + model: ref('fact_orders') + label: Count Distinct + timestamp: order_date + time_grains: [day, week, month] + type: count + sql: customer_id + dimensions: + - had_discount + - order_country +""" + +# seeds/period_to_date_count__expected.csv +if os.getenv('dbt_target') == 'postgres': + period_to_date_count__expected_csv = """ +date_month,date_year,period_to_date_count,period_to_date_count_this_year_min,period_to_date_count_max_for_year,period_to_date_count_sum_for_year,period_to_date_count_average_for_year +2022-01-01,2022-01-01,7,7,7,7,7.0000000000000000 +2022-02-01,2022-01-01,3,3,7,10,5.0000000000000000 +""".lstrip() + +# seeds/period_to_date_count__expected.csv +if os.getenv('dbt_target') == 'redshift': + period_to_date_count__expected_csv = """ +date_month,date_year,period_to_date_count,period_to_date_count_this_year_min,period_to_date_count_max_for_year,period_to_date_count_sum_for_year,period_to_date_count_average_for_year +2022-01-01,2022-01-01,7,7,7,7,7.0000000000000000 +2022-02-01,2022-01-01,3,3,7,10,5.0000000000000000 +""".lstrip() + +# seeds/period_to_date_count__expected.csv +if os.getenv('dbt_target') == 'snowflake': + period_to_date_count__expected_csv = """ +date_month,date_year,period_to_date_count,period_to_date_count_this_year_min,period_to_date_count_max_for_year,period_to_date_count_sum_for_year,period_to_date_count_average_for_year +2022-01-01,2022-01-01,7,7,7,7,7.000000 +2022-02-01,2022-01-01,3,3,7,10,5.000000 +""".lstrip() + +# seeds/period_to_date_count__expected.csv +if os.getenv('dbt_target') == 'bigquery': + period_to_date_count__expected_csv = """ +date_month,date_year,period_to_date_count,period_to_date_count_this_year_min,period_to_date_count_max_for_year,period_to_date_count_sum_for_year,period_to_date_count_average_for_year +2022-01-01,2022-01-01,7,7,7,7,7.0000000000000000 +2022-02-01,2022-01-01,3,3,7,10,5.0000000000000000 +""".lstrip() + +# seeds/period_to_date_count__expected.yml +if os.getenv('dbt_target') == 'bigquery': + period_to_date_count__expected_yml = """ +version: 2 +seeds: + - name: period_to_date_count__expected + config: + column_types: + date_month: date + date_year: date + period_to_date_count: INT64 + period_to_date_count_this_year_min: INT64 + period_to_date_count_max_for_year: INT64 + period_to_date_count_sum_for_year: INT64 + period_to_date_count_average_for_year: FLOAT64 +""".lstrip() +else: + period_to_date_count__expected_yml = """""" + +class TestPeriodToDateCount: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "period_to_date_count__expected.csv": period_to_date_count__expected_csv, + "period_to_date_count__expected.yml": period_to_date_count__expected_yml + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "period_to_date_count.sql": period_to_date_count_sql, + "period_to_date_count.yml": period_to_date_count_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/secondary_calculations/period_to_date/test_period_to_date_count_distinct.py b/tests/functional/metric_options/secondary_calculations/period_to_date/test_period_to_date_count_distinct.py new file mode 100644 index 00000000..6a7e9ac6 --- /dev/null +++ b/tests/functional/metric_options/secondary_calculations/period_to_date/test_period_to_date_count_distinct.py @@ -0,0 +1,165 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/period_to_date_count_distinct.sql +period_to_date_count_distinct_sql = """ +select * +from +{{ metrics.calculate(metric('period_to_date_count_distinct'), + grain='month', + secondary_calculations=[ + metrics.period_to_date(aggregate="min", period="year", alias="this_year_min"), + metrics.period_to_date(aggregate="max", period="year"), + metrics.period_to_date(aggregate="sum", period="year"), + metrics.period_to_date(aggregate="average", period="year"), + ] + ) +}} +""" + +# models/period_to_date_count_distinct.yml +period_to_date_count_distinct_yml = """ +version: 2 +models: + - name: period_to_date_count_distinct + tests: + - dbt_utils.equality: + compare_model: ref('period_to_date_count_distinct__expected') +metrics: + - name: period_to_date_count_distinct + model: ref('fact_orders') + label: Count Distinct + timestamp: order_date + time_grains: [day, week, month] + type: count_distinct + sql: customer_id + dimensions: + - had_discount + - order_country +""" + +# seeds/period_to_date_count_distinct__expected.csv +if os.getenv('dbt_target') == 'postgres': + period_to_date_count_distinct__expected_csv = """ +date_month,date_year,period_to_date_count_distinct,period_to_date_count_distinct_this_year_min,period_to_date_count_distinct_max_for_year,period_to_date_count_distinct_sum_for_year,period_to_date_count_distinct_average_for_year +2022-01-01,2022-01-01,5,5,5,5,5.0000000000000000 +2022-02-01,2022-01-01,3,3,5,8,4.0000000000000000 +""".lstrip() + +# seeds/period_to_date_count_distinct__expected.csv +if os.getenv('dbt_target') == 'redshift': + period_to_date_count_distinct__expected_csv = """ +date_month,date_year,period_to_date_count_distinct,period_to_date_count_distinct_this_year_min,period_to_date_count_distinct_max_for_year,period_to_date_count_distinct_sum_for_year,period_to_date_count_distinct_average_for_year +2022-01-01,2022-01-01,5,5,5,5,5.0000000000000000 +2022-02-01,2022-01-01,3,3,5,8,4.0000000000000000 +""".lstrip() + +# seeds/period_to_date_count_distinct__expected.csv +if os.getenv('dbt_target') == 'snowflake': + period_to_date_count_distinct__expected_csv = """ +date_month,date_year,period_to_date_count_distinct,period_to_date_count_distinct_this_year_min,period_to_date_count_distinct_max_for_year,period_to_date_count_distinct_sum_for_year,period_to_date_count_distinct_average_for_year +2022-01-01,2022-01-01,5,5,5,5,5.000000 +2022-02-01,2022-01-01,3,3,5,8,4.000000 +""".lstrip() + +# seeds/period_to_date_count_distinct__expected.csv +if os.getenv('dbt_target') == 'bigquery': + period_to_date_count_distinct__expected_csv = """ +date_month,date_year,period_to_date_count_distinct,period_to_date_count_distinct_this_year_min,period_to_date_count_distinct_max_for_year,period_to_date_count_distinct_sum_for_year,period_to_date_count_distinct_average_for_year +2022-01-01,2022-01-01,5,5,5,5,5.0000000000000000 +2022-02-01,2022-01-01,3,3,5,8,4.0000000000000000 +""".lstrip() + +# seeds/period_to_date_count_distinct__expected.yml +if os.getenv('dbt_target') == 'bigquery': + period_to_date_count_distinct__expected_yml = """ +version: 2 +seeds: + - name: period_to_date_count_distinct__expected + config: + column_types: + date_month: date + date_year: date + period_to_date_count_distinct: INT64 + period_to_date_count_distinct_this_year_min: INT64 + period_to_date_count_distinct_max_for_year: INT64 + period_to_date_count_distinct_sum_for_year: INT64 + period_to_date_count_distinct_average_for_year: FLOAT64 +""".lstrip() +else: + period_to_date_count_distinct__expected_yml = """""" + +class TestPeriodToDateCountDistinct: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "period_to_date_count_distinct__expected.csv": period_to_date_count_distinct__expected_csv, + "period_to_date_count_distinct__expected.yml": period_to_date_count_distinct__expected_yml + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "period_to_date_count_distinct.sql": period_to_date_count_distinct_sql, + "period_to_date_count_distinct.yml": period_to_date_count_distinct_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/secondary_calculations/period_to_date/test_period_to_date_expression.py b/tests/functional/metric_options/secondary_calculations/period_to_date/test_period_to_date_expression.py new file mode 100644 index 00000000..3997f486 --- /dev/null +++ b/tests/functional/metric_options/secondary_calculations/period_to_date/test_period_to_date_expression.py @@ -0,0 +1,154 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/period_to_date_expression_metric.sql +period_to_date_expression_metric_sql = """ +select * +from +{{ metrics.calculate(metric('period_to_date_expression_metric'), + grain='month', + secondary_calculations=[ + metrics.period_to_date(aggregate="min", period="year", alias="this_year_min"), + metrics.period_to_date(aggregate="max", period="year"), + metrics.period_to_date(aggregate="sum", period="year") + ] + ) +}} +""" + +# models/base_sum_metric.yml +base_sum_metric_yml = """ +version: 2 +metrics: + - name: base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# models/period_to_date_expression_metric.yml +period_to_date_expression_metric_yml = """ +version: 2 +models: + - name: period_to_date_expression_metric + tests: + - dbt_utils.equality: + compare_model: ref('period_to_date_expression_metric__expected') +metrics: + - name: period_to_date_expression_metric + label: Expression ($) + timestamp: order_date + time_grains: [day, week, month] + type: expression + sql: "{{metric('base_sum_metric')}} + 1" + dimensions: + - had_discount + - order_country +""" + +# seeds/period_to_date_expression_metric__expected.csv +period_to_date_expression_metric__expected_csv = """ +date_month,date_year,base_sum_metric,period_to_date_expression_metric,period_to_date_expression_metric_this_year_min,period_to_date_expression_metric_max_for_year,period_to_date_expression_metric_sum_for_year +2022-01-01,2022-01-01,8,9,9,9,9 +2022-02-01,2022-01-01,6,7,7,9,16 +""".lstrip() + +# seeds/period_to_date_expression_metric__expected.yml +if os.getenv('dbt_target') == 'bigquery': + period_to_date_expression_metric__expected_yml = """ +version: 2 +seeds: + - name: period_to_date_expression_metric__expected + config: + column_types: + date_month: date + date_year: date + period_to_date_expression_metric: INT64 + period_to_date_expression_metric_this_year_min: INT64 + period_to_date_expression_metric_max_for_year: INT64 + period_to_date_expression_metric_sum_for_year: INT64 +""".lstrip() +else: + period_to_date_expression_metric__expected_yml = """""" + +class TestPeriodToDateExpressionMetric: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "period_to_date_expression_metric__expected.csv": period_to_date_expression_metric__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.yml": fact_orders_yml, + "base_sum_metric.yml": base_sum_metric_yml, + "period_to_date_expression_metric.yml": period_to_date_expression_metric_yml, + "fact_orders.sql": fact_orders_sql, + "period_to_date_expression_metric.sql": period_to_date_expression_metric_sql + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/secondary_calculations/period_to_date/test_period_to_date_max.py b/tests/functional/metric_options/secondary_calculations/period_to_date/test_period_to_date_max.py new file mode 100644 index 00000000..22253746 --- /dev/null +++ b/tests/functional/metric_options/secondary_calculations/period_to_date/test_period_to_date_max.py @@ -0,0 +1,165 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/period_to_date_max.sql +period_to_date_max_sql = """ +select * +from +{{ metrics.calculate(metric('period_to_date_max'), + grain='month', + secondary_calculations=[ + metrics.period_to_date(aggregate="min", period="year", alias="this_year_min"), + metrics.period_to_date(aggregate="max", period="year"), + metrics.period_to_date(aggregate="sum", period="year"), + metrics.period_to_date(aggregate="average", period="year"), + ] + ) +}} +""" + +# models/period_to_date_max.yml +period_to_date_max_yml = """ +version: 2 +models: + - name: period_to_date_max + tests: + - dbt_utils.equality: + compare_model: ref('period_to_date_max__expected') +metrics: + - name: period_to_date_max + model: ref('fact_orders') + label: max value + timestamp: order_date + time_grains: [day, week, month] + type: max + sql: customer_id + dimensions: + - had_discount + - order_country +""" + +# seeds/period_to_date_max__expected.csv +if os.getenv('dbt_target') == 'postgres': + period_to_date_max__expected_csv = """ +date_month,date_year,period_to_date_max,period_to_date_max_this_year_min,period_to_date_max_max_for_year,period_to_date_max_sum_for_year,period_to_date_max_average_for_year +2022-01-01,2022-01-01,5,5,5,5,5.0000000000000000 +2022-02-01,2022-01-01,3,3,5,8,4.0000000000000000 +""".lstrip() + +# seeds/period_to_date_max__expected.csv +if os.getenv('dbt_target') == 'redshift': + period_to_date_max__expected_csv = """ +date_month,date_year,period_to_date_max,period_to_date_max_this_year_min,period_to_date_max_max_for_year,period_to_date_max_sum_for_year,period_to_date_max_average_for_year +2022-01-01,2022-01-01,5,5,5,5,5.0000000000000000 +2022-02-01,2022-01-01,3,3,5,8,4.0000000000000000 +""".lstrip() + +# seeds/period_to_date_max__expected.csv +if os.getenv('dbt_target') == 'snowflake': + period_to_date_max__expected_csv = """ +date_month,date_year,period_to_date_max,period_to_date_max_this_year_min,period_to_date_max_max_for_year,period_to_date_max_sum_for_year,period_to_date_max_average_for_year +2022-01-01,2022-01-01,5,5,5,5,5.000000 +2022-02-01,2022-01-01,3,3,5,8,4.000000 +""".lstrip() + +# seeds/period_to_date_max__expected.csv +if os.getenv('dbt_target') == 'bigquery': + period_to_date_max__expected_csv = """ +date_month,date_year,period_to_date_max,period_to_date_max_this_year_min,period_to_date_max_max_for_year,period_to_date_max_sum_for_year,period_to_date_max_average_for_year +2022-01-01,2022-01-01,5,5,5,5,5.0000000000000000 +2022-02-01,2022-01-01,3,3,5,8,4.0000000000000000 +""".lstrip() + +# seeds/period_to_date_max__expected.yml +if os.getenv('dbt_target') == 'bigquery': + period_to_date_max__expected_yml = """ +version: 2 +seeds: + - name: period_to_date_max__expected + config: + column_types: + date_month: date + date_year: date + period_to_date_max: INT64 + period_to_date_max_this_year_min: INT64 + period_to_date_max_max_for_year: INT64 + period_to_date_max_sum_for_year: INT64 + period_to_date_max_average_for_year: FLOAT64 +""".lstrip() +else: + period_to_date_max__expected_yml = """""" + +class TestPeriodToDateMax: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "period_to_date_max__expected.csv": period_to_date_max__expected_csv, + "period_to_date_max__expected.yml": period_to_date_max__expected_yml + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "period_to_date_max.sql": period_to_date_max_sql, + "period_to_date_max.yml": period_to_date_max_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/secondary_calculations/period_to_date/test_period_to_date_min.py b/tests/functional/metric_options/secondary_calculations/period_to_date/test_period_to_date_min.py new file mode 100644 index 00000000..c85ecd67 --- /dev/null +++ b/tests/functional/metric_options/secondary_calculations/period_to_date/test_period_to_date_min.py @@ -0,0 +1,165 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/period_to_date_min.sql +period_to_date_min_sql = """ +select * +from +{{ metrics.calculate(metric('period_to_date_min'), + grain='month', + secondary_calculations=[ + metrics.period_to_date(aggregate="min", period="year", alias="this_year_min"), + metrics.period_to_date(aggregate="max", period="year"), + metrics.period_to_date(aggregate="sum", period="year"), + metrics.period_to_date(aggregate="average", period="year"), + ] + ) +}} +""" + +# models/period_to_date_min.yml +period_to_date_min_yml = """ +version: 2 +models: + - name: period_to_date_min + tests: + - dbt_utils.equality: + compare_model: ref('period_to_date_min__expected') +metrics: + - name: period_to_date_min + model: ref('fact_orders') + label: min value + timestamp: order_date + time_grains: [day, week, month] + type: min + sql: customer_id + dimensions: + - had_discount + - order_country +""" + +# seeds/period_to_date_min__expected.csv +if os.getenv('dbt_target') == 'postgres': + period_to_date_min__expected_csv = """ +date_month,date_year,period_to_date_min,period_to_date_min_this_year_min,period_to_date_min_max_for_year,period_to_date_min_sum_for_year,period_to_date_min_average_for_year +2022-01-01,2022-01-01,1,1,1,1,1.0000000000000000 +2022-02-01,2022-01-01,1,1,1,2,1.0000000000000000 +""".lstrip() + +# seeds/period_to_date_min__expected.csv +if os.getenv('dbt_target') == 'redshift': + period_to_date_min__expected_csv = """ +date_month,date_year,period_to_date_min,period_to_date_min_this_year_min,period_to_date_min_max_for_year,period_to_date_min_sum_for_year,period_to_date_min_average_for_year +2022-01-01,2022-01-01,1,1,1,1,1.0000000000000000 +2022-02-01,2022-01-01,1,1,1,2,1.0000000000000000 +""".lstrip() + +# seeds/period_to_date_min__expected.csv +if os.getenv('dbt_target') == 'snowflake': + period_to_date_min__expected_csv = """ +date_month,date_year,period_to_date_min,period_to_date_min_this_year_min,period_to_date_min_max_for_year,period_to_date_min_sum_for_year,period_to_date_min_average_for_year +2022-01-01,2022-01-01,1,1,1,1,1.000000 +2022-02-01,2022-01-01,1,1,1,2,1.000000 +""".lstrip() + +# seeds/period_to_date_min__expected.csv +if os.getenv('dbt_target') == 'bigquery': + period_to_date_min__expected_csv = """ +date_month,date_year,period_to_date_min,period_to_date_min_this_year_min,period_to_date_min_max_for_year,period_to_date_min_sum_for_year,period_to_date_min_average_for_year +2022-01-01,2022-01-01,1,1,1,1,1.0000000000000000 +2022-02-01,2022-01-01,1,1,1,2,1.0000000000000000 +""".lstrip() + +# seeds/period_to_date_min__expected.yml +if os.getenv('dbt_target') == 'bigquery': + period_to_date_min__expected_yml = """ +version: 2 +seeds: + - name: period_to_date_min__expected + config: + column_types: + date_month: date + date_year: date + period_to_date_min: INT64 + period_to_date_min_this_year_min: INT64 + period_to_date_min_max_for_year: INT64 + period_to_date_min_sum_for_year: INT64 + period_to_date_min_average_for_year: FLOAT64 +""".lstrip() +else: + period_to_date_min__expected_yml = """""" + +class TestPeriodToDateMin: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "period_to_date_min__expected.csv": period_to_date_min__expected_csv, + "period_to_date_min__expected.yml": period_to_date_min__expected_yml + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "period_to_date_min.sql": period_to_date_min_sql, + "period_to_date_min.yml": period_to_date_min_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/secondary_calculations/period_to_date/test_period_to_date_sum.py b/tests/functional/metric_options/secondary_calculations/period_to_date/test_period_to_date_sum.py new file mode 100644 index 00000000..be2644f3 --- /dev/null +++ b/tests/functional/metric_options/secondary_calculations/period_to_date/test_period_to_date_sum.py @@ -0,0 +1,166 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/period_to_date_sum.sql +period_to_date_sum_sql = """ +select * +from +{{ metrics.calculate(metric('period_to_date_sum'), + grain='month', + secondary_calculations=[ + metrics.period_to_date(aggregate="sum", period="year", alias="this_year_sum"), + metrics.period_to_date(aggregate="max", period="year"), + metrics.period_to_date(aggregate="sum", period="year"), + metrics.period_to_date(aggregate="average", period="year"), + ] + ) +}} +""" + +# models/period_to_date_sum.yml +period_to_date_sum_yml = """ +version: 2 +models: + - name: period_to_date_sum + tests: + - dbt_utils.equality: + compare_model: ref('period_to_date_sum__expected') +metrics: + - name: period_to_date_sum + model: ref('fact_orders') + label: sum value + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: customer_id + dimensions: + - had_discount + - order_country +""" + +# seeds/period_to_date_sum__expected.csv +if os.getenv('dbt_target') == 'postgres': + period_to_date_sum__expected_csv = """ +date_month,date_year,period_to_date_sum,period_to_date_sum_this_year_sum,period_to_date_sum_max_for_year,period_to_date_sum_sum_for_year,period_to_date_sum_average_for_year +2022-01-01,2022-01-01,18,18,18,18,18.0000000000000000 +2022-02-01,2022-01-01,6,24,18,24,12.0000000000000000 +""".lstrip() + +# seeds/period_to_date_sum__expected.csv +if os.getenv('dbt_target') == 'redshift': + period_to_date_sum__expected_csv = """ +date_month,date_year,period_to_date_sum,period_to_date_sum_this_year_sum,period_to_date_sum_max_for_year,period_to_date_sum_sum_for_year,period_to_date_sum_average_for_year +2022-01-01,2022-01-01,18,18,18,18,18.0000000000000000 +2022-02-01,2022-01-01,6,24,18,24,12.0000000000000000 +""".lstrip() + +# seeds/period_to_date_sum__expected.csv +if os.getenv('dbt_target') == 'snowflake': + period_to_date_sum__expected_csv = """ +date_month,date_year,period_to_date_sum,period_to_date_sum_this_year_sum,period_to_date_sum_max_for_year,period_to_date_sum_sum_for_year,period_to_date_sum_average_for_year +2022-01-01,2022-01-01,18,18,18,18,18.000000 +2022-02-01,2022-01-01,6,24,18,24,12.000000 +""".lstrip() + +# seeds/period_to_date_sum__expected.csv +if os.getenv('dbt_target') == 'bigquery': + period_to_date_sum__expected_csv = """ +date_month,date_year,period_to_date_sum,period_to_date_sum_this_year_sum,period_to_date_sum_max_for_year,period_to_date_sum_sum_for_year,period_to_date_sum_average_for_year +2022-01-01,2022-01-01,18,18,18,18,18.0000000000000000 +2022-02-01,2022-01-01,6,24,18,24,12.0000000000000000 +""".lstrip() + +# seeds/period_to_date_sum__expected.yml +if os.getenv('dbt_target') == 'bigquery': + period_to_date_sum__expected_yml = """ +version: 2 +seeds: + - name: period_to_date_sum__expected + config: + column_types: + date_month: date + date_year: date + period_to_date_sum: INT64 + period_to_date_sum_this_year_min: INT64 + period_to_date_sum_max_for_year: INT64 + period_to_date_sum_sum_for_year: INT64 + period_to_date_sum_average_for_year: FLOAT64 +""".lstrip() +else: + period_to_date_sum__expected_yml = """""" + + +class TestPeriodToDateSum: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "period_to_date_sum__expected.csv": period_to_date_sum__expected_csv, + "period_to_date_sum__expected.yml": period_to_date_sum__expected_yml + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "period_to_date_sum.sql": period_to_date_sum_sql, + "period_to_date_sum.yml": period_to_date_sum_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/secondary_calculations/rolling/test_rolling_average.py b/tests/functional/metric_options/secondary_calculations/rolling/test_rolling_average.py new file mode 100644 index 00000000..4fa5273b --- /dev/null +++ b/tests/functional/metric_options/secondary_calculations/rolling/test_rolling_average.py @@ -0,0 +1,161 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/rolling_average.sql +rolling_average_sql = """ +select * +from +{{ metrics.calculate(metric('rolling_average'), + grain='month', + secondary_calculations=[ + metrics.rolling(aggregate="max", interval=2), + metrics.rolling(aggregate="min", interval=2) + ] + ) +}} +""" + +# models/rolling_average.yml +rolling_average_yml = """ +version: 2 +models: + - name: rolling_average + tests: + - dbt_utils.equality: + compare_model: ref('rolling_average__expected') +metrics: + - name: rolling_average + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: average + sql: discount_total + dimensions: + - had_discount + - order_country +""" + +# seeds/rolling_average__expected.csv +if os.getenv('dbt_target') == 'postgres': + rolling_average__expected_csv = """ +date_month,rolling_average,rolling_average_rolling_max_2_month,rolling_average_rolling_min_2_month +2022-01-01,1,1,1 +2022-02-01,1.3333333333333333,1.3333333333333333,1 +""".lstrip() + +# seeds/rolling_average__expected.csv +if os.getenv('dbt_target') == 'redshift': + rolling_average__expected_csv = """ +date_month,rolling_average,rolling_average_rolling_max_2_month,rolling_average_rolling_min_2_month +2022-01-01,1,1,1 +2022-02-01,1.3333333333333333,1.3333333333333333,1 +""".lstrip() + +# seeds/rolling_average__expected.csv +if os.getenv('dbt_target') == 'snowflake': + rolling_average__expected_csv = """ +date_month,rolling_average,rolling_average_rolling_max_2_month,rolling_average_rolling_min_2_month +2022-01-01,1,1,1 +2022-02-01,1.333333,1.333333,1 +""".lstrip() + +# seeds/rolling_average__expected.csv +if os.getenv('dbt_target') == 'bigquery': + rolling_average__expected_csv = """ +date_month,rolling_average,rolling_average_rolling_max_2_month,rolling_average_rolling_min_2_month +2022-01-01,1,1,1 +2022-02-01,1.3333333333333333,1.3333333333333333,1 +""".lstrip() + +# seeds/rolling_average__expected.yml +if os.getenv('dbt_target') == 'bigquery': + rolling_average__expected_yml = """ +version: 2 +seeds: + - name: rolling_average__expected + config: + column_types: + date_month: date + rolling_average: FLOAT64 + rolling_average_rolling_max_2_month: FLOAT64 + rolling_average_rolling_min_2_month: INT64 +""".lstrip() +else: + rolling_average__expected_yml = """""" + +class TestRollingAverage: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "rolling_average__expected.csv": rolling_average__expected_csv, + "rolling_average__expected.yml": rolling_average__expected_yml + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "rolling_average.sql": rolling_average_sql, + "rolling_average.yml": rolling_average_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/secondary_calculations/rolling/test_rolling_count.py b/tests/functional/metric_options/secondary_calculations/rolling/test_rolling_count.py new file mode 100644 index 00000000..1da014db --- /dev/null +++ b/tests/functional/metric_options/secondary_calculations/rolling/test_rolling_count.py @@ -0,0 +1,164 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/rolling_count.sql +rolling_count_sql = """ +select * +from +{{ metrics.calculate(metric('rolling_count'), + grain='month', + secondary_calculations=[ + metrics.rolling(aggregate="min", interval=2), + metrics.rolling(aggregate="max", interval=2), + metrics.rolling(aggregate="sum", interval=2), + metrics.rolling(aggregate="average", interval=2) + ] + ) +}} +""" + +# models/rolling_count.yml +rolling_count_yml = """ +version: 2 +models: + - name: rolling_count + tests: + - dbt_utils.equality: + compare_model: ref('rolling_count__expected') +metrics: + - name: rolling_count + model: ref('fact_orders') + label: Count Distinct + timestamp: order_date + time_grains: [day, week, month] + type: count + sql: customer_id + dimensions: + - had_discount + - order_country +""" + +# seeds/rolling_count__expected.csv +if os.getenv('dbt_target') == 'postgres': + rolling_count__expected_csv = """ +date_month,rolling_count,rolling_count_rolling_min_2_month,rolling_count_rolling_max_2_month,rolling_count_rolling_sum_2_month,rolling_count_rolling_average_2_month +2022-01-01,7,7,7,7,7.0000000000000000 +2022-02-01,3,3,7,10,5.0000000000000000 +""".lstrip() + +# seeds/rolling_count__expected.csv +if os.getenv('dbt_target') == 'redshift': + rolling_count__expected_csv = """ +date_month,rolling_count,rolling_count_rolling_min_2_month,rolling_count_rolling_max_2_month,rolling_count_rolling_sum_2_month,rolling_count_rolling_average_2_month +2022-01-01,7,7,7,7,7.0000000000000000 +2022-02-01,3,3,7,10,5.0000000000000000 +""".lstrip() + +# seeds/rolling_count__expected.csv +if os.getenv('dbt_target') == 'snowflake': + rolling_count__expected_csv = """ +date_month,rolling_count,rolling_count_rolling_min_2_month,rolling_count_rolling_max_2_month,rolling_count_rolling_sum_2_month,rolling_count_rolling_average_2_month +2022-01-01,7,7,7,7,7.000000 +2022-02-01,3,3,7,10,5.000000 +""".lstrip() + +# seeds/rolling_count__expected.csv +if os.getenv('dbt_target') == 'bigquery': + rolling_count__expected_csv = """ +date_month,rolling_count,rolling_count_rolling_min_2_month,rolling_count_rolling_max_2_month,rolling_count_rolling_sum_2_month,rolling_count_rolling_average_2_month +2022-01-01,7,7,7,7,7.0000000000000000 +2022-02-01,3,3,7,10,5.0000000000000000 +""".lstrip() + +# seeds/rolling_count__expected.yml +if os.getenv('dbt_target') == 'bigquery': + rolling_count__expected_yml = """ +version: 2 +seeds: + - name: rolling_count__expected + config: + column_types: + date_month: date + rolling_count: INT64 + rolling_count_rolling_min_2_month: INT64 + rolling_count_rolling_max_2_month: INT64 + rolling_count_rolling_sum_2_month: INT64 + rolling_count_rolling_average_2_month: FLOAT64 +""".lstrip() +else: + rolling_count__expected_yml = """""" + +class TestRollingCount: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "rolling_count__expected.csv": rolling_count__expected_csv, + "rolling_count__expected.yml": rolling_count__expected_yml + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "rolling_count.sql": rolling_count_sql, + "rolling_count.yml": rolling_count_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/secondary_calculations/rolling/test_rolling_count_distinct.py b/tests/functional/metric_options/secondary_calculations/rolling/test_rolling_count_distinct.py new file mode 100644 index 00000000..6dcad62d --- /dev/null +++ b/tests/functional/metric_options/secondary_calculations/rolling/test_rolling_count_distinct.py @@ -0,0 +1,164 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/rolling_count_distinct.sql +rolling_count_distinct_sql = """ +select * +from +{{ metrics.calculate(metric('rolling_count_distinct'), + grain='month', + secondary_calculations=[ + metrics.rolling(aggregate="min", interval=2), + metrics.rolling(aggregate="max", interval=2), + metrics.rolling(aggregate="sum", interval=2), + metrics.rolling(aggregate="average", interval=2) + ] + ) +}} +""" + +# models/rolling_count_distinct.yml +rolling_count_distinct_yml = """ +version: 2 +models: + - name: rolling_count_distinct + tests: + - dbt_utils.equality: + compare_model: ref('rolling_count_distinct__expected') +metrics: + - name: rolling_count_distinct + model: ref('fact_orders') + label: Count Distinct + timestamp: order_date + time_grains: [day, week, month] + type: count_distinct + sql: customer_id + dimensions: + - had_discount + - order_country +""" + +# seeds/rolling_count_distinct__expected.csv +if os.getenv('dbt_target') == 'postgres': + rolling_count_distinct__expected_csv = """ +date_month,rolling_count_distinct,rolling_count_distinct_rolling_min_2_month,rolling_count_distinct_rolling_max_2_month,rolling_count_distinct_rolling_sum_2_month,rolling_count_distinct_rolling_average_2_month +2022-01-01,5,5,5,5,5.0000000000000000 +2022-02-01,3,3,5,8,4.0000000000000000 +""".lstrip() + +# seeds/rolling_count_distinct__expected.csv +if os.getenv('dbt_target') == 'redshift': + rolling_count_distinct__expected_csv = """ +date_month,rolling_count_distinct,rolling_count_distinct_rolling_min_2_month,rolling_count_distinct_rolling_max_2_month,rolling_count_distinct_rolling_sum_2_month,rolling_count_distinct_rolling_average_2_month +2022-01-01,5,5,5,5,5.0000000000000000 +2022-02-01,3,3,5,8,4.0000000000000000 +""".lstrip() + +# seeds/rolling_count_distinct__expected.csv +if os.getenv('dbt_target') == 'snowflake': + rolling_count_distinct__expected_csv = """ +date_month,rolling_count_distinct,rolling_count_distinct_rolling_min_2_month,rolling_count_distinct_rolling_max_2_month,rolling_count_distinct_rolling_sum_2_month,rolling_count_distinct_rolling_average_2_month +2022-01-01,5,5,5,5,5.000000 +2022-02-01,3,3,5,8,4.000000 +""".lstrip() + +# seeds/rolling_count_distinct__expected.csv +if os.getenv('dbt_target') == 'bigquery': + rolling_count_distinct__expected_csv = """ +date_month,rolling_count_distinct,rolling_count_distinct_rolling_min_2_month,rolling_count_distinct_rolling_max_2_month,rolling_count_distinct_rolling_sum_2_month,rolling_count_distinct_rolling_average_2_month +2022-01-01,5,5,5,5,5.0000000000000000 +2022-02-01,3,3,5,8,4.0000000000000000 +""".lstrip() + +# seeds/rolling_count_distinct__expected.yml +if os.getenv('dbt_target') == 'bigquery': + rolling_count_distinct__expected_yml = """ +version: 2 +seeds: + - name: rolling_count_distinct__expected + config: + column_types: + date_month: date + rolling_count_distinct: INT64 + rolling_count_distinct_rolling_min_2_month: INT64 + rolling_count_distinct_rolling_max_2_month: INT64 + rolling_count_distinct_rolling_sum_2_month: INT64 + rolling_count_distinct_rolling_average_2_month: FLOAT64 +""".lstrip() +else: + rolling_count_distinct__expected_yml = """""" + +class TestRollingCountDistinct: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "rolling_count_distinct__expected.csv": rolling_count_distinct__expected_csv, + "rolling_count_distinct__expected.yml": rolling_count_distinct__expected_yml + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "rolling_count_distinct.sql": rolling_count_distinct_sql, + "rolling_count_distinct.yml": rolling_count_distinct_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/secondary_calculations/rolling/test_rolling_expression.py b/tests/functional/metric_options/secondary_calculations/rolling/test_rolling_expression.py new file mode 100644 index 00000000..cb1bb3ea --- /dev/null +++ b/tests/functional/metric_options/secondary_calculations/rolling/test_rolling_expression.py @@ -0,0 +1,179 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/rolling_expression_metric.sql +rolling_expression_metric_sql = """ +select * +from +{{ metrics.calculate(metric('rolling_expression_metric'), + grain='month', + secondary_calculations=[ + metrics.rolling(aggregate="max", interval=2), + metrics.rolling(aggregate="min", interval=2), + metrics.rolling(aggregate="sum", interval=2) + ] + ) +}} +""" + +# models/base_sum_metric.yml +base_sum_metric_yml = """ +version: 2 +metrics: + - name: base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# models/rolling_expression_metric.yml +rolling_expression_metric_yml = """ +version: 2 +models: + - name: rolling_expression_metric + tests: + - dbt_utils.equality: + compare_model: ref('rolling_expression_metric__expected') +metrics: + - name: rolling_expression_metric + label: Expression ($) + timestamp: order_date + time_grains: [day, week, month] + type: expression + sql: "{{metric('base_sum_metric')}} + 1" + dimensions: + - had_discount + - order_country +""" + +# seeds/rolling_expression_metric__expected.csv +if os.getenv('dbt_target') == 'postgres': + rolling_expression_metric__expected_csv = """ +date_month,base_sum_metric,rolling_expression_metric,rolling_expression_metric_rolling_max_2_month,rolling_expression_metric_rolling_min_2_month,rolling_expression_metric_rolling_sum_2_month +2022-01-01,8,9,9,9,9 +2022-02-01,6,7,9,7,16 +""".lstrip() + +# seeds/rolling_expression_metric__expected.csv +if os.getenv('dbt_target') == 'redshift': + rolling_expression_metric__expected_csv = """ +date_month,base_sum_metric,rolling_expression_metric,rolling_expression_metric_rolling_max_2_month,rolling_expression_metric_rolling_min_2_month,rolling_expression_metric_rolling_sum_2_month +2022-01-01,8,9,9,9,9 +2022-02-01,6,7,9,7,16 +""".lstrip() + +# seeds/rolling_expression_metric__expected.csv +if os.getenv('dbt_target') == 'snowflake': + rolling_expression_metric__expected_csv = """ +date_month,base_sum_metric,rolling_expression_metric,rolling_expression_metric_rolling_max_2_month,rolling_expression_metric_rolling_min_2_month,rolling_expression_metric_rolling_sum_2_month +2022-01-01,8,9,9,9,9 +2022-02-01,6,7,9,7,16 +""".lstrip() + +# seeds/rolling_expression_metric__expected.csv +if os.getenv('dbt_target') == 'bigquery': + rolling_expression_metric__expected_csv = """ +date_month,base_sum_metric,rolling_expression_metric,rolling_expression_metric_rolling_max_2_month,rolling_expression_metric_rolling_min_2_month,rolling_expression_metric_rolling_sum_2_month +2022-01-01,8,9,9,9,9 +2022-02-01,6,7,9,7,16 +""".lstrip() + +# seeds/rolling_expression__expected.yml +if os.getenv('dbt_target') == 'bigquery': + rolling_expression__expected_yml = """ +version: 2 +seeds: + - name: rolling_expression__expected + config: + column_types: + date_month: date + rolling_expression: INT64 + rolling_expression_rolling_min_2_month: INT64 + rolling_expression_rolling_max_2_month: INT64 + rolling_expression_rolling_sum_2_month: INT64 +""".lstrip() +else: + rolling_expression__expected_yml = """""" + +class TestRollingExpressionMetric: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "rolling_expression_metric__expected.csv": rolling_expression_metric__expected_csv, + "rolling_expression__expected.yml": rolling_expression__expected_yml + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.yml": fact_orders_yml, + "base_sum_metric.yml": base_sum_metric_yml, + "rolling_expression_metric.yml": rolling_expression_metric_yml, + "fact_orders.sql": fact_orders_sql, + "rolling_expression_metric.sql": rolling_expression_metric_sql + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/secondary_calculations/rolling/test_rolling_max.py b/tests/functional/metric_options/secondary_calculations/rolling/test_rolling_max.py new file mode 100644 index 00000000..e5bbf217 --- /dev/null +++ b/tests/functional/metric_options/secondary_calculations/rolling/test_rolling_max.py @@ -0,0 +1,164 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/rolling_max.sql +rolling_max_sql = """ +select * +from +{{ metrics.calculate(metric('rolling_max'), + grain='month', + secondary_calculations=[ + metrics.rolling(aggregate="min", interval=2), + metrics.rolling(aggregate="max", interval=2), + metrics.rolling(aggregate="sum", interval=2), + metrics.rolling(aggregate="average", interval=2) + ] + ) +}} +""" + +# models/rolling_max.yml +rolling_max_yml = """ +version: 2 +models: + - name: rolling_max + tests: + - dbt_utils.equality: + compare_model: ref('rolling_max__expected') +metrics: + - name: rolling_max + model: ref('fact_orders') + label: rolling min + timestamp: order_date + time_grains: [day, week, month] + type: max + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# seeds/rolling_max__expected.csv +if os.getenv('dbt_target') == 'postgres': + rolling_max__expected_csv = """ +date_month,rolling_max,rolling_max_rolling_min_2_month,rolling_max_rolling_max_2_month,rolling_max_rolling_sum_2_month,rolling_max_rolling_average_2_month +2022-01-01,2,2,2,2,2.0000000000000000 +2022-02-01,4,2,4,6,3.0000000000000000 +""".lstrip() + +# seeds/rolling_max__expected.csv +if os.getenv('dbt_target') == 'redshift': + rolling_max__expected_csv = """ +date_month,rolling_max,rolling_max_rolling_min_2_month,rolling_max_rolling_max_2_month,rolling_max_rolling_sum_2_month,rolling_max_rolling_average_2_month +2022-01-01,2,2,2,2,2.0000000000000000 +2022-02-01,4,2,4,6,3.0000000000000000 +""".lstrip() + +# seeds/rolling_max__expected.csv +if os.getenv('dbt_target') == 'snowflake': + rolling_max__expected_csv = """ +date_month,rolling_max,rolling_max_rolling_min_2_month,rolling_max_rolling_max_2_month,rolling_max_rolling_sum_2_month,rolling_max_rolling_average_2_month +2022-01-01,2,2,2,2,2.000000 +2022-02-01,4,2,4,6,3.000000 +""".lstrip() + +# seeds/rolling_max__expected.csv +if os.getenv('dbt_target') == 'bigquery': + rolling_max__expected_csv = """ +date_month,rolling_max,rolling_max_rolling_min_2_month,rolling_max_rolling_max_2_month,rolling_max_rolling_sum_2_month,rolling_max_rolling_average_2_month +2022-01-01,2,2,2,2,2.0000000000000000 +2022-02-01,4,2,4,6,3.0000000000000000 +""".lstrip() + +# seeds/rolling_max__expected.yml +if os.getenv('dbt_target') == 'bigquery': + rolling_max__expected_yml = """ +version: 2 +seeds: + - name: rolling_max__expected + config: + column_types: + date_month: date + rolling_max: INT64 + rolling_max_rolling_min_2_month: INT64 + rolling_max_rolling_max_2_month: INT64 + rolling_max_rolling_sum_2_month: INT64 + rolling_max_rolling_average_2_month: FLOAT64 +""".lstrip() +else: + rolling_max__expected_yml = """""" + +class TestRollingMax: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "rolling_max__expected.csv": rolling_max__expected_csv, + "rolling_max__expected.yml": rolling_max__expected_yml, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "rolling_max.sql": rolling_max_sql, + "rolling_max.yml": rolling_max_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/secondary_calculations/rolling/test_rolling_min.py b/tests/functional/metric_options/secondary_calculations/rolling/test_rolling_min.py new file mode 100644 index 00000000..262cd971 --- /dev/null +++ b/tests/functional/metric_options/secondary_calculations/rolling/test_rolling_min.py @@ -0,0 +1,164 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/rolling_min.sql +rolling_min_sql = """ +select * +from +{{ metrics.calculate(metric('rolling_min'), + grain='month', + secondary_calculations=[ + metrics.rolling(aggregate="min", interval=2), + metrics.rolling(aggregate="max", interval=2), + metrics.rolling(aggregate="sum", interval=2), + metrics.rolling(aggregate="average", interval=2) + ] + ) +}} +""" + +# models/rolling_min.yml +rolling_min_yml = """ +version: 2 +models: + - name: rolling_min + tests: + - dbt_utils.equality: + compare_model: ref('rolling_min__expected') +metrics: + - name: rolling_min + model: ref('fact_orders') + label: rolling min + timestamp: order_date + time_grains: [day, week, month] + type: min + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# seeds/rolling_min__expected.csv +if os.getenv('dbt_target') == 'postgres': + rolling_min__expected_csv = """ +date_month,rolling_min,rolling_min_rolling_min_2_month,rolling_min_rolling_max_2_month,rolling_min_rolling_sum_2_month,rolling_min_rolling_average_2_month +2022-01-01,1,1,1,1,1.0000000000000000 +2022-02-01,1,1,1,2,1.0000000000000000 +""".lstrip() + +# seeds/rolling_min__expected.csv +if os.getenv('dbt_target') == 'redshift': + rolling_min__expected_csv = """ +date_month,rolling_min,rolling_min_rolling_min_2_month,rolling_min_rolling_max_2_month,rolling_min_rolling_sum_2_month,rolling_min_rolling_average_2_month +2022-01-01,1,1,1,1,1.0000000000000000 +2022-02-01,1,1,1,2,1.0000000000000000 +""".lstrip() + +# seeds/rolling_min__expected.csv +if os.getenv('dbt_target') == 'snowflake': + rolling_min__expected_csv = """ +date_month,rolling_min,rolling_min_rolling_min_2_month,rolling_min_rolling_max_2_month,rolling_min_rolling_sum_2_month,rolling_min_rolling_average_2_month +2022-01-01,1,1,1,1,1.000000 +2022-02-01,1,1,1,2,1.000000 +""".lstrip() + +# seeds/rolling_min__expected.csv +if os.getenv('dbt_target') == 'bigquery': + rolling_min__expected_csv = """ +date_month,rolling_min,rolling_min_rolling_min_2_month,rolling_min_rolling_max_2_month,rolling_min_rolling_sum_2_month,rolling_min_rolling_average_2_month +2022-01-01,1,1,1,1,1.0000000000000000 +2022-02-01,1,1,1,2,1.0000000000000000 +""".lstrip() + +# seeds/rolling_min__expected.yml +if os.getenv('dbt_target') == 'bigquery': + rolling_min__expected_yml = """ +version: 2 +seeds: + - name: rolling_min__expected + config: + column_types: + date_month: date + rolling_min: INT64 + rolling_min_rolling_min_2_month: INT64 + rolling_min_rolling_max_2_month: INT64 + rolling_min_rolling_sum_2_month: INT64 + rolling_min_rolling_average_2_month: FLOAT64 +""".lstrip() +else: + rolling_min__expected_yml = """""" + +class TestRollingMin: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "rolling_min__expected.csv": rolling_min__expected_csv, + "rolling_min__expected.yml": rolling_min__expected_yml + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "rolling_min.sql": rolling_min_sql, + "rolling_min.yml": rolling_min_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/secondary_calculations/rolling/test_rolling_sum.py b/tests/functional/metric_options/secondary_calculations/rolling/test_rolling_sum.py new file mode 100644 index 00000000..36e67780 --- /dev/null +++ b/tests/functional/metric_options/secondary_calculations/rolling/test_rolling_sum.py @@ -0,0 +1,164 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/rolling_sum.sql +rolling_sum_sql = """ +select * +from +{{ metrics.calculate(metric('rolling_sum'), + grain='month', + secondary_calculations=[ + metrics.rolling(aggregate="min", interval=2), + metrics.rolling(aggregate="max", interval=2), + metrics.rolling(aggregate="sum", interval=2), + metrics.rolling(aggregate="average", interval=2) + ] + ) +}} +""" + +# models/rolling_sum.yml +rolling_sum_yml = """ +version: 2 +models: + - name: rolling_sum + tests: + - dbt_utils.equality: + compare_model: ref('rolling_sum__expected') +metrics: + - name: rolling_sum + model: ref('fact_orders') + label: Count Distinct + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: customer_id + dimensions: + - had_discount + - order_country +""" + +# seeds/rolling_sum__expected.csv +if os.getenv('dbt_target') == 'postgres': + rolling_sum__expected_csv = """ +date_month,rolling_sum,rolling_sum_rolling_min_2_month,rolling_sum_rolling_max_2_month,rolling_sum_rolling_sum_2_month,rolling_sum_rolling_average_2_month +2022-01-01,18,18,18,18,18.0000000000000000 +2022-02-01,6,6,18,24,12.0000000000000000 +""".lstrip() + +# seeds/rolling_sum__expected.csv +if os.getenv('dbt_target') == 'redshift': + rolling_sum__expected_csv = """ +date_month,rolling_sum,rolling_sum_rolling_min_2_month,rolling_sum_rolling_max_2_month,rolling_sum_rolling_sum_2_month,rolling_sum_rolling_average_2_month +2022-01-01,18,18,18,18,18.0000000000000000 +2022-02-01,6,6,18,24,12.0000000000000000 +""".lstrip() + +# seeds/rolling_sum__expected.csv +if os.getenv('dbt_target') == 'snowflake': + rolling_sum__expected_csv = """ +date_month,rolling_sum,rolling_sum_rolling_min_2_month,rolling_sum_rolling_max_2_month,rolling_sum_rolling_sum_2_month,rolling_sum_rolling_average_2_month +2022-01-01,18,18,18,18,18.000000 +2022-02-01,6,6,18,24,12.000000 +""".lstrip() + +# seeds/rolling_sum__expected.csv +if os.getenv('dbt_target') == 'bigquery': + rolling_sum__expected_csv = """ +date_month,rolling_sum,rolling_sum_rolling_min_2_month,rolling_sum_rolling_max_2_month,rolling_sum_rolling_sum_2_month,rolling_sum_rolling_average_2_month +2022-01-01,18,18,18,18,18.0000000000000000 +2022-02-01,6,6,18,24,12.0000000000000000 +""".lstrip() + +# seeds/rolling_sum__expected.yml +if os.getenv('dbt_target') == 'bigquery': + rolling_sum__expected_yml = """ +version: 2 +seeds: + - name: rolling_sum__expected + config: + column_types: + date_month: date + rolling_sum: INT64 + rolling_sum_rolling_min_2_month: INT64 + rolling_sum_rolling_max_2_month: INT64 + rolling_sum_rolling_sum_2_month: INT64 + rolling_sum_rolling_average_2_month: FLOAT64 +""".lstrip() +else: + rolling_sum__expected_yml = """""" + +class TestRollingSum: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "rolling_sum__expected.csv": rolling_sum__expected_csv, + "rolling_sum__expected.yml":rolling_sum__expected_yml + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "rolling_sum.sql": rolling_sum_sql, + "rolling_sum.yml": rolling_sum_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/start_date/test_late_start_date_base_metric.py b/tests/functional/metric_options/start_date/test_late_start_date_base_metric.py new file mode 100644 index 00000000..1e589cbf --- /dev/null +++ b/tests/functional/metric_options/start_date/test_late_start_date_base_metric.py @@ -0,0 +1,115 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/late_start_date_base_sum_metric.sql +late_start_date_base_sum_metric_sql = """ +select * +from +{{ metrics.calculate(metric('late_start_date_base_sum_metric'), + grain='month', + start_date='2022-02-04' + ) +}} +""" + +# models/late_start_date_base_sum_metric.yml +late_start_date_base_sum_metric_yml = """ +version: 2 +models: + - name: late_start_date_base_sum_metric + tests: + - dbt_utils.equality: + compare_model: ref('late_start_date_base_sum_metric__expected') +metrics: + - name: late_start_date_base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# seeds/late_start_date_base_sum_metric__expected.csv +late_start_date_base_sum_metric__expected_csv = """ +date_month,late_start_date_base_sum_metric +2022-02-01,5 +""".lstrip() + +class TestLateStartDateBaseSumMetric: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "late_start_date_base_sum_metric__expected.csv": late_start_date_base_sum_metric__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "late_start_date_base_sum_metric.sql": late_start_date_base_sum_metric_sql, + "late_start_date_base_sum_metric.yml": late_start_date_base_sum_metric_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/start_date/test_late_start_date_expression_metric.py b/tests/functional/metric_options/start_date/test_late_start_date_expression_metric.py new file mode 100644 index 00000000..fcc46f59 --- /dev/null +++ b/tests/functional/metric_options/start_date/test_late_start_date_expression_metric.py @@ -0,0 +1,131 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/late_start_date_expression_metric.sql +late_start_date_expression_metric_sql = """ +select * +from +{{ metrics.calculate(metric('late_start_date_expression_metric'), + grain='month', + start_date='2022-02-04' + ) +}} +""" + +# models/base_sum_metric.yml +base_sum_metric_yml = """ +version: 2 +metrics: + - name: base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# models/late_start_date_expression_metric.yml +late_start_date_expression_metric_yml = """ +version: 2 +models: + - name: late_start_date_expression_metric + tests: + - dbt_utils.equality: + compare_model: ref('late_start_date_expression_metric__expected') +metrics: + - name: late_start_date_expression_metric + label: Expression ($) + timestamp: order_date + time_grains: [day, week, month] + type: expression + sql: "{{metric('base_sum_metric')}} + 1" + dimensions: + - had_discount + - order_country +""" + +# seeds/late_start_date_expression_metric__expected.csv +late_start_date_expression_metric__expected_csv = """ +date_month,base_sum_metric,late_start_date_expression_metric +2022-02-01,5,6 +""".lstrip() + +class TestStartDateExpressionMetric: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "late_start_date_expression_metric__expected.csv": late_start_date_expression_metric__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.yml": fact_orders_yml, + "base_sum_metric.yml": base_sum_metric_yml, + "late_start_date_expression_metric.yml": late_start_date_expression_metric_yml, + "fact_orders.sql": fact_orders_sql, + "late_start_date_expression_metric.sql": late_start_date_expression_metric_sql + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/start_date/test_start_date_base_metric.py b/tests/functional/metric_options/start_date/test_start_date_base_metric.py new file mode 100644 index 00000000..435f43e7 --- /dev/null +++ b/tests/functional/metric_options/start_date/test_start_date_base_metric.py @@ -0,0 +1,115 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/start_date_base_sum_metric.sql +start_date_base_sum_metric_sql = """ +select * +from +{{ metrics.calculate(metric('start_date_base_sum_metric'), + grain='month', + start_date='2022-02-01' + ) +}} +""" + +# models/start_date_base_sum_metric.yml +start_date_base_sum_metric_yml = """ +version: 2 +models: + - name: start_date_base_sum_metric + tests: + - dbt_utils.equality: + compare_model: ref('start_date_base_sum_metric__expected') +metrics: + - name: start_date_base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# seeds/start_date_base_sum_metric__expected.csv +start_date_base_sum_metric__expected_csv = """ +date_month,start_date_base_sum_metric +2022-02-01,6 +""".lstrip() + +class TestStartDateBaseSumMetric: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "start_date_base_sum_metric__expected.csv": start_date_base_sum_metric__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.sql": fact_orders_sql, + "fact_orders.yml": fact_orders_yml, + "start_date_base_sum_metric.sql": start_date_base_sum_metric_sql, + "start_date_base_sum_metric.yml": start_date_base_sum_metric_yml + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file diff --git a/tests/functional/metric_options/start_date/test_start_date_expression_metric.py b/tests/functional/metric_options/start_date/test_start_date_expression_metric.py new file mode 100644 index 00000000..d699aeb8 --- /dev/null +++ b/tests/functional/metric_options/start_date/test_start_date_expression_metric.py @@ -0,0 +1,131 @@ +from struct import pack +import os +import pytest +from dbt.tests.util import run_dbt + +# our file contents +from tests.functional.fixtures import ( + fact_orders_source_csv, + fact_orders_sql, + fact_orders_yml, +) + +# models/start_date_expression_metric.sql +start_date_expression_metric_sql = """ +select * +from +{{ metrics.calculate(metric('start_date_expression_metric'), + grain='month', + start_date='2022-02-01' + ) +}} +""" + +# models/base_sum_metric.yml +base_sum_metric_yml = """ +version: 2 +metrics: + - name: base_sum_metric + model: ref('fact_orders') + label: Total Discount ($) + timestamp: order_date + time_grains: [day, week, month] + type: sum + sql: order_total + dimensions: + - had_discount + - order_country +""" + +# models/start_date_expression_metric.yml +start_date_expression_metric_yml = """ +version: 2 +models: + - name: start_date_expression_metric + tests: + - dbt_utils.equality: + compare_model: ref('start_date_expression_metric__expected') +metrics: + - name: start_date_expression_metric + label: Expression ($) + timestamp: order_date + time_grains: [day, week, month] + type: expression + sql: "{{metric('base_sum_metric')}} + 1" + dimensions: + - had_discount + - order_country +""" + +# seeds/start_date_expression_metric__expected.csv +start_date_expression_metric__expected_csv = """ +date_month,base_sum_metric,start_date_expression_metric +2022-02-01,6,7 +""".lstrip() + +class TestStartDateExpressionMetric: + + # configuration in dbt_project.yml + if os.getenv('dbt_target') == 'bigquery': + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "table"} + } + else: + @pytest.fixture(scope="class") + def project_config_update(self): + return { + "name": "example", + "models": {"+materialized": "view"} + } + + # install current repo as package + @pytest.fixture(scope="class") + def packages(self): + return { + "packages": [ + {"local": os.getcwd()} + ] + } + + + # everything that goes in the "seeds" directory + @pytest.fixture(scope="class") + def seeds(self): + return { + "fact_orders_source.csv": fact_orders_source_csv, + "start_date_expression_metric__expected.csv": start_date_expression_metric__expected_csv, + } + + # everything that goes in the "models" directory + @pytest.fixture(scope="class") + def models(self): + return { + "fact_orders.yml": fact_orders_yml, + "base_sum_metric.yml": base_sum_metric_yml, + "start_date_expression_metric.yml": start_date_expression_metric_yml, + "fact_orders.sql": fact_orders_sql, + "start_date_expression_metric.sql": start_date_expression_metric_sql + } + + def test_build_completion(self,project,): + # running deps to install package + results = run_dbt(["deps"]) + + # seed seeds + results = run_dbt(["seed"]) + assert len(results) == 2 + + # initial run + results = run_dbt(["run"]) + assert len(results) == 3 + + # test tests + results = run_dbt(["test"]) # expect passing test + assert len(results) == 1 + + # # # # validate that the results include pass + result_statuses = sorted(r.status for r in results) + assert result_statuses == ["pass"] \ No newline at end of file