Skip to content

Commit

Permalink
✅ Add end to end tests.
Browse files Browse the repository at this point in the history
  • Loading branch information
rafalkrupinski committed May 21, 2024
1 parent 2634252 commit 9fac158
Show file tree
Hide file tree
Showing 61 changed files with 2,594 additions and 17 deletions.
2 changes: 0 additions & 2 deletions src/lapidary/render/load.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import abc
import hashlib
import logging
import pickle
from collections.abc import Iterable, Mapping, Sequence
from typing import cast

Expand Down
12 changes: 0 additions & 12 deletions src/lapidary/render/templates/pyproject.toml.jinja
Original file line number Diff line number Diff line change
Expand Up @@ -14,24 +14,12 @@ packages = [

[tool.poetry.dependencies]
python = "^3.9"
pydantic = { extras = ["email"], version = "^{{ get_version('pydantic') }}" }
lapidary = "{{ get_version('lapidary') }}"

[tool.poetry.group.dev.dependencies]
mypy = "0.990"
lapidary-render = "{{ get_version('lapidary_render') }}"
taskipy = "^1.10.3"

[tool.taskipy.tasks]
update = 'lapidary update'
mypy = 'mypy'
check = 'task mypy'

[tool.lapidary]
{%- for key, value in config.items() %}
{{ key }} = "{{ value }}"
{%- endfor %}

[tool.mypy]
mypy_path = ['gen']
packages = ['{{ config.package }}']
8 changes: 8 additions & 0 deletions tests/e2e/Readme.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# End to end tests

1. Create a project scaffolding (schema and pyproject.toml) for a test project (for example with `lapidary init`) in `init` directory
2. Copy the project scaffolding to `expected`
3. Render project in `expected` directory.
4. Examine the rendered code.
5. If code is satisfactory, commit the new code to git.
6. test_e2e.py will re-render the project and compare the result with the contents of `expected`.
141 changes: 141 additions & 0 deletions tests/e2e/expected/dummy/dummy.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
openapi: 3.0.2
info:
title: subschemas
description: 'test generating /components/schemas with sub-schemas'
version: 1.0.0
paths:
/test/:
get:
operationId: test_op
responses:
default:
content: { }
description: ''

parameters:
- name: param1
in: query
schema:
$ref: '#/components/schemas/schema1'
required: true
- name: param2
in: query
schema:
type: object
properties:
prop1:
type: string
additionalProperties: false
required:
- prop1
required: true

components:
schemas:
schema1:
type: object
properties:
prop1:
type: object
properties:
prop2:
type: object
properties:
key:
type: string
required:
- key
additionalProperties: false
additionalProperties: false
required:
- prop2
additionalProperties: false
required:
- prop1
securitySchemes:
oauth-refresh:
type: oauth2
flows:
authorizationCode:
authorizationUrl: https://example.com/authorization_url
tokenUrl: https://example.com/token_url
refreshUrl: https://example.com/refresh_url
scopes:
read: read
write: write
clientCredentials:
refreshUrl: https://example.com/refresh_url
tokenUrl: https://example.com/token_url
scopes:
read: read
write: write
implicit:
authorizationUrl: https://example.com/authorization_url
refreshUrl: https://example.com/refresh_url
scopes:
read: read
write: write
password:
tokenUrl: https://example.com/token_url
refreshUrl: https://example.com/refresh_url
scopes:
read: read
write: write
oauth:
type: oauth2
flows:
authorizationCode:
authorizationUrl: https://example.com/authorization_url
tokenUrl: https://example.com/token_url
scopes:
read: read
write: write
clientCredentials:
tokenUrl: https://example.com/token_url
scopes:
read: read
write: write
implicit:
authorizationUrl: https://example.com/authorization_url
scopes:
read: read
write: write
password:
tokenUrl: https://example.com/token_url
scopes:
read: read
write: write
api-key:
type: apiKey
name: x-api-key
in: header
api-key-cookie:
type: apiKey
name: x-api-key
in: cookie
api-key-query:
type: apiKey
name: x-api-key
in: query
http_basic:
type: http
scheme: Basic
http_bearer:
type: http
scheme: bearer
http_digest:
type: http
scheme: digest

security:
- oauth-refresh:
- read
- write
- oauth:
- read
- write
- api-key: []
- api-key-cookie: []
- api-key-query: []
- http_basic: []
- http_digest: []
Empty file.
52 changes: 52 additions & 0 deletions tests/e2e/expected/dummy/gen/test_dummy/client.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# This file is automatically @generated by Lapidary and should not be changed by hand.


__all__ = [
'ApiClient',
]

import typing

from typing_extensions import Self
from typing import Annotated, Union
from lapidary.runtime import *


import test_dummy.components.schemas.schema1.schema
import test_dummy.paths.u_00007e01testu_00007e01.get.parameters.u_000031.schema.schema


class ApiClient(ClientBase):
def __init__(
self,
*,
base_url: str,
**kwargs,
):
super().__init__(
base_url=base_url,
security=[{'oauth-refresh': ['read', 'write']}, {'oauth': ['read', 'write']}, {'api-key': []}, {'api-key-cookie': []}, {'api-key-query': []}, {'http_basic': []}, {'http_digest': []}],
**kwargs,
)

async def __aenter__(self) -> 'ApiClient':
await super().__aenter__()
return self

async def __aexit__(self, __exc_type=None, __exc_value=None, __traceback=None) -> None:
await super().__aexit__(__exc_type, __exc_value, __traceback)

@get('/test/')
async def test_op(
self: Self,
*,
param1_q: Annotated[test_dummy.components.schemas.schema1.schema.schema1, Query('param1', )],
param2_q: Annotated[test_dummy.paths.u_00007e01testu_00007e01.get.parameters.u_000031.schema.schema.schema, Query('param2', )],
) -> Annotated[
None,
Responses({
'default': {
},
})
]:
pass
Empty file.
Empty file.
Empty file.
Empty file.
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# This file is automatically @generated by Lapidary and should not be changed by hand.

from __future__ import annotations

import typing

import lapidary.runtime
import pydantic
import typing_extensions
import lapidary.runtime


class prop2(lapidary.runtime.ModelBase):
key: typing.Annotated[
str,
pydantic.Field(
alias='key',
)
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# This file is automatically @generated by Lapidary and should not be changed by hand.

from __future__ import annotations

import typing

import lapidary.runtime
import pydantic
import typing_extensions
import lapidary.runtime
import test_dummy.components.schemas.schema1.properties.prop1.properties.prop2.schema


class prop1(lapidary.runtime.ModelBase):
prop2: typing.Annotated[
test_dummy.components.schemas.schema1.properties.prop1.properties.prop2.schema.prop2,
pydantic.Field(
alias='prop2',
)
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# This file is automatically @generated by Lapidary and should not be changed by hand.

from __future__ import annotations

import typing

import lapidary.runtime
import pydantic
import typing_extensions
import lapidary.runtime
import test_dummy.components.schemas.schema1.properties.prop1.schema


class schema1(lapidary.runtime.ModelBase):
prop1: typing.Annotated[
test_dummy.components.schemas.schema1.properties.prop1.schema.prop1,
pydantic.Field(
alias='prop1',
)
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
# This file is automatically @generated by Lapidary and should not be changed by hand.

from collections.abc import Iterable
from typing import Union

import httpx
import httpx_auth
import lapidary.runtime.auth
from lapidary.runtime import NamedAuth
from typing_extensions import Literal


def oauth2_implicit_oauth(
scope: Union[Iterable[Literal['read', 'write']], None] = None,
**kwargs,
) -> NamedAuth:
if scope is not None:
kwargs['scope'] = ' '.join(scope)

return 'oauth', httpx_auth.OAuth2Implicit(
authorization_url='https://example.com/authorization_url',
**kwargs,
)


def oauth2_client_credentials_oauth(
client_id: str,
client_secret: str,
scope: Union[Iterable[Literal['read', 'write']], None] = None,
**kwargs,
) -> NamedAuth:
if scope is not None:
kwargs['scope'] = ' '.join(scope)

return 'oauth', httpx_auth.OAuth2ClientCredentials(
token_url='https://example.com/token_url',
client_id=client_id,
client_secret=client_secret,
**kwargs,
)


def oauth2_authorization_code_oauth(
scope: Union[Iterable[Literal['read', 'write']], None] = None,
**kwargs,
) -> NamedAuth:
if scope is not None:
kwargs['scope'] = ' '.join(scope)

return 'oauth', httpx_auth.OAuth2AuthorizationCode(
authorizaiton_url='https://example.com/authorization_url',
token_url='https://example.com/token_url',
**kwargs,
)


def api_key_apiu_00002dkey(api_key: str) -> NamedAuth:
return 'api-key', lapidary.runtime.auth.HeaderApiKey(
api_key=api_key,
header_name='x-api-key',
)


def api_key_apiu_00002dkeyu_00002dcookie(api_key: str) -> NamedAuth:
return 'api-key-cookie', lapidary.runtime.auth.CookieApiKey(
api_key=api_key,
cookie_name='x-api-key',
)


def api_key_apiu_00002dkeyu_00002dquery(api_key: str) -> NamedAuth:
return 'api-key-query', lapidary.runtime.auth.QueryApiKey(
api_key=api_key,
query_parameter_name='x-api-key',
)


def http_basic_http_basic(user_name: str, password: str) -> NamedAuth:
return 'http_basic', httpx.BasicAuth(
username=user_name,
password=password,
)


def http_digest_http_digest(user_name: str, password: str) -> NamedAuth:
return 'http_digest', httpx.DigestAuth(
username=user_name,
password=password,
)
Empty file.
Empty file.
Empty file.
Loading

0 comments on commit 9fac158

Please sign in to comment.