From 98ef5e255adcd5ff3800f1fb36da87260ebe8531 Mon Sep 17 00:00:00 2001 From: "Sean T. Allen" Date: Sat, 8 Aug 2026 21:57:19 -0400 Subject: [PATCH] Add pony-lint and fix all lint errors Add pony-lint CI workflow and Makefile lint target, then fix all lint errors across the codebase: acronym casing (Json->JSON, Url->URL), dot-spacing, call-argument-format, assignment-indent, match-case-indent, control-structure-alignment, line-length, blank-lines, indentation-size, public-docstring, package-docstring, docstring-format, prefer-chaining, and exhaustive-match annotations. Six file-naming errors remain. These require file renames that would be a separate change. --- .github/workflows/pony-lint.yml | 24 + Makefile | 10 +- examples/create-gist-oo/create_gist_oo.pony | 3 + examples/create-gist-oo/main.pony | 31 +- examples/create-gist/create_gist.pony | 3 + examples/create-gist/main.pony | 31 +- .../create_issue_comment_oo.pony | 3 + examples/create-issue-comment-oo/main.pony | 35 +- .../create_issue_comment.pony | 3 + examples/create-issue-comment/main.pony | 19 +- examples/create-label-oo/create_label_oo.pony | 3 + examples/create-label-oo/main.pony | 20 +- examples/create-label/create_label.pony | 3 + examples/create-label/main.pony | 15 +- .../create-release-oo/create_release_oo.pony | 3 + examples/create-release-oo/main.pony | 24 +- examples/create-release/create_release.pony | 3 + examples/create-release/main.pony | 19 +- examples/delete-label-oo/delete_label_oo.pony | 3 + examples/delete-label-oo/main.pony | 20 +- examples/delete-label/delete_label.pony | 3 + examples/delete-label/main.pony | 15 +- examples/get-commit-oo/get_commit_oo.pony | 3 + examples/get-commit-oo/main.pony | 27 +- examples/get-commit/get_commit.pony | 3 + examples/get-commit/main.pony | 22 +- examples/get-gist-oo/get_gist_oo.pony | 3 + examples/get-gist-oo/main.pony | 18 +- examples/get-gist/get_gist.pony | 3 + examples/get-gist/main.pony | 18 +- .../get_issue_comments_oo.pony | 3 + examples/get-issue-comments-oo/main.pony | 38 +- .../get_issue_comments.pony | 3 + examples/get-issue-comments/main.pony | 22 +- examples/get-issue-oo/get_issue_oo.pony | 3 + examples/get-issue-oo/main.pony | 31 +- examples/get-issue/get_issue.pony | 3 + examples/get-issue/main.pony | 22 +- examples/get-issues-oo/get_issues_oo.pony | 3 + examples/get-issues-oo/main.pony | 72 +- examples/get-issues/get_issues.pony | 3 + examples/get-issues/main.pony | 64 +- .../get_pull_request_files_oo.pony | 3 + examples/get-pull-request-files-oo/main.pony | 38 +- .../get_pull_request_files.pony | 3 + examples/get-pull-request-files/main.pony | 22 +- .../get_pull_request_oo.pony | 3 + examples/get-pull-request-oo/main.pony | 31 +- .../get-pull-request/get_pull_request.pony | 3 + examples/get-pull-request/main.pony | 22 +- .../get_repository_labels.pony | 3 + examples/get-repository-labels/main.pony | 22 +- .../get-repository-oo/get_repository_oo.pony | 3 + examples/get-repository-oo/main.pony | 22 +- examples/get-repository/get_repository.pony | 3 + examples/get-repository/main.pony | 22 +- .../gist-comments-oo/gist_comments_oo.pony | 3 + examples/gist-comments-oo/main.pony | 23 +- examples/gist-comments/gist_comments.pony | 3 + examples/gist-comments/main.pony | 18 +- examples/list-gists-oo/list_gists_oo.pony | 3 + examples/list-gists-oo/main.pony | 20 +- examples/list-gists/list_gists.pony | 3 + examples/list-gists/main.pony | 20 +- examples/search-issues/main.pony | 18 +- examples/search-issues/search_issues.pony | 3 + examples/standard-pony-labels/main.pony | 68 +- .../standard_pony_labels.pony | 3 + examples/star-gist-oo/main.pony | 27 +- examples/star-gist-oo/star_gist_oo.pony | 3 + examples/star-gist/main.pony | 20 +- examples/star-gist/star_gist.pony | 3 + github_rest_api/_test.pony | 135 ++-- github_rest_api/_test_json_converters.pony | 707 +++++++++++------- github_rest_api/_test_mock_http_server.pony | 14 +- github_rest_api/_test_request_actors.pony | 238 ++++-- github_rest_api/_test_result_receivers.pony | 75 +- .../_test_search_and_pagination.pony | 167 +++-- github_rest_api/asset.pony | 14 +- github_rest_api/commit.pony | 28 +- github_rest_api/commit_file.pony | 5 +- github_rest_api/gist.pony | 175 +++-- github_rest_api/gist_comment.pony | 97 ++- github_rest_api/gist_commit.pony | 17 +- github_rest_api/gist_file.pony | 14 +- github_rest_api/git_commit.pony | 9 +- github_rest_api/git_person.pony | 2 +- github_rest_api/issue.pony | 103 +-- github_rest_api/issue_comment.pony | 60 +- github_rest_api/issue_pull_request.pony | 7 +- github_rest_api/json_nav_util.pony | 2 +- github_rest_api/label.pony | 45 +- github_rest_api/license.pony | 8 +- github_rest_api/paginated_list.pony | 116 +-- github_rest_api/pull_request.pony | 42 +- github_rest_api/pull_request_base.pony | 9 +- github_rest_api/pull_request_file.pony | 30 +- github_rest_api/release.pony | 38 +- github_rest_api/repository.pony | 195 ++--- github_rest_api/request/_ssl.pony | 6 +- github_rest_api/request/_test.pony | 6 +- github_rest_api/request/check_requester.pony | 60 +- github_rest_api/request/credentials.pony | 13 +- github_rest_api/request/json.pony | 17 +- github_rest_api/request/json_requester.pony | 90 ++- .../request/no_content_requester.pony | 60 +- github_rest_api/request/request.pony | 5 + github_rest_api/request/request_error.pony | 4 + github_rest_api/search.pony | 48 +- github_rest_api/user.pony | 8 +- 110 files changed, 2423 insertions(+), 1341 deletions(-) create mode 100644 .github/workflows/pony-lint.yml create mode 100644 examples/create-gist-oo/create_gist_oo.pony create mode 100644 examples/create-gist/create_gist.pony create mode 100644 examples/create-issue-comment-oo/create_issue_comment_oo.pony create mode 100644 examples/create-issue-comment/create_issue_comment.pony create mode 100644 examples/create-label-oo/create_label_oo.pony create mode 100644 examples/create-label/create_label.pony create mode 100644 examples/create-release-oo/create_release_oo.pony create mode 100644 examples/create-release/create_release.pony create mode 100644 examples/delete-label-oo/delete_label_oo.pony create mode 100644 examples/delete-label/delete_label.pony create mode 100644 examples/get-commit-oo/get_commit_oo.pony create mode 100644 examples/get-commit/get_commit.pony create mode 100644 examples/get-gist-oo/get_gist_oo.pony create mode 100644 examples/get-gist/get_gist.pony create mode 100644 examples/get-issue-comments-oo/get_issue_comments_oo.pony create mode 100644 examples/get-issue-comments/get_issue_comments.pony create mode 100644 examples/get-issue-oo/get_issue_oo.pony create mode 100644 examples/get-issue/get_issue.pony create mode 100644 examples/get-issues-oo/get_issues_oo.pony create mode 100644 examples/get-issues/get_issues.pony create mode 100644 examples/get-pull-request-files-oo/get_pull_request_files_oo.pony create mode 100644 examples/get-pull-request-files/get_pull_request_files.pony create mode 100644 examples/get-pull-request-oo/get_pull_request_oo.pony create mode 100644 examples/get-pull-request/get_pull_request.pony create mode 100644 examples/get-repository-labels/get_repository_labels.pony create mode 100644 examples/get-repository-oo/get_repository_oo.pony create mode 100644 examples/get-repository/get_repository.pony create mode 100644 examples/gist-comments-oo/gist_comments_oo.pony create mode 100644 examples/gist-comments/gist_comments.pony create mode 100644 examples/list-gists-oo/list_gists_oo.pony create mode 100644 examples/list-gists/list_gists.pony create mode 100644 examples/search-issues/search_issues.pony create mode 100644 examples/standard-pony-labels/standard_pony_labels.pony create mode 100644 examples/star-gist-oo/star_gist_oo.pony create mode 100644 examples/star-gist/star_gist.pony create mode 100644 github_rest_api/request/request.pony diff --git a/.github/workflows/pony-lint.yml b/.github/workflows/pony-lint.yml new file mode 100644 index 0000000..8ddec33 --- /dev/null +++ b/.github/workflows/pony-lint.yml @@ -0,0 +1,24 @@ +name: pony-lint + +on: + pull_request: + paths: + - '**/*.pony' + +concurrency: + group: pony-lint-${{ github.ref }} + cancel-in-progress: true + +permissions: + packages: read + +jobs: + pony-lint: + name: Lint Pony source + runs-on: ubuntu-latest + container: + image: ghcr.io/ponylang/shared-docker-ci-standard-builder:nightly + steps: + - uses: actions/checkout@v6.0.2 + - name: Lint + run: make lint diff --git a/Makefile b/Makefile index b7eb076..6bc0f43 100644 --- a/Makefile +++ b/Makefile @@ -24,7 +24,9 @@ else PONYC = $(COMPILE_WITH) --debug endif -ifeq (,$(filter $(MAKECMDGOALS),clean docs realclean TAGS)) +LINT_WITH := corral run -- pony-lint + +ifeq (,$(filter $(MAKECMDGOALS),clean docs lint realclean TAGS)) ifeq ($(ssl), 3.0.x) SSL = -Dopenssl_3.0.x else ifeq ($(ssl), 1.1.x) @@ -85,4 +87,8 @@ all: test $(BUILD_DIR): mkdir -p $(BUILD_DIR) -.PHONY: all examples _build_examples clean fetch TAGS test test-one +lint: + $(GET_DEPENDENCIES_WITH) + $(LINT_WITH) . + +.PHONY: all examples _build_examples clean fetch lint TAGS test test-one diff --git a/examples/create-gist-oo/create_gist_oo.pony b/examples/create-gist-oo/create_gist_oo.pony new file mode 100644 index 0000000..28ec8de --- /dev/null +++ b/examples/create-gist-oo/create_gist_oo.pony @@ -0,0 +1,3 @@ +""" +Example program: create-gist-oo. +""" diff --git a/examples/create-gist-oo/main.pony b/examples/create-gist-oo/main.pony index a149d37..1cde143 100644 --- a/examples/create-gist-oo/main.pony +++ b/examples/create-gist-oo/main.pony @@ -8,28 +8,32 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("create-gist-oo", + CommandSpec.leaf( + "create-gist-oo", "Create a new gist with a single file", [ OptionSpec.string("filename", "Name of the file to create") OptionSpec.string("content", "Content of the file") - OptionSpec.string("description", + OptionSpec.string( + "description", "Description of the gist" where default' = "") - OptionSpec.bool("public", + OptionSpec.bool( + "public", "Whether the gist should be public" where default' = false) OptionSpec.string("token", "GitHub personal access token") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -45,11 +49,11 @@ actor Main let auth = lori.TCPConnectAuth(env.root) let creds = Credentials(auth, token) - let files = recover val - let f = Array[(String, String)] - f.push((filename, content)) - f - end + let files = + recover val + Array[(String, String)] + .> push((filename, content)) + end let desc: (String | None) = if description.size() > 0 then description else None end @@ -61,6 +65,9 @@ actor Main end primitive PrintGist + """ + Prints gist creation results to the given output stream. + """ fun apply(out: OutStream, g: GistOrError) => match \exhaustive\ g | let gist: Gist => diff --git a/examples/create-gist/create_gist.pony b/examples/create-gist/create_gist.pony new file mode 100644 index 0000000..b2dc494 --- /dev/null +++ b/examples/create-gist/create_gist.pony @@ -0,0 +1,3 @@ +""" +Example program: create-gist. +""" diff --git a/examples/create-gist/main.pony b/examples/create-gist/main.pony index 9c9743a..ccc22a0 100644 --- a/examples/create-gist/main.pony +++ b/examples/create-gist/main.pony @@ -8,28 +8,32 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("create-gist", + CommandSpec.leaf( + "create-gist", "Create a new gist with a single file", [ OptionSpec.string("filename", "Name of the file to create") OptionSpec.string("content", "Content of the file") - OptionSpec.string("description", + OptionSpec.string( + "description", "Description of the gist" where default' = "") - OptionSpec.bool("public", + OptionSpec.bool( + "public", "Whether the gist should be public" where default' = false) OptionSpec.string("token", "GitHub personal access token") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -45,11 +49,11 @@ actor Main let auth = lori.TCPConnectAuth(env.root) let creds = Credentials(auth, token) - let files = recover val - let f = Array[(String, String)] - f.push((filename, content)) - f - end + let files = + recover val + Array[(String, String)] + .> push((filename, content)) + end let desc: (String | None) = if description.size() > 0 then description else None end @@ -61,6 +65,9 @@ actor Main end primitive PrintGist + """ + Prints gist creation results to the given output stream. + """ fun apply(out: OutStream, g: GistOrError) => match \exhaustive\ g | let gist: Gist => diff --git a/examples/create-issue-comment-oo/create_issue_comment_oo.pony b/examples/create-issue-comment-oo/create_issue_comment_oo.pony new file mode 100644 index 0000000..ff8140c --- /dev/null +++ b/examples/create-issue-comment-oo/create_issue_comment_oo.pony @@ -0,0 +1,3 @@ +""" +Example program: create-issue-comment-oo. +""" diff --git a/examples/create-issue-comment-oo/main.pony b/examples/create-issue-comment-oo/main.pony index e1d72f1..1751661 100644 --- a/examples/create-issue-comment-oo/main.pony +++ b/examples/create-issue-comment-oo/main.pony @@ -9,24 +9,26 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("create-issue-comment-oo", + CommandSpec.leaf( + "create-issue-comment-oo", "Create a comment on a GitHub issue", [ - OptionSpec.string("owner", "Owner of the repository the issue is in") - OptionSpec.string("repo", "Name of the repository the issue is in") + OptionSpec.string("owner", "Repository owner") + OptionSpec.string("repo", "Repository name") OptionSpec.i64("issue", "Issue number") OptionSpec.string("comment", "Comment to add to the issue") OptionSpec.string("token", "GitHub personal access token") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -43,32 +45,41 @@ actor Main let creds = Credentials(auth, token) GitHub(creds).get_repo(owner, repo) - .flatten_next[IssueOrError](RetrieveIssue~apply(issue)) - .flatten_next[IssueCommentOrError](CreateComment~apply(comment)) - .next[None](PrintComment~apply(env.out)) + .flatten_next[IssueOrError](RetrieveIssue~apply(issue)) + .flatten_next[IssueCommentOrError](CreateComment~apply(comment)) + .next[None](PrintComment~apply(env.out)) else env.out.print("Something went wrong") end primitive RetrieveIssue + """ + Retrieves an issue from the repository. + """ fun apply(number: I64, r: RepositoryOrError): Promise[IssueOrError] => match \exhaustive\ r | let repo: Repository => repo.get_issue(number) | let e: RequestError => - Promise[IssueOrError].>apply(e) + Promise[IssueOrError] .> apply(e) end primitive CreateComment + """ + Creates a comment on an issue. + """ fun apply(body: String, i: IssueOrError): Promise[IssueCommentOrError] => match \exhaustive\ i | let issue: Issue => issue.create_comment(body) | let e: RequestError => - Promise[IssueCommentOrError].>apply(e) + Promise[IssueCommentOrError] .> apply(e) end primitive PrintComment + """ + Prints issue comment results to the given output stream. + """ fun apply(out: OutStream, c: IssueCommentOrError) => match \exhaustive\ c | let comment: IssueComment => diff --git a/examples/create-issue-comment/create_issue_comment.pony b/examples/create-issue-comment/create_issue_comment.pony new file mode 100644 index 0000000..c051b95 --- /dev/null +++ b/examples/create-issue-comment/create_issue_comment.pony @@ -0,0 +1,3 @@ +""" +Example program: create-issue-comment. +""" diff --git a/examples/create-issue-comment/main.pony b/examples/create-issue-comment/main.pony index d1ea9b8..30f98a9 100644 --- a/examples/create-issue-comment/main.pony +++ b/examples/create-issue-comment/main.pony @@ -8,24 +8,26 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("create-issue-comment", + CommandSpec.leaf( + "create-issue-comment", "Create a comment on a GitHub issue", [ - OptionSpec.string("owner", "Owner of the repository the issue is in") - OptionSpec.string("repo", "Name of the repository the issue is in") + OptionSpec.string("owner", "Repository owner") + OptionSpec.string("repo", "Repository name") OptionSpec.i64("issue", "Issue number") OptionSpec.string("comment", "Comment to add to the issue") OptionSpec.string("token", "GitHub personal access token") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -48,6 +50,9 @@ actor Main end primitive PrintComment + """ + Prints issue comment results to the given output stream. + """ fun apply(out: OutStream, c: IssueCommentOrError) => match \exhaustive\ c | let comment: IssueComment => diff --git a/examples/create-label-oo/create_label_oo.pony b/examples/create-label-oo/create_label_oo.pony new file mode 100644 index 0000000..07d0a6b --- /dev/null +++ b/examples/create-label-oo/create_label_oo.pony @@ -0,0 +1,3 @@ +""" +Example program: create-label-oo. +""" diff --git a/examples/create-label-oo/main.pony b/examples/create-label-oo/main.pony index 36e0313..904f215 100644 --- a/examples/create-label-oo/main.pony +++ b/examples/create-label-oo/main.pony @@ -9,7 +9,8 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("create-label-oo", + CommandSpec.leaf( + "create-label-oo", "Create a new label", [ OptionSpec.string( @@ -23,13 +24,14 @@ actor Main ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -54,6 +56,9 @@ actor Main end primitive MakeLabel + """ + Creates a label on the repository. + """ fun apply(name: String, color: String, description: String, @@ -63,10 +68,13 @@ primitive MakeLabel | let repo: Repository => repo.create_label(name, color, description) | let e: RequestError => - Promise[LabelOrError].>apply(e) + Promise[LabelOrError] .> apply(e) end primitive PrintLabel + """ + Prints label results to the given output stream. + """ fun apply(out: OutStream, l: LabelOrError) => match \exhaustive\ l | let label: Label => diff --git a/examples/create-label/create_label.pony b/examples/create-label/create_label.pony new file mode 100644 index 0000000..457eeeb --- /dev/null +++ b/examples/create-label/create_label.pony @@ -0,0 +1,3 @@ +""" +Example program: create-label. +""" diff --git a/examples/create-label/main.pony b/examples/create-label/main.pony index e76ce8d..f95499e 100644 --- a/examples/create-label/main.pony +++ b/examples/create-label/main.pony @@ -8,7 +8,8 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("create-label", + CommandSpec.leaf( + "create-label", "Create a new label", [ OptionSpec.string( @@ -22,13 +23,14 @@ actor Main ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -52,6 +54,9 @@ actor Main end primitive PrintLabel + """ + Prints label results to the given output stream. + """ fun apply(out: OutStream, l: LabelOrError) => match \exhaustive\ l | let label: Label => diff --git a/examples/create-release-oo/create_release_oo.pony b/examples/create-release-oo/create_release_oo.pony new file mode 100644 index 0000000..db5520f --- /dev/null +++ b/examples/create-release-oo/create_release_oo.pony @@ -0,0 +1,3 @@ +""" +Example program: create-release-oo. +""" diff --git a/examples/create-release-oo/main.pony b/examples/create-release-oo/main.pony index 6c3b84c..05a4127 100644 --- a/examples/create-release-oo/main.pony +++ b/examples/create-release-oo/main.pony @@ -9,11 +9,12 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("create-release-oo", + CommandSpec.leaf( + "create-release-oo", "Create a release", [ - OptionSpec.string("owner", "Owner of the repository the issue is in") - OptionSpec.string("repo", "Name of the repository the issue is in") + OptionSpec.string("owner", "Repository owner") + OptionSpec.string("repo", "Repository name") OptionSpec.string("tag", "Tag for release") OptionSpec.string("name", "Release name") OptionSpec.string("body", "Release notes") @@ -21,13 +22,14 @@ actor Main ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -52,6 +54,9 @@ actor Main end primitive MakeRelease + """ + Creates a release on the repository. + """ fun apply(tag_name: String, name: String, body: String, @@ -61,10 +66,13 @@ primitive MakeRelease | let repo: Repository => repo.create_release(tag_name, name, body) | let e: RequestError => - Promise[ReleaseOrError].>apply(e) + Promise[ReleaseOrError] .> apply(e) end primitive PrintRelease + """ + Prints release results to the given output stream. + """ fun apply(out: OutStream, r: ReleaseOrError) => match \exhaustive\ r | let release: Release => diff --git a/examples/create-release/create_release.pony b/examples/create-release/create_release.pony new file mode 100644 index 0000000..27f33f6 --- /dev/null +++ b/examples/create-release/create_release.pony @@ -0,0 +1,3 @@ +""" +Example program: create-release. +""" diff --git a/examples/create-release/main.pony b/examples/create-release/main.pony index 1cba030..0e73c91 100644 --- a/examples/create-release/main.pony +++ b/examples/create-release/main.pony @@ -8,11 +8,12 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("create-release", + CommandSpec.leaf( + "create-release", "Create a release", [ - OptionSpec.string("owner", "Owner of the repository the issue is in") - OptionSpec.string("repo", "Name of the repository the issue is in") + OptionSpec.string("owner", "Repository owner") + OptionSpec.string("repo", "Repository name") OptionSpec.string("tag", "Tag for release") OptionSpec.string("name", "Release name") OptionSpec.string("body", "Release notes") @@ -20,13 +21,14 @@ actor Main ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -50,6 +52,9 @@ actor Main end primitive PrintRelease + """ + Prints release results to the given output stream. + """ fun apply(out: OutStream, r: ReleaseOrError) => match \exhaustive\ r | let release: Release => diff --git a/examples/delete-label-oo/delete_label_oo.pony b/examples/delete-label-oo/delete_label_oo.pony new file mode 100644 index 0000000..65eb469 --- /dev/null +++ b/examples/delete-label-oo/delete_label_oo.pony @@ -0,0 +1,3 @@ +""" +Example program: delete-label-oo. +""" diff --git a/examples/delete-label-oo/main.pony b/examples/delete-label-oo/main.pony index 89938fc..96ae435 100644 --- a/examples/delete-label-oo/main.pony +++ b/examples/delete-label-oo/main.pony @@ -9,7 +9,8 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("delete-label-oo", + CommandSpec.leaf( + "delete-label-oo", "Deletes an existing label", [ OptionSpec.string( @@ -21,13 +22,14 @@ actor Main ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -50,15 +52,21 @@ actor Main end primitive RemoveLabel + """ + Removes a label from the repository. + """ fun apply(label: String, r: RepositoryOrError): Promise[DeletedOrError] => match \exhaustive\ r | let repo: Repository => repo.delete_label(label) | let e: RequestError => - Promise[DeletedOrError].>apply(e) + Promise[DeletedOrError] .> apply(e) end primitive PrintResult + """ + Prints the operation result to the given output stream. + """ fun apply(out: OutStream, label: String, d: DeletedOrError) => match \exhaustive\ d | Deleted => diff --git a/examples/delete-label/delete_label.pony b/examples/delete-label/delete_label.pony new file mode 100644 index 0000000..09e0d0b --- /dev/null +++ b/examples/delete-label/delete_label.pony @@ -0,0 +1,3 @@ +""" +Example program: delete-label. +""" diff --git a/examples/delete-label/main.pony b/examples/delete-label/main.pony index d5cefa7..aa05c4c 100644 --- a/examples/delete-label/main.pony +++ b/examples/delete-label/main.pony @@ -8,7 +8,8 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("delete-label", + CommandSpec.leaf( + "delete-label", "Deletes an existing label", [ OptionSpec.string( @@ -20,13 +21,14 @@ actor Main ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -48,6 +50,9 @@ actor Main end primitive PrintResult + """ + Prints the operation result to the given output stream. + """ fun apply(out: OutStream, label: String, d: DeletedOrError) => match \exhaustive\ d | Deleted => diff --git a/examples/get-commit-oo/get_commit_oo.pony b/examples/get-commit-oo/get_commit_oo.pony new file mode 100644 index 0000000..3cc9d9a --- /dev/null +++ b/examples/get-commit-oo/get_commit_oo.pony @@ -0,0 +1,3 @@ +""" +Example program: get-commit-oo. +""" diff --git a/examples/get-commit-oo/main.pony b/examples/get-commit-oo/main.pony index 58a5348..1dea840 100644 --- a/examples/get-commit-oo/main.pony +++ b/examples/get-commit-oo/main.pony @@ -9,25 +9,28 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("get-commit-oo", + CommandSpec.leaf( + "get-commit-oo", "Get a commit", [ - OptionSpec.string("owner", "Owner of the repository the commit is in") - OptionSpec.string("repo", "Name of the repository the commit is in") + OptionSpec.string("owner", "Repository owner") + OptionSpec.string("repo", "Repository name") OptionSpec.string("sha", "Sha of the commit to retrieve") - OptionSpec.string("token", + OptionSpec.string( + "token", "GitHub personal access token" where default' = "") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -50,15 +53,21 @@ actor Main end primitive RetrieveCommit + """ + Retrieves a commit from the repository. + """ fun apply(sha: String, r: RepositoryOrError): Promise[CommitOrError] => match \exhaustive\ r | let repo: Repository => repo.get_commit(sha) | let e: RequestError => - Promise[CommitOrError].>apply(e) + Promise[CommitOrError] .> apply(e) end primitive PrintCommit + """ + Prints commit details to the given output stream. + """ fun apply(out: OutStream, c: CommitOrError) => match \exhaustive\ c | let commit: Commit => diff --git a/examples/get-commit/get_commit.pony b/examples/get-commit/get_commit.pony new file mode 100644 index 0000000..3504d30 --- /dev/null +++ b/examples/get-commit/get_commit.pony @@ -0,0 +1,3 @@ +""" +Example program: get-commit. +""" diff --git a/examples/get-commit/main.pony b/examples/get-commit/main.pony index 2d9f89f..de49e26 100644 --- a/examples/get-commit/main.pony +++ b/examples/get-commit/main.pony @@ -8,25 +8,28 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("get-commit", + CommandSpec.leaf( + "get-commit", "Get a commit", [ - OptionSpec.string("owner", "Owner of the repository the commit is in") - OptionSpec.string("repo", "Name of the repository the commit is in") + OptionSpec.string("owner", "Repository owner") + OptionSpec.string("repo", "Repository name") OptionSpec.string("sha", "Sha of the commit to retrieve") - OptionSpec.string("token", + OptionSpec.string( + "token", "GitHub personal access token" where default' = "") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -48,6 +51,9 @@ actor Main end primitive PrintCommit + """ + Prints commit details to the given output stream. + """ fun apply(out: OutStream, c: CommitOrError) => match \exhaustive\ c | let commit: Commit => diff --git a/examples/get-gist-oo/get_gist_oo.pony b/examples/get-gist-oo/get_gist_oo.pony new file mode 100644 index 0000000..0e2e527 --- /dev/null +++ b/examples/get-gist-oo/get_gist_oo.pony @@ -0,0 +1,3 @@ +""" +Example program: get-gist-oo. +""" diff --git a/examples/get-gist-oo/main.pony b/examples/get-gist-oo/main.pony index c994e0d..82e2749 100644 --- a/examples/get-gist-oo/main.pony +++ b/examples/get-gist-oo/main.pony @@ -8,23 +8,26 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("get-gist-oo", + CommandSpec.leaf( + "get-gist-oo", "Get information about a gist", [ OptionSpec.string("gist-id", "ID of the gist to fetch") - OptionSpec.string("token", + OptionSpec.string( + "token", "GitHub personal access token" where default' = "") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -44,6 +47,9 @@ actor Main end primitive PrintGist + """ + Prints gist details to the given output stream. + """ fun apply(out: OutStream, g: GistOrError) => match \exhaustive\ g | let gist: Gist => diff --git a/examples/get-gist/get_gist.pony b/examples/get-gist/get_gist.pony new file mode 100644 index 0000000..3283de8 --- /dev/null +++ b/examples/get-gist/get_gist.pony @@ -0,0 +1,3 @@ +""" +Example program: get-gist. +""" diff --git a/examples/get-gist/main.pony b/examples/get-gist/main.pony index 9c2951f..8b49a51 100644 --- a/examples/get-gist/main.pony +++ b/examples/get-gist/main.pony @@ -8,23 +8,26 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("get-gist", + CommandSpec.leaf( + "get-gist", "Get information about a gist", [ OptionSpec.string("gist-id", "ID of the gist to fetch") - OptionSpec.string("token", + OptionSpec.string( + "token", "GitHub personal access token" where default' = "") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -44,6 +47,9 @@ actor Main end primitive PrintGist + """ + Prints gist details to the given output stream. + """ fun apply(out: OutStream, g: GistOrError) => match \exhaustive\ g | let gist: Gist => diff --git a/examples/get-issue-comments-oo/get_issue_comments_oo.pony b/examples/get-issue-comments-oo/get_issue_comments_oo.pony new file mode 100644 index 0000000..adfd125 --- /dev/null +++ b/examples/get-issue-comments-oo/get_issue_comments_oo.pony @@ -0,0 +1,3 @@ +""" +Example program: get-issue-comments-oo. +""" diff --git a/examples/get-issue-comments-oo/main.pony b/examples/get-issue-comments-oo/main.pony index ac64680..2d864f2 100644 --- a/examples/get-issue-comments-oo/main.pony +++ b/examples/get-issue-comments-oo/main.pony @@ -9,25 +9,28 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("get-issue-comments-oo", + CommandSpec.leaf( + "get-issue-comments-oo", "Get all comments for an issue", [ - OptionSpec.string("owner", "Owner of the repository the issue is in") - OptionSpec.string("repo", "Name of the repository the issue is in") + OptionSpec.string("owner", "Repository owner") + OptionSpec.string("repo", "Repository name") OptionSpec.i64("issue", "Issue number to get comments for") - OptionSpec.string("token", + OptionSpec.string( + "token", "GitHub personal access token" where default' = "") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -43,32 +46,41 @@ actor Main let creds = Credentials(auth, token) GitHub(creds).get_repo(owner, repo) - .flatten_next[IssueOrError](RetrieveIssue~apply(issue)) - .flatten_next[IssueCommentsOrError](RetrieveComments~apply()) - .next[None](PrintIssueComments~apply(env.out)) + .flatten_next[IssueOrError](RetrieveIssue~apply(issue)) + .flatten_next[IssueCommentsOrError](RetrieveComments~apply()) + .next[None](PrintIssueComments~apply(env.out)) else env.out.print("Something went wrong") end primitive RetrieveIssue + """ + Retrieves an issue from the repository. + """ fun apply(number: I64, r: RepositoryOrError): Promise[IssueOrError] => match \exhaustive\ r | let repo: Repository => repo.get_issue(number) | let e: RequestError => - Promise[IssueOrError].>apply(e) + Promise[IssueOrError] .> apply(e) end primitive RetrieveComments + """ + Retrieves comments from the resource. + """ fun apply(i: IssueOrError): Promise[IssueCommentsOrError] => match \exhaustive\ i | let issue: Issue => issue.get_comments() | let e: RequestError => - Promise[IssueCommentsOrError].>apply(e) + Promise[IssueCommentsOrError] .> apply(e) end primitive PrintIssueComments + """ + Prints issue comments to the given output stream. + """ fun apply(out: OutStream, r: IssueCommentsOrError) => match \exhaustive\ r | let comments: Array[IssueComment] val => diff --git a/examples/get-issue-comments/get_issue_comments.pony b/examples/get-issue-comments/get_issue_comments.pony new file mode 100644 index 0000000..80c3f34 --- /dev/null +++ b/examples/get-issue-comments/get_issue_comments.pony @@ -0,0 +1,3 @@ +""" +Example program: get-issue-comments. +""" diff --git a/examples/get-issue-comments/main.pony b/examples/get-issue-comments/main.pony index 47daad3..c10f9dc 100644 --- a/examples/get-issue-comments/main.pony +++ b/examples/get-issue-comments/main.pony @@ -8,25 +8,28 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("get-issue-comments", + CommandSpec.leaf( + "get-issue-comments", "Get all comments for an issue", [ - OptionSpec.string("owner", "Owner of the repository the issue is in") - OptionSpec.string("repo", "Name of the repository the issue is in") + OptionSpec.string("owner", "Repository owner") + OptionSpec.string("repo", "Repository name") OptionSpec.i64("issue", "Issue number to get comments for") - OptionSpec.string("token", + OptionSpec.string( + "token", "GitHub personal access token" where default' = "") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -48,6 +51,9 @@ actor Main end primitive PrintIssueComments + """ + Prints issue comments to the given output stream. + """ fun apply(out: OutStream, r: IssueCommentsOrError) => match \exhaustive\ r | let comments: Array[IssueComment] val => diff --git a/examples/get-issue-oo/get_issue_oo.pony b/examples/get-issue-oo/get_issue_oo.pony new file mode 100644 index 0000000..79ff814 --- /dev/null +++ b/examples/get-issue-oo/get_issue_oo.pony @@ -0,0 +1,3 @@ +""" +Example program: get-issue-oo. +""" diff --git a/examples/get-issue-oo/main.pony b/examples/get-issue-oo/main.pony index 5c73d0a..37cab4f 100644 --- a/examples/get-issue-oo/main.pony +++ b/examples/get-issue-oo/main.pony @@ -9,25 +9,28 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("get-issue-oo", + CommandSpec.leaf( + "get-issue-oo", "Get an issue", [ - OptionSpec.string("owner", "Owner of the repository the issue is in") - OptionSpec.string("repo", "Name of the repository the issue is in") + OptionSpec.string("owner", "Repository owner") + OptionSpec.string("repo", "Repository name") OptionSpec.i64("issue", "Issue number to retrieve") - OptionSpec.string("token", + OptionSpec.string( + "token", "GitHub personal access token" where default' = "") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -43,22 +46,28 @@ actor Main let creds = Credentials(auth, token) GitHub(creds).get_repo(owner, repo) - .flatten_next[IssueOrError](RetrieveIssue~apply(issue)) - .next[None](PrintIssue~apply(env.out)) + .flatten_next[IssueOrError](RetrieveIssue~apply(issue)) + .next[None](PrintIssue~apply(env.out)) else env.out.print("Something went wrong") end primitive RetrieveIssue + """ + Retrieves an issue from the repository. + """ fun apply(number: I64, r: RepositoryOrError): Promise[IssueOrError] => match \exhaustive\ r | let repo: Repository => repo.get_issue(number) | let e: RequestError => - Promise[IssueOrError].>apply(e) + Promise[IssueOrError] .> apply(e) end primitive PrintIssue + """ + Prints issue details to the given output stream. + """ fun apply(out: OutStream, i: IssueOrError) => match \exhaustive\ i | let issue: Issue => diff --git a/examples/get-issue/get_issue.pony b/examples/get-issue/get_issue.pony new file mode 100644 index 0000000..aaa9cb7 --- /dev/null +++ b/examples/get-issue/get_issue.pony @@ -0,0 +1,3 @@ +""" +Example program: get-issue. +""" diff --git a/examples/get-issue/main.pony b/examples/get-issue/main.pony index 5267db1..26d660e 100644 --- a/examples/get-issue/main.pony +++ b/examples/get-issue/main.pony @@ -8,25 +8,28 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("get-issue", + CommandSpec.leaf( + "get-issue", "Get an issue", [ - OptionSpec.string("owner", "Owner of the repository the issue is in") - OptionSpec.string("repo", "Name of the repository the issue is in") + OptionSpec.string("owner", "Repository owner") + OptionSpec.string("repo", "Repository name") OptionSpec.i64("issue", "Issue number to retrieve") - OptionSpec.string("token", + OptionSpec.string( + "token", "GitHub personal access token" where default' = "") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -48,6 +51,9 @@ actor Main end primitive PrintIssue + """ + Prints issue details to the given output stream. + """ fun apply(out: OutStream, i: IssueOrError) => match \exhaustive\ i | let issue: Issue => diff --git a/examples/get-issues-oo/get_issues_oo.pony b/examples/get-issues-oo/get_issues_oo.pony new file mode 100644 index 0000000..1957056 --- /dev/null +++ b/examples/get-issues-oo/get_issues_oo.pony @@ -0,0 +1,3 @@ +""" +Example program: get-issues-oo. +""" diff --git a/examples/get-issues-oo/main.pony b/examples/get-issues-oo/main.pony index f47d632..61220c9 100644 --- a/examples/get-issues-oo/main.pony +++ b/examples/get-issues-oo/main.pony @@ -9,42 +9,51 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("get-issues-oo", + CommandSpec.leaf( + "get-issues-oo", "List issues in a repository", [ OptionSpec.string("owner", "Owner of the repository") OptionSpec.string("repo", "Name of the repository") - OptionSpec.string("token", + OptionSpec.string( + "token", "GitHub personal access token" where default' = "") - OptionSpec.string("labels", + OptionSpec.string( + "labels", "Comma-separated label names to filter by" where default' = "") - OptionSpec.string("state", + OptionSpec.string( + "state", "Issue state: open, closed, or all" where default' = "open") - OptionSpec.string("sort", + OptionSpec.string( + "sort", "Sort field: created, updated, or comments" where default' = "created") - OptionSpec.string("direction", + OptionSpec.string( + "direction", "Sort direction: asc or desc" where default' = "desc") - OptionSpec.string("since", + OptionSpec.string( + "since", "Only issues updated at or after this ISO 8601 timestamp" where default' = "") - OptionSpec.i64("per-page", + OptionSpec.i64( + "per-page", "Results per page (1-100, default 30)" where default' = 0) ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -60,22 +69,25 @@ actor Main let since = cmd.option("since").string() let per_page_i = cmd.option("per-page").i64() - let sort: IssueSort = match sort_str - | "updated" => SortByUpdated - | "comments" => SortByComments + let sort: IssueSort = + match sort_str + | "updated" => SortByUpdated + | "comments" => SortByComments else SortByCreated end - let direction: SortDirection = match direction_str - | "asc" => SortAscending + let direction: SortDirection = + match direction_str + | "asc" => SortAscending else SortDescending end - let per_page: (I64 | None) = if per_page_i > 0 then + let per_page: (I64 | None) = + if per_page_i > 0 then per_page_i - else + else None - end + end // ----- Get issues let auth = lori.TCPConnectAuth(env.root) @@ -83,7 +95,12 @@ actor Main GitHub(creds).get_repo(owner, repo) .flatten_next[(PaginatedList[Issue] | RequestError)]( - RetrieveIssues~apply(labels, state, sort, direction, since, + RetrieveIssues~apply( + labels, + state, + sort, + direction, + since, per_page)) .next[None](PrintIssues~apply(env.out)) else @@ -91,6 +108,9 @@ actor Main end primitive RetrieveIssues + """ + Retrieves issues from the repository. + """ fun apply(labels: String, state: String, sort: IssueSort, @@ -104,18 +124,22 @@ primitive RetrieveIssues | let repo: Repository => repo.get_issues(labels, state, sort, direction, since, per_page) | let e: RequestError => - Promise[(PaginatedList[Issue] | RequestError)].>apply(e) + Promise[(PaginatedList[Issue] | RequestError)] .> apply(e) end primitive PrintIssues + """ + Prints a list of issues to the given output stream. + """ fun apply(out: OutStream, r: (PaginatedList[Issue] | RequestError)) => match \exhaustive\ r | let list: PaginatedList[Issue] => for issue in list.results.values() do - let state = match issue.state - | let s: String => s + let state = + match issue.state + | let s: String => s else "unknown" end out.print( diff --git a/examples/get-issues/get_issues.pony b/examples/get-issues/get_issues.pony new file mode 100644 index 0000000..11d9156 --- /dev/null +++ b/examples/get-issues/get_issues.pony @@ -0,0 +1,3 @@ +""" +Example program: get-issues. +""" diff --git a/examples/get-issues/main.pony b/examples/get-issues/main.pony index 5f2d003..8d28c01 100644 --- a/examples/get-issues/main.pony +++ b/examples/get-issues/main.pony @@ -9,42 +9,51 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("get-issues", + CommandSpec.leaf( + "get-issues", "List issues in a repository", [ OptionSpec.string("owner", "Owner of the repository") OptionSpec.string("repo", "Name of the repository") - OptionSpec.string("token", + OptionSpec.string( + "token", "GitHub personal access token" where default' = "") - OptionSpec.string("labels", + OptionSpec.string( + "labels", "Comma-separated label names to filter by" where default' = "") - OptionSpec.string("state", + OptionSpec.string( + "state", "Issue state: open, closed, or all" where default' = "open") - OptionSpec.string("sort", + OptionSpec.string( + "sort", "Sort field: created, updated, or comments" where default' = "created") - OptionSpec.string("direction", + OptionSpec.string( + "direction", "Sort direction: asc or desc" where default' = "desc") - OptionSpec.string("since", + OptionSpec.string( + "since", "Only issues updated at or after this ISO 8601 timestamp" where default' = "") - OptionSpec.i64("per-page", + OptionSpec.i64( + "per-page", "Results per page (1-100, default 30)" where default' = 0) ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -60,28 +69,33 @@ actor Main let since = cmd.option("since").string() let per_page_i = cmd.option("per-page").i64() - let sort: IssueSort = match sort_str - | "updated" => SortByUpdated - | "comments" => SortByComments + let sort: IssueSort = + match sort_str + | "updated" => SortByUpdated + | "comments" => SortByComments else SortByCreated end - let direction: SortDirection = match direction_str - | "asc" => SortAscending + let direction: SortDirection = + match direction_str + | "asc" => SortAscending else SortDescending end - let per_page: (I64 | None) = if per_page_i > 0 then + let per_page: (I64 | None) = + if per_page_i > 0 then per_page_i - else + else None - end + end // ----- Get issues let auth = lori.TCPConnectAuth(env.root) let creds = Credentials(auth, token) - let p = GetRepositoryIssues(owner, repo, creds + let p = + GetRepositoryIssues( + owner, repo, creds where labels = labels, state = state, sort = sort, @@ -94,14 +108,18 @@ actor Main end primitive PrintIssues + """ + Prints a list of issues to the given output stream. + """ fun apply(out: OutStream, r: (PaginatedList[Issue] | RequestError)) => match \exhaustive\ r | let list: PaginatedList[Issue] => for issue in list.results.values() do - let state = match issue.state - | let s: String => s + let state = + match issue.state + | let s: String => s else "unknown" end out.print( diff --git a/examples/get-pull-request-files-oo/get_pull_request_files_oo.pony b/examples/get-pull-request-files-oo/get_pull_request_files_oo.pony new file mode 100644 index 0000000..434c699 --- /dev/null +++ b/examples/get-pull-request-files-oo/get_pull_request_files_oo.pony @@ -0,0 +1,3 @@ +""" +Example program: get-pull-request-files-oo. +""" diff --git a/examples/get-pull-request-files-oo/main.pony b/examples/get-pull-request-files-oo/main.pony index d102d29..5b528b5 100644 --- a/examples/get-pull-request-files-oo/main.pony +++ b/examples/get-pull-request-files-oo/main.pony @@ -9,25 +9,28 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("get-pull-request-files-oo", + CommandSpec.leaf( + "get-pull-request-files-oo", "Get all files for a pull request", [ - OptionSpec.string("owner", "Owner of the repository the issue is in") - OptionSpec.string("repo", "Name of the repository the issue is in") + OptionSpec.string("owner", "Repository owner") + OptionSpec.string("repo", "Repository name") OptionSpec.i64("pr", "Pullrequest number to get files for") - OptionSpec.string("token", + OptionSpec.string( + "token", "GitHub personal access token" where default' = "") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -43,32 +46,41 @@ actor Main let creds = Credentials(auth, token) GitHub(creds).get_repo(owner, repo) - .flatten_next[PullRequestOrError](RetrievePullRequest~apply(pr)) - .flatten_next[PullRequestFilesOrError](RetrievePullReqestFiles~apply()) - .next[None](PrintPullRequestFiles~apply(env.out)) + .flatten_next[PullRequestOrError](RetrievePullRequest~apply(pr)) + .flatten_next[PullRequestFilesOrError](RetrievePullReqestFiles~apply()) + .next[None](PrintPullRequestFiles~apply(env.out)) else env.out.print("Something went wrong") end primitive RetrievePullRequest + """ + Retrieves a pull request from the repository. + """ fun apply(number: I64, r: RepositoryOrError): Promise[PullRequestOrError] => match \exhaustive\ r | let repo: Repository => repo.get_pull_request(number) | let e: RequestError => - Promise[PullRequestOrError].>apply(e) + Promise[PullRequestOrError] .> apply(e) end primitive RetrievePullReqestFiles + """ + Retrieves files changed in the pull request. + """ fun apply(p: PullRequestOrError): Promise[PullRequestFilesOrError] => match \exhaustive\ p | let pr: PullRequest => pr.get_files() | let e: RequestError => - Promise[PullRequestFilesOrError].>apply(e) + Promise[PullRequestFilesOrError] .> apply(e) end primitive PrintPullRequestFiles + """ + Prints pull request files to the given output stream. + """ fun apply(out: OutStream, r: PullRequestFilesOrError) => match \exhaustive\ r | let files: Array[PullRequestFile] val => diff --git a/examples/get-pull-request-files/get_pull_request_files.pony b/examples/get-pull-request-files/get_pull_request_files.pony new file mode 100644 index 0000000..7d4d123 --- /dev/null +++ b/examples/get-pull-request-files/get_pull_request_files.pony @@ -0,0 +1,3 @@ +""" +Example program: get-pull-request-files. +""" diff --git a/examples/get-pull-request-files/main.pony b/examples/get-pull-request-files/main.pony index 86abf35..4f871bd 100644 --- a/examples/get-pull-request-files/main.pony +++ b/examples/get-pull-request-files/main.pony @@ -8,25 +8,28 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("get-pull-request-files", + CommandSpec.leaf( + "get-pull-request-files", "Get all files for a pull request", [ - OptionSpec.string("owner", "Owner of the repository the issue is in") - OptionSpec.string("repo", "Name of the repository the issue is in") + OptionSpec.string("owner", "Repository owner") + OptionSpec.string("repo", "Repository name") OptionSpec.i64("pr", "Pullrequest number to get files for") - OptionSpec.string("token", + OptionSpec.string( + "token", "GitHub personal access token" where default' = "") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -48,6 +51,9 @@ actor Main end primitive PrintPullRequestFiles + """ + Prints pull request files to the given output stream. + """ fun apply(out: OutStream, r: PullRequestFilesOrError) => match \exhaustive\ r | let files: Array[PullRequestFile] val => diff --git a/examples/get-pull-request-oo/get_pull_request_oo.pony b/examples/get-pull-request-oo/get_pull_request_oo.pony new file mode 100644 index 0000000..85ce1bd --- /dev/null +++ b/examples/get-pull-request-oo/get_pull_request_oo.pony @@ -0,0 +1,3 @@ +""" +Example program: get-pull-request-oo. +""" diff --git a/examples/get-pull-request-oo/main.pony b/examples/get-pull-request-oo/main.pony index 1f618af..0ed887f 100644 --- a/examples/get-pull-request-oo/main.pony +++ b/examples/get-pull-request-oo/main.pony @@ -9,25 +9,28 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("get-pull-request-oo", + CommandSpec.leaf( + "get-pull-request-oo", "Get pull request", [ - OptionSpec.string("owner", "Owner of the repository the issue is in") - OptionSpec.string("repo", "Name of the repository the issue is in") + OptionSpec.string("owner", "Repository owner") + OptionSpec.string("repo", "Repository name") OptionSpec.i64("pr", "Pull request number to retrieve") - OptionSpec.string("token", + OptionSpec.string( + "token", "GitHub personal access token" where default' = "") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -43,8 +46,8 @@ actor Main let creds = Credentials(auth, token) GitHub(creds).get_repo(owner, repo) - .flatten_next[PullRequestOrError](RetrievePullRequest~apply(pr)) - .next[None](PrintPullRequest~apply(env.out)) + .flatten_next[PullRequestOrError](RetrievePullRequest~apply(pr)) + .next[None](PrintPullRequest~apply(env.out)) let p = GetPullRequest(owner, repo, pr, creds) p.next[None](PrintPullRequest~apply(env.out)) @@ -53,15 +56,21 @@ actor Main end primitive RetrievePullRequest + """ + Retrieves a pull request from the repository. + """ fun apply(number: I64, r: RepositoryOrError): Promise[PullRequestOrError] => match \exhaustive\ r | let repo: Repository => repo.get_pull_request(number) | let e: RequestError => - Promise[PullRequestOrError].>apply(e) + Promise[PullRequestOrError] .> apply(e) end primitive PrintPullRequest + """ + Prints pull request details to the given output stream. + """ fun apply(out: OutStream, p: PullRequestOrError) => match \exhaustive\ p | let pr: PullRequest => diff --git a/examples/get-pull-request/get_pull_request.pony b/examples/get-pull-request/get_pull_request.pony new file mode 100644 index 0000000..8cbc82c --- /dev/null +++ b/examples/get-pull-request/get_pull_request.pony @@ -0,0 +1,3 @@ +""" +Example program: get-pull-request. +""" diff --git a/examples/get-pull-request/main.pony b/examples/get-pull-request/main.pony index 8e31597..d32c656 100644 --- a/examples/get-pull-request/main.pony +++ b/examples/get-pull-request/main.pony @@ -8,25 +8,28 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("get-pull-request", + CommandSpec.leaf( + "get-pull-request", "Get pull request", [ - OptionSpec.string("owner", "Owner of the repository the issue is in") - OptionSpec.string("repo", "Name of the repository the issue is in") + OptionSpec.string("owner", "Repository owner") + OptionSpec.string("repo", "Repository name") OptionSpec.i64("pr", "Pull request number to retrieve") - OptionSpec.string("token", + OptionSpec.string( + "token", "GitHub personal access token" where default' = "") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -48,6 +51,9 @@ actor Main end primitive PrintPullRequest + """ + Prints pull request details to the given output stream. + """ fun apply(out: OutStream, p: PullRequestOrError) => match \exhaustive\ p | let pr: PullRequest => diff --git a/examples/get-repository-labels/get_repository_labels.pony b/examples/get-repository-labels/get_repository_labels.pony new file mode 100644 index 0000000..a53cdb1 --- /dev/null +++ b/examples/get-repository-labels/get_repository_labels.pony @@ -0,0 +1,3 @@ +""" +Example program: get-repository-labels. +""" diff --git a/examples/get-repository-labels/main.pony b/examples/get-repository-labels/main.pony index 16300f9..aef8c76 100644 --- a/examples/get-repository-labels/main.pony +++ b/examples/get-repository-labels/main.pony @@ -9,24 +9,27 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("get-repository-labels", + CommandSpec.leaf( + "get-repository-labels", "Get all labels for a repository", [ - OptionSpec.string("owner", "Owner of the repository the issue is in") - OptionSpec.string("repo", "Name of the repository the issue is in") - OptionSpec.string("token", + OptionSpec.string("owner", "Repository owner") + OptionSpec.string("repo", "Repository name") + OptionSpec.string( + "token", "GitHub personal access token" where default' = "") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -47,6 +50,9 @@ actor Main end primitive PrintRepositoryLabels + """ + Prints repository labels to the given output stream. + """ fun apply(out: OutStream, l: (PaginatedList[Label] | RequestError)) => match \exhaustive\ l | let pl: PaginatedList[Label] => diff --git a/examples/get-repository-oo/get_repository_oo.pony b/examples/get-repository-oo/get_repository_oo.pony new file mode 100644 index 0000000..46f9586 --- /dev/null +++ b/examples/get-repository-oo/get_repository_oo.pony @@ -0,0 +1,3 @@ +""" +Example program: get-repository-oo. +""" diff --git a/examples/get-repository-oo/main.pony b/examples/get-repository-oo/main.pony index 0a82411..fc0697b 100644 --- a/examples/get-repository-oo/main.pony +++ b/examples/get-repository-oo/main.pony @@ -8,24 +8,27 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("get-repository-oo", + CommandSpec.leaf( + "get-repository-oo", "Get information about a repository", [ - OptionSpec.string("owner", "Owner of the repository the issue is in") - OptionSpec.string("repo", "Name of the repository the issue is in") - OptionSpec.string("token", + OptionSpec.string("owner", "Repository owner") + OptionSpec.string("repo", "Repository name") + OptionSpec.string( + "token", "GitHub personal access token" where default' = "") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -46,6 +49,9 @@ actor Main end primitive PrintRepository + """ + Prints repository details to the given output stream. + """ fun apply(out: OutStream, c: RepositoryOrError) => match \exhaustive\ c | let repo: Repository => diff --git a/examples/get-repository/get_repository.pony b/examples/get-repository/get_repository.pony new file mode 100644 index 0000000..f4042f3 --- /dev/null +++ b/examples/get-repository/get_repository.pony @@ -0,0 +1,3 @@ +""" +Example program: get-repository. +""" diff --git a/examples/get-repository/main.pony b/examples/get-repository/main.pony index a260f40..9829820 100644 --- a/examples/get-repository/main.pony +++ b/examples/get-repository/main.pony @@ -8,24 +8,27 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("get-repository", + CommandSpec.leaf( + "get-repository", "Get information about a repository", [ - OptionSpec.string("owner", "Owner of the repository the issue is in") - OptionSpec.string("repo", "Name of the repository the issue is in") - OptionSpec.string("token", + OptionSpec.string("owner", "Repository owner") + OptionSpec.string("repo", "Repository name") + OptionSpec.string( + "token", "GitHub personal access token" where default' = "") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -46,6 +49,9 @@ actor Main end primitive PrintRepository + """ + Prints repository details to the given output stream. + """ fun apply(out: OutStream, c: RepositoryOrError) => match \exhaustive\ c | let repo: Repository => diff --git a/examples/gist-comments-oo/gist_comments_oo.pony b/examples/gist-comments-oo/gist_comments_oo.pony new file mode 100644 index 0000000..101e28a --- /dev/null +++ b/examples/gist-comments-oo/gist_comments_oo.pony @@ -0,0 +1,3 @@ +""" +Example program: gist-comments-oo. +""" diff --git a/examples/gist-comments-oo/main.pony b/examples/gist-comments-oo/main.pony index dfd1276..6ab48f6 100644 --- a/examples/gist-comments-oo/main.pony +++ b/examples/gist-comments-oo/main.pony @@ -9,23 +9,26 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("gist-comments-oo", + CommandSpec.leaf( + "gist-comments-oo", "List comments on a gist", [ OptionSpec.string("gist-id", "ID of the gist") - OptionSpec.string("token", + OptionSpec.string( + "token", "GitHub personal access token" where default' = "") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -47,6 +50,9 @@ actor Main end primitive RetrieveComments + """ + Retrieves comments from the resource. + """ fun apply(g: GistOrError) : Promise[(PaginatedList[GistComment] | RequestError)] => @@ -54,10 +60,13 @@ primitive RetrieveComments | let gist: Gist => gist.get_comments() | let e: RequestError => - Promise[(PaginatedList[GistComment] | RequestError)].>apply(e) + Promise[(PaginatedList[GistComment] | RequestError)] .> apply(e) end primitive PrintComments + """ + Prints comments to the given output stream. + """ fun apply(out: OutStream, r: (PaginatedList[GistComment] | RequestError)) => diff --git a/examples/gist-comments/gist_comments.pony b/examples/gist-comments/gist_comments.pony new file mode 100644 index 0000000..f7fbc06 --- /dev/null +++ b/examples/gist-comments/gist_comments.pony @@ -0,0 +1,3 @@ +""" +Example program: gist-comments. +""" diff --git a/examples/gist-comments/main.pony b/examples/gist-comments/main.pony index 237e218..3d46d3c 100644 --- a/examples/gist-comments/main.pony +++ b/examples/gist-comments/main.pony @@ -9,23 +9,26 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("gist-comments", + CommandSpec.leaf( + "gist-comments", "List comments on a gist", [ OptionSpec.string("gist-id", "ID of the gist") - OptionSpec.string("token", + OptionSpec.string( + "token", "GitHub personal access token" where default' = "") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -45,6 +48,9 @@ actor Main end primitive PrintComments + """ + Prints comments to the given output stream. + """ fun apply(out: OutStream, r: (PaginatedList[GistComment] | RequestError)) => diff --git a/examples/list-gists-oo/list_gists_oo.pony b/examples/list-gists-oo/list_gists_oo.pony new file mode 100644 index 0000000..10f517c --- /dev/null +++ b/examples/list-gists-oo/list_gists_oo.pony @@ -0,0 +1,3 @@ +""" +Example program: list-gists-oo. +""" diff --git a/examples/list-gists-oo/main.pony b/examples/list-gists-oo/main.pony index d41d247..a2c0d9a 100644 --- a/examples/list-gists-oo/main.pony +++ b/examples/list-gists-oo/main.pony @@ -9,20 +9,22 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("list-gists-oo", + CommandSpec.leaf( + "list-gists-oo", "List the authenticated user's gists", [ OptionSpec.string("token", "GitHub personal access token") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -41,14 +43,18 @@ actor Main end primitive PrintGists + """ + Prints a list of gists to the given output stream. + """ fun apply(out: OutStream, r: (PaginatedList[Gist] | RequestError)) => match \exhaustive\ r | let list: PaginatedList[Gist] => for gist in list.results.values() do - let desc = match gist.description - | let d: String => d + let desc = + match gist.description + | let d: String => d else "(no description)" end out.print(gist.id + " - " + desc) diff --git a/examples/list-gists/list_gists.pony b/examples/list-gists/list_gists.pony new file mode 100644 index 0000000..74220d7 --- /dev/null +++ b/examples/list-gists/list_gists.pony @@ -0,0 +1,3 @@ +""" +Example program: list-gists. +""" diff --git a/examples/list-gists/main.pony b/examples/list-gists/main.pony index c4ad197..21adbdf 100644 --- a/examples/list-gists/main.pony +++ b/examples/list-gists/main.pony @@ -9,20 +9,22 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("list-gists", + CommandSpec.leaf( + "list-gists", "List the authenticated user's gists", [ OptionSpec.string("token", "GitHub personal access token") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -41,14 +43,18 @@ actor Main end primitive PrintGists + """ + Prints a list of gists to the given output stream. + """ fun apply(out: OutStream, r: (PaginatedList[Gist] | RequestError)) => match \exhaustive\ r | let list: PaginatedList[Gist] => for gist in list.results.values() do - let desc = match gist.description - | let d: String => d + let desc = + match gist.description + | let d: String => d else "(no description)" end out.print(gist.id + " - " + desc) diff --git a/examples/search-issues/main.pony b/examples/search-issues/main.pony index 05515cf..4ef0ac5 100644 --- a/examples/search-issues/main.pony +++ b/examples/search-issues/main.pony @@ -9,23 +9,26 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("search-issues", + CommandSpec.leaf( + "search-issues", "Search issues", [ OptionSpec.string("query", "Query string") - OptionSpec.string("token", + OptionSpec.string( + "token", "GitHub personal access token" where default' = "") ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -45,6 +48,9 @@ actor Main end primitive PrintResults + """ + Prints search results to the given output stream. + """ fun apply(out: OutStream, r: IssueSearchResultsOrError) => match \exhaustive\ r | let results: SearchResults[Issue] => diff --git a/examples/search-issues/search_issues.pony b/examples/search-issues/search_issues.pony new file mode 100644 index 0000000..058b07b --- /dev/null +++ b/examples/search-issues/search_issues.pony @@ -0,0 +1,3 @@ +""" +Example program: search-issues. +""" diff --git a/examples/standard-pony-labels/main.pony b/examples/standard-pony-labels/main.pony index c5eca48..01cc156 100644 --- a/examples/standard-pony-labels/main.pony +++ b/examples/standard-pony-labels/main.pony @@ -9,7 +9,8 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("standard-pony-labels", + CommandSpec.leaf( + "standard-pony-labels", "Deletes all labels in a repo and creates the standard ponylang ones", [ OptionSpec.string( @@ -20,13 +21,14 @@ actor Main ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -47,6 +49,9 @@ actor Main end primitive RemoveLabels + """ + Removes existing labels from the repository. + """ fun apply(out: OutStream, owner: String, repo: String, @@ -65,7 +70,8 @@ primitive RemoveLabels out.print("Deleting " + label.name + " label") DeleteLabel(owner, repo, label.name, creds) - .next[None](NotifyLabelDeleted~apply(out, + .next[None](NotifyLabelDeleted~apply( + out, owner, repo, creds, @@ -86,6 +92,9 @@ primitive RemoveLabels end primitive NotifyLabelDeleted + """ + Handles a label deletion notification. + """ fun apply(out: OutStream, owner: String, repo: String, @@ -108,25 +117,43 @@ primitive NotifyLabelDeleted end primitive CreatePonyLabels + """ + Creates the standard set of Pony project labels. + """ fun apply(out: OutStream, owner: String, repo: String, creds: Credentials) => - let standard_pony_labels: Array[(String, String, String)] val = [ + let standard_pony_labels: Array[(String, String, String)] val = + [ ("bug", "f7c6c7", "Something isn't working") - ("changelog - added", "ffaa55", "Automatically add \"Added\" CHANGELOG entry on merge") - ("changelog - changed", "ff7755", "Automatically add \"Changed\" CHANGELOG entry on merge") - ("changelog - fixed", "77aa55", "Automatically add \"Fixed\" CHANGELOG entry on merge") - ("do not merge", "d93f0b", "This PR should not be merged at this time") - ("documentation", "0075ca", "Improvements or additions to documentation") - ("enhancement", "a2eeef", "New feature or request") - ("good first issue", "7057ff", "Good for newcomers") - ("help wanted", "008672", "Extra attention is needed") - ("needs discussion", "ffffdd", "Needs to be discussed further") - ("needs investigation", "D3D3D3", "This needs to be looked into before it's \"ready for work\"") - ("triggers release", "006b75", "Major issue that when fixed, results in an \"emergency\" release") - ("discuss during sync", "CC1F71", "Should be discussed during an upcoming sync") + ("changelog - added", "ffaa55", + "Automatically add \"Added\" CHANGELOG entry on merge") + ("changelog - changed", "ff7755", + "Automatically add \"Changed\" CHANGELOG entry on merge") + ("changelog - fixed", "77aa55", + "Automatically add \"Fixed\" CHANGELOG entry on merge") + ("do not merge", "d93f0b", + "This PR should not be merged at this time") + ("documentation", "0075ca", + "Improvements or additions to documentation") + ("enhancement", "a2eeef", + "New feature or request") + ("good first issue", "7057ff", + "Good for newcomers") + ("help wanted", "008672", + "Extra attention is needed") + ("needs discussion", "ffffdd", + "Needs to be discussed further") + ("needs investigation", "D3D3D3", + "This needs to be looked into before " + + "it's \"ready for work\"") + ("triggers release", "006b75", + "Major issue that when fixed, results " + + "in an \"emergency\" release") + ("discuss during sync", "CC1F71", + "Should be discussed during an upcoming sync") ] for label in standard_pony_labels.values() do @@ -135,6 +162,9 @@ primitive CreatePonyLabels end primitive NotifyLabelCreated + """ + Handles a label creation notification. + """ fun apply(out: OutStream, label: String, l: LabelOrError) => match \exhaustive\ l | let l': Label => diff --git a/examples/standard-pony-labels/standard_pony_labels.pony b/examples/standard-pony-labels/standard_pony_labels.pony new file mode 100644 index 0000000..f5f91f0 --- /dev/null +++ b/examples/standard-pony-labels/standard_pony_labels.pony @@ -0,0 +1,3 @@ +""" +Example program: standard-pony-labels. +""" diff --git a/examples/star-gist-oo/main.pony b/examples/star-gist-oo/main.pony index 0b1dee3..c283e42 100644 --- a/examples/star-gist-oo/main.pony +++ b/examples/star-gist-oo/main.pony @@ -9,7 +9,8 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("star-gist-oo", + CommandSpec.leaf( + "star-gist-oo", "Star a gist and then check if it is starred", [ OptionSpec.string("gist-id", "ID of the gist to star") @@ -17,13 +18,14 @@ actor Main ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -45,27 +47,36 @@ actor Main end primitive StarIt + """ + Stars a gist. + """ fun apply(g: GistOrError): Promise[DeletedOrError] => match \exhaustive\ g | let gist: Gist => gist.star() | let e: RequestError => - Promise[DeletedOrError].>apply(e) + Promise[DeletedOrError] .> apply(e) end primitive CheckIt + """ + Checks the star status of a gist. + """ fun apply(d: DeletedOrError): Promise[BoolOrError] => match \exhaustive\ d | Deleted => // Star succeeded. We can't call is_starred() here because we don't // have the Gist reference in this chain step. In real code, keep the // Gist accessible or use the functional API (see star-gist example). - Promise[BoolOrError].>apply(true) + Promise[BoolOrError] .> apply(true) | let e: RequestError => - Promise[BoolOrError].>apply(e) + Promise[BoolOrError] .> apply(e) end primitive PrintResult + """ + Prints the operation result to the given output stream. + """ fun apply(out: OutStream, r: BoolOrError) => match \exhaustive\ r | let starred: Bool => diff --git a/examples/star-gist-oo/star_gist_oo.pony b/examples/star-gist-oo/star_gist_oo.pony new file mode 100644 index 0000000..81139e0 --- /dev/null +++ b/examples/star-gist-oo/star_gist_oo.pony @@ -0,0 +1,3 @@ +""" +Example program: star-gist-oo. +""" diff --git a/examples/star-gist/main.pony b/examples/star-gist/main.pony index 79e77ce..506acd0 100644 --- a/examples/star-gist/main.pony +++ b/examples/star-gist/main.pony @@ -9,7 +9,8 @@ actor Main try // ----- CLI setup let cs = - CommandSpec.leaf("star-gist", + CommandSpec.leaf( + "star-gist", "Star a gist and then check if it is starred", [ OptionSpec.string("gist-id", "ID of the gist to star") @@ -17,13 +18,14 @@ actor Main ] )? .> add_help()? - let cmd = match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) - | let c: Command => + let cmd = + match \exhaustive\ CommandParser(cs).parse(env.args, env.vars) + | let c: Command => c - | let ch: CommandHelp => + | let ch: CommandHelp => ch.print_help(env.out) return - | let se: SyntaxError => + | let se: SyntaxError => env.err.print(se.string()) env.exitcode(1) return @@ -45,6 +47,9 @@ actor Main end primitive CheckStar + """ + Checks whether a gist is starred. + """ fun apply(gist_id: String, creds: Credentials, d: DeletedOrError): Promise[BoolOrError] @@ -53,10 +58,13 @@ primitive CheckStar | Deleted => CheckGistStar(gist_id, creds) | let e: RequestError => - Promise[BoolOrError].>apply(e) + Promise[BoolOrError] .> apply(e) end primitive PrintResult + """ + Prints the operation result to the given output stream. + """ fun apply(out: OutStream, r: BoolOrError) => match \exhaustive\ r | let starred: Bool => diff --git a/examples/star-gist/star_gist.pony b/examples/star-gist/star_gist.pony new file mode 100644 index 0000000..06c29af --- /dev/null +++ b/examples/star-gist/star_gist.pony @@ -0,0 +1,3 @@ +""" +Example program: star-gist. +""" diff --git a/github_rest_api/_test.pony b/github_rest_api/_test.pony index 8411d9f..e491df7 100644 --- a/github_rest_api/_test.pony +++ b/github_rest_api/_test.pony @@ -15,41 +15,41 @@ actor \nodoc\ Main is TestList test(_TestExtractPaginationLinksFirstPage) test(_TestExtractPaginationLinksLastPage) test(_TestExtractPaginationLinksBetweenPages) - test(_TestGitPersonJsonConverterPreservesValues) - test(_TestGitPersonJsonConverterMissingField) - test(_TestLicenseJsonConverterPreservesValues) - test(_TestLicenseJsonConverterMissingField) - test(_TestCommitFileJsonConverterPreservesValues) - test(_TestCommitFileJsonConverterMissingField) - test(_TestGistChangeStatusJsonConverterPreservesValues) - test(_TestGistChangeStatusJsonConverterMissingField) - test(_TestLabelJsonConverterPreservesValues) - test(_TestLabelJsonConverterMissingField) - test(_TestIssuePRJsonConverterPreservesValues) - test(_TestIssuePRJsonConverterMissingField) - test(_TestAssetJsonConverterPreservesValues) - test(_TestAssetJsonConverterMissingField) - test(_TestGistFileJsonConverterPreservesValues) - test(_TestGistFileJsonConverterMissingField) - test(_TestGistFileJsonConverterAbsentOptionalFields) - test(_TestGitCommitJsonConverterPreservesValues) - test(_TestGitCommitJsonConverterMissingField) - test(_TestCommitJsonConverterPreservesValues) - test(_TestCommitJsonConverterMissingField) - test(_TestIssueJsonConverterPreservesValues) - test(_TestIssueJsonConverterMissingField) - test(_TestIssueJsonConverterAbsentPullRequest) - test(_TestRepoJsonConverterPreservesValues) - test(_TestRepoJsonConverterMissingField) - test(_TestRepoJsonConverterAbsentOptionalFields) - test(_TestGistJsonConverterPreservesValues) - test(_TestGistJsonConverterMissingField) - test(_TestGistJsonConverterAbsentOptionalFields) + test(_TestGitPersonJSONConverterPreservesValues) + test(_TestGitPersonJSONConverterMissingField) + test(_TestLicenseJSONConverterPreservesValues) + test(_TestLicenseJSONConverterMissingField) + test(_TestCommitFileJSONConverterPreservesValues) + test(_TestCommitFileJSONConverterMissingField) + test(_TestGistChangeStatusJSONConverterPreservesValues) + test(_TestGistChangeStatusJSONConverterMissingField) + test(_TestLabelJSONConverterPreservesValues) + test(_TestLabelJSONConverterMissingField) + test(_TestIssuePRJSONConverterPreservesValues) + test(_TestIssuePRJSONConverterMissingField) + test(_TestAssetJSONConverterPreservesValues) + test(_TestAssetJSONConverterMissingField) + test(_TestGistFileJSONConverterPreservesValues) + test(_TestGistFileJSONConverterMissingField) + test(_TestGistFileJSONConverterAbsentOptionalFields) + test(_TestGitCommitJSONConverterPreservesValues) + test(_TestGitCommitJSONConverterMissingField) + test(_TestCommitJSONConverterPreservesValues) + test(_TestCommitJSONConverterMissingField) + test(_TestIssueJSONConverterPreservesValues) + test(_TestIssueJSONConverterMissingField) + test(_TestIssueJSONConverterAbsentPullRequest) + test(_TestRepoJSONConverterPreservesValues) + test(_TestRepoJSONConverterMissingField) + test(_TestRepoJSONConverterAbsentOptionalFields) + test(_TestGistJSONConverterPreservesValues) + test(_TestGistJSONConverterMissingField) + test(_TestGistJSONConverterAbsentOptionalFields) test(_TestStringOrNoneReturnsString) test(_TestStringOrNoneReturnsNone) test(_TestStringOrNoneRaisesOnInvalid) - test(_TestJsonTypeStringAllArms) - test(_TestJsonTypeStringI64Property) + test(_TestJSONTypeStringAllArms) + test(_TestJSONTypeStringI64Property) test(_TestDeletedResultReceiverSuccess) test(_TestDeletedResultReceiverFailure) test(_TestBoolResultReceiverSuccessTrue) @@ -64,11 +64,11 @@ actor \nodoc\ Main is TestList test(_TestSearchResultReceiverSuccess) test(_TestSearchResultReceiverConverterError) test(_TestSearchResultReceiverFailure) - test(_TestJsonRequesterGetSuccess) - test(_TestJsonRequesterGetFailure) - test(_TestJsonRequesterPostSuccess) - test(_TestJsonRequesterGetRedirect) - test(_TestJsonRequesterGetParseError) + test(_TestJSONRequesterGetSuccess) + test(_TestJSONRequesterGetFailure) + test(_TestJSONRequesterPostSuccess) + test(_TestJSONRequesterGetRedirect) + test(_TestJSONRequesterGetParseError) test(_TestNoContentDeleteSuccess) test(_TestNoContentDeleteFailure) test(_TestCheckRequester204) @@ -95,34 +95,40 @@ class \nodoc\ _TestExtractPaginationLinksNoLinks is UnitTest fun ref apply(h: TestHelper) ? => (let prev, let next) = _ExtractPaginationLinks("") - h.assert_is[None](None, prev as None, - "prev should be None") - h.assert_is[None](None, next as None, - "next should be None") + h.assert_is[None]( + None, prev as None, "prev should be None") + h.assert_is[None]( + None, next as None, "next should be None") class \nodoc\ _TestExtractPaginationLinksInvalidHeader is UnitTest fun name(): String => "extract-pagination-links/invalid-header" fun ref apply(h: TestHelper) ? => - (let prev, let next) = _ExtractPaginationLinks("not a valid link header") - h.assert_is[None](None, prev as None, - "prev should be None for invalid header") - h.assert_is[None](None, next as None, - "next should be None for invalid header") + (let prev, let next) = + _ExtractPaginationLinks("not a valid link header") + h.assert_is[None]( + None, prev as None, "prev should be None for invalid header") + h.assert_is[None]( + None, next as None, "next should be None for invalid header") class \nodoc\ _TestExtractPaginationLinksFirstPage is UnitTest fun name(): String => "extract-pagination-links/first-page" fun ref apply(h: TestHelper) ? => - let link = "; rel=\"next\", ; rel=\"last\"" + let link = + "; rel=\"next\", " + + "; rel=\"last\"" (let prev, let next) = _ExtractPaginationLinks(link) - h.assert_is[None](None, prev as None, - "prev should be None") + h.assert_is[None]( + None, prev as None, "prev should be None") h.assert_eq[String]( - "https://api.github.com/repositories/218833512/labels?per_page=2&page=2", + "https://api.github.com/repositories/218833512/labels" + + "?per_page=2&page=2", next as String) class \nodoc\ _TestExtractPaginationLinksLastPage is UnitTest @@ -130,26 +136,41 @@ class \nodoc\ _TestExtractPaginationLinksLastPage is UnitTest "extract-pagination-links/last-page" fun ref apply(h: TestHelper) ? => - let link = "; rel=\"prev\", ; rel=\"first\"" + let link = + "; rel=\"prev\", " + + "; rel=\"first\"" (let prev, let next) = _ExtractPaginationLinks(link) h.assert_eq[String]( - "https://api.github.com/repositories/218833512/labels?per_page=2&page=4", + "https://api.github.com/repositories/218833512/labels" + + "?per_page=2&page=4", prev as String) - h.assert_is[None](None, next as None, - "next should be None") + h.assert_is[None]( + None, next as None, "next should be None") class \nodoc\ _TestExtractPaginationLinksBetweenPages is UnitTest fun name(): String => "extract-pagination-links/between-pages" fun ref apply(h: TestHelper) ? => - let link = "; rel=\"prev\", ; rel=\"next\", ; rel=\"last\", ; rel=\"first\"" + let link = + "; rel=\"prev\", " + + "; rel=\"next\", " + + "; rel=\"last\", " + + "; rel=\"first\"" (let prev, let next) = _ExtractPaginationLinks(link) h.assert_eq[String]( - "https://api.github.com/repositories/218833512/labels?per_page=2&page=1", + "https://api.github.com/repositories/218833512/labels" + + "?per_page=2&page=1", prev as String) h.assert_eq[String]( - "https://api.github.com/repositories/218833512/labels?per_page=2&page=3", + "https://api.github.com/repositories/218833512/labels" + + "?per_page=2&page=3", next as String) diff --git a/github_rest_api/_test_json_converters.pony b/github_rest_api/_test_json_converters.pony index e4a799c..6614a85 100644 --- a/github_rest_api/_test_json_converters.pony +++ b/github_rest_api/_test_json_converters.pony @@ -4,12 +4,13 @@ use "pony_test" use lori = "lori" use req = "request" -class \nodoc\ _TestGitPersonJsonConverterPreservesValues is UnitTest +class \nodoc\ _TestGitPersonJSONConverterPreservesValues is UnitTest fun name(): String => "git-person-json-converter/preserves-values" fun ref apply(h: TestHelper) ? => PonyCheck.for_all[String]( - recover val Generators.ascii_printable(1, 20) end, h)( + recover val Generators.ascii_printable(1, 20) end, + h)( {(base, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) @@ -21,7 +22,7 @@ class \nodoc\ _TestGitPersonJsonConverterPreservesValues is UnitTest .update("email", email_val) let json = JsonNav(obj) try - let person = GitPersonJsonConverter(json, creds)? + let person = GitPersonJSONConverter(json, creds)? h.assert_eq[String](name_val, person.name) h.assert_eq[String](email_val, person.email) else @@ -29,13 +30,14 @@ class \nodoc\ _TestGitPersonJsonConverterPreservesValues is UnitTest end })? -class \nodoc\ _TestGitPersonJsonConverterMissingField is UnitTest +class \nodoc\ _TestGitPersonJSONConverterMissingField is UnitTest fun name(): String => "git-person-json-converter/missing-field" fun ref apply(h: TestHelper) ? => PonyCheck.for_all2[String, USize]( recover val Generators.ascii_printable(1, 20) end, - recover val Generators.usize(0, 1) end, h)( + recover val Generators.usize(0, 1) end, + h)( {(base, skip_idx, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) @@ -45,18 +47,19 @@ class \nodoc\ _TestGitPersonJsonConverterMissingField is UnitTest if skip_idx != 1 then obj = obj.update("email", "email_" + b) end let json = JsonNav(obj) try - GitPersonJsonConverter(json, creds)? + GitPersonJSONConverter(json, creds)? h.fail("converter should have raised for missing field at index " + skip_idx.string()) end })? -class \nodoc\ _TestLicenseJsonConverterPreservesValues is UnitTest +class \nodoc\ _TestLicenseJSONConverterPreservesValues is UnitTest fun name(): String => "license-json-converter/preserves-values" fun ref apply(h: TestHelper) ? => PonyCheck.for_all[String]( - recover val Generators.ascii_printable(1, 20) end, h)( + recover val Generators.ascii_printable(1, 20) end, + h)( {(base, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) @@ -74,7 +77,7 @@ class \nodoc\ _TestLicenseJsonConverterPreservesValues is UnitTest .update("url", url_val) let json = JsonNav(obj) try - let license = LicenseJsonConverter(json, creds)? + let license = LicenseJSONConverter(json, creds)? h.assert_eq[String](node_id_val, license.node_id) h.assert_eq[String](name_val, license.name) h.assert_eq[String](key_val, license.key) @@ -85,13 +88,14 @@ class \nodoc\ _TestLicenseJsonConverterPreservesValues is UnitTest end })? -class \nodoc\ _TestLicenseJsonConverterMissingField is UnitTest +class \nodoc\ _TestLicenseJSONConverterMissingField is UnitTest fun name(): String => "license-json-converter/missing-field" fun ref apply(h: TestHelper) ? => PonyCheck.for_all2[String, USize]( recover val Generators.ascii_printable(1, 20) end, - recover val Generators.usize(0, 4) end, h)( + recover val Generators.usize(0, 4) end, + h)( {(base, skip_idx, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) @@ -104,18 +108,19 @@ class \nodoc\ _TestLicenseJsonConverterMissingField is UnitTest if skip_idx != 4 then obj = obj.update("url", "url_" + b) end let json = JsonNav(obj) try - LicenseJsonConverter(json, creds)? + LicenseJSONConverter(json, creds)? h.fail("converter should have raised for missing field at index " + skip_idx.string()) end })? -class \nodoc\ _TestCommitFileJsonConverterPreservesValues is UnitTest +class \nodoc\ _TestCommitFileJSONConverterPreservesValues is UnitTest fun name(): String => "commit-file-json-converter/preserves-values" fun ref apply(h: TestHelper) ? => PonyCheck.for_all[String]( - recover val Generators.ascii_printable(1, 20) end, h)( + recover val Generators.ascii_printable(1, 20) end, + h)( {(base, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) @@ -129,7 +134,7 @@ class \nodoc\ _TestCommitFileJsonConverterPreservesValues is UnitTest .update("filename", filename_val) let json = JsonNav(obj) try - let file = CommitFileJsonConverter(json, creds)? + let file = CommitFileJSONConverter(json, creds)? h.assert_eq[String](sha_val, file.sha) h.assert_eq[String](status_val, file.status) h.assert_eq[String](filename_val, file.filename) @@ -138,13 +143,14 @@ class \nodoc\ _TestCommitFileJsonConverterPreservesValues is UnitTest end })? -class \nodoc\ _TestCommitFileJsonConverterMissingField is UnitTest +class \nodoc\ _TestCommitFileJSONConverterMissingField is UnitTest fun name(): String => "commit-file-json-converter/missing-field" fun ref apply(h: TestHelper) ? => PonyCheck.for_all2[String, USize]( recover val Generators.ascii_printable(1, 20) end, - recover val Generators.usize(0, 2) end, h)( + recover val Generators.usize(0, 2) end, + h)( {(base, skip_idx, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) @@ -157,13 +163,13 @@ class \nodoc\ _TestCommitFileJsonConverterMissingField is UnitTest end let json = JsonNav(obj) try - CommitFileJsonConverter(json, creds)? + CommitFileJSONConverter(json, creds)? h.fail("converter should have raised for missing field at index " + skip_idx.string()) end })? -class \nodoc\ _TestGistChangeStatusJsonConverterPreservesValues is UnitTest +class \nodoc\ _TestGistChangeStatusJSONConverterPreservesValues is UnitTest fun name(): String => "gist-change-status-json-converter/preserves-values" @@ -171,7 +177,8 @@ class \nodoc\ _TestGistChangeStatusJsonConverterPreservesValues is UnitTest PonyCheck.for_all3[I64, I64, I64]( recover val Generators.i64() end, recover val Generators.i64() end, - recover val Generators.i64() end, h)( + recover val Generators.i64() end, + h)( {(additions, deletions, total, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) @@ -181,7 +188,7 @@ class \nodoc\ _TestGistChangeStatusJsonConverterPreservesValues is UnitTest .update("total", total) let json = JsonNav(obj) try - let status = GistChangeStatusJsonConverter(json, creds)? + let status = GistChangeStatusJSONConverter(json, creds)? h.assert_eq[I64](additions, status.additions) h.assert_eq[I64](deletions, status.deletions) h.assert_eq[I64](total, status.total) @@ -190,14 +197,15 @@ class \nodoc\ _TestGistChangeStatusJsonConverterPreservesValues is UnitTest end })? -class \nodoc\ _TestGistChangeStatusJsonConverterMissingField is UnitTest +class \nodoc\ _TestGistChangeStatusJSONConverterMissingField is UnitTest fun name(): String => "gist-change-status-json-converter/missing-field" fun ref apply(h: TestHelper) ? => PonyCheck.for_all2[I64, USize]( recover val Generators.i64() end, - recover val Generators.usize(0, 2) end, h)( + recover val Generators.usize(0, 2) end, + h)( {(value, skip_idx, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) @@ -207,13 +215,13 @@ class \nodoc\ _TestGistChangeStatusJsonConverterMissingField is UnitTest if skip_idx != 2 then obj = obj.update("total", value) end let json = JsonNav(obj) try - GistChangeStatusJsonConverter(json, creds)? + GistChangeStatusJSONConverter(json, creds)? h.fail("converter should have raised for missing field at index " + skip_idx.string()) end })? -primitive \nodoc\ _TestUserJson +primitive \nodoc\ _TestUserJSON """ Builds a valid User JSON object for testing converters that nest a User. """ @@ -238,7 +246,7 @@ primitive \nodoc\ _TestUserJson .update("type", "User") .update("site_admin", false) -primitive \nodoc\ _TestGitPersonJson +primitive \nodoc\ _TestGitPersonJSON """ Builds a valid GitPerson JSON object for testing converters that nest a GitPerson. @@ -248,7 +256,7 @@ primitive \nodoc\ _TestGitPersonJson .update("name", "name_" + b) .update("email", "email_" + b) -primitive \nodoc\ _TestCommitFileJson +primitive \nodoc\ _TestCommitFileJSON """ Builds a valid CommitFile JSON object for testing converters that nest a CommitFile. @@ -259,19 +267,19 @@ primitive \nodoc\ _TestCommitFileJson .update("status", "status_" + b) .update("filename", "filename_" + b) -primitive \nodoc\ _TestGitCommitJson +primitive \nodoc\ _TestGitCommitJSON """ Builds a valid GitCommit JSON object for testing converters that nest a GitCommit. """ fun apply(b: String val): JsonObject => JsonObject - .update("author", _TestGitPersonJson(b)) - .update("committer", _TestGitPersonJson(b)) + .update("author", _TestGitPersonJSON(b)) + .update("committer", _TestGitPersonJSON(b)) .update("message", "message_" + b) .update("url", "gcurl_" + b) -primitive \nodoc\ _TestLabelJson +primitive \nodoc\ _TestLabelJSON """ Builds a valid Label JSON object for testing converters that nest a Label. """ @@ -285,7 +293,7 @@ primitive \nodoc\ _TestLabelJson .update("default", false) .update("description", "ldesc_" + b) -primitive \nodoc\ _TestIssuePullRequestJson +primitive \nodoc\ _TestIssuePullRequestJSON """ Builds a valid IssuePullRequest JSON object for testing converters that nest an IssuePullRequest. @@ -298,13 +306,14 @@ primitive \nodoc\ _TestIssuePullRequestJson .update("patch_url", "prpatch_" + b) .update("merged_at", "prmerged_" + b) -class \nodoc\ _TestLabelJsonConverterPreservesValues is UnitTest +class \nodoc\ _TestLabelJSONConverterPreservesValues is UnitTest fun name(): String => "label-json-converter/preserves-values" fun ref apply(h: TestHelper) ? => PonyCheck.for_all2[String, Bool]( recover val Generators.ascii_printable(1, 20) end, - recover val Generators.bool() end, h)( + recover val Generators.bool() end, + h)( {(base, desc_is_null, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) @@ -329,7 +338,7 @@ class \nodoc\ _TestLabelJsonConverterPreservesValues is UnitTest end let json = JsonNav(obj) try - let lbl = LabelJsonConverter(json, creds)? + let lbl = LabelJSONConverter(json, creds)? h.assert_eq[I64](id_val, lbl.id) h.assert_eq[String](node_id_val, lbl.node_id) h.assert_eq[String](url_val, lbl.url) @@ -337,13 +346,13 @@ class \nodoc\ _TestLabelJsonConverterPreservesValues is UnitTest h.assert_eq[String](color_val, lbl.color) h.assert_false(lbl.default, "default should be false") if desc_is_null then - match lbl.description + match \exhaustive\ lbl.description | None => None | let _: String => h.fail("description should be None") end else - match lbl.description + match \exhaustive\ lbl.description | let s: String => h.assert_eq[String](desc_val, s) | None => @@ -355,13 +364,14 @@ class \nodoc\ _TestLabelJsonConverterPreservesValues is UnitTest end })? -class \nodoc\ _TestLabelJsonConverterMissingField is UnitTest +class \nodoc\ _TestLabelJSONConverterMissingField is UnitTest fun name(): String => "label-json-converter/missing-field" fun ref apply(h: TestHelper) ? => PonyCheck.for_all2[String, USize]( recover val Generators.ascii_printable(1, 20) end, - recover val Generators.usize(0, 6) end, h)( + recover val Generators.usize(0, 6) end, + h)( {(base, skip_idx, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) @@ -386,21 +396,22 @@ class \nodoc\ _TestLabelJsonConverterMissingField is UnitTest end let json = JsonNav(obj) try - LabelJsonConverter(json, creds)? + LabelJSONConverter(json, creds)? h.fail( "converter should have raised for missing " + "field at index " + skip_idx.string()) end })? -class \nodoc\ _TestIssuePRJsonConverterPreservesValues is UnitTest +class \nodoc\ _TestIssuePRJSONConverterPreservesValues is UnitTest fun name(): String => "issue-pull-request-json-converter/preserves-values" fun ref apply(h: TestHelper) ? => PonyCheck.for_all2[String, Bool]( recover val Generators.ascii_printable(1, 20) end, - recover val Generators.bool() end, h)( + recover val Generators.bool() end, + h)( {(base, merged_is_null, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) @@ -423,19 +434,19 @@ class \nodoc\ _TestIssuePRJsonConverterPreservesValues is UnitTest let json = JsonNav(obj) try let ipr = - IssuePullRequestJsonConverter(json, creds)? + IssuePullRequestJSONConverter(json, creds)? h.assert_eq[String](url_val, ipr.url) h.assert_eq[String](html_url_val, ipr.html_url) h.assert_eq[String](diff_url_val, ipr.diff_url) h.assert_eq[String](patch_url_val, ipr.patch_url) if merged_is_null then - match ipr.merged_at + match \exhaustive\ ipr.merged_at | None => None | let _: String => h.fail("merged_at should be None") end else - match ipr.merged_at + match \exhaustive\ ipr.merged_at | let s: String => h.assert_eq[String](merged_val, s) | None => @@ -447,14 +458,15 @@ class \nodoc\ _TestIssuePRJsonConverterPreservesValues is UnitTest end })? -class \nodoc\ _TestIssuePRJsonConverterMissingField is UnitTest +class \nodoc\ _TestIssuePRJSONConverterMissingField is UnitTest fun name(): String => "issue-pull-request-json-converter/missing-field" fun ref apply(h: TestHelper) ? => PonyCheck.for_all2[String, USize]( recover val Generators.ascii_printable(1, 20) end, - recover val Generators.usize(0, 4) end, h)( + recover val Generators.usize(0, 4) end, + h)( {(base, skip_idx, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) @@ -477,21 +489,22 @@ class \nodoc\ _TestIssuePRJsonConverterMissingField is UnitTest end let json = JsonNav(obj) try - IssuePullRequestJsonConverter(json, creds)? + IssuePullRequestJSONConverter(json, creds)? h.fail( "converter should have raised for missing " + "field at index " + skip_idx.string()) end })? -class \nodoc\ _TestAssetJsonConverterPreservesValues is UnitTest +class \nodoc\ _TestAssetJSONConverterPreservesValues is UnitTest fun name(): String => "asset-json-converter/preserves-values" fun ref apply(h: TestHelper) ? => PonyCheck.for_all2[String, Bool]( recover val Generators.ascii_printable(1, 20) end, - recover val Generators.bool() end, h)( + recover val Generators.bool() end, + h)( {(base, label_is_null, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) @@ -508,7 +521,7 @@ class \nodoc\ _TestAssetJsonConverterPreservesValues is UnitTest let ua_val: String val = "ua_" + b let url_val: String val = "url_" + b let bd_val: String val = "bd_" + b - let uploader_obj = _TestUserJson(b) + let uploader_obj = _TestUserJSON(b) var obj = JsonObject .update("id", id_val) .update("node_id", node_id_val) @@ -529,7 +542,7 @@ class \nodoc\ _TestAssetJsonConverterPreservesValues is UnitTest end let json = JsonNav(obj) try - let asset = AssetJsonConverter(json, creds)? + let asset = AssetJSONConverter(json, creds)? h.assert_eq[I64](id_val, asset.id) h.assert_eq[String](node_id_val, asset.node_id) h.assert_eq[String](name_val, asset.name) @@ -540,19 +553,21 @@ class \nodoc\ _TestAssetJsonConverterPreservesValues is UnitTest h.assert_eq[String](ca_val, asset.created_at) h.assert_eq[String](ua_val, asset.updated_at) h.assert_eq[String](url_val, asset.url) - h.assert_eq[String](bd_val, + h.assert_eq[String]( + bd_val, asset.browser_download_url) - h.assert_eq[String]("login_" + b, + h.assert_eq[String]( + "login_" + b, asset.uploader.login) h.assert_eq[I64](I64(1), asset.uploader.id) if label_is_null then - match asset.label + match \exhaustive\ asset.label | None => None | let _: String => h.fail("label should be None") end else - match asset.label + match \exhaustive\ asset.label | let s: String => h.assert_eq[String](label_val, s) | None => @@ -564,19 +579,20 @@ class \nodoc\ _TestAssetJsonConverterPreservesValues is UnitTest end })? -class \nodoc\ _TestAssetJsonConverterMissingField is UnitTest +class \nodoc\ _TestAssetJSONConverterMissingField is UnitTest fun name(): String => "asset-json-converter/missing-field" fun ref apply(h: TestHelper) ? => PonyCheck.for_all2[String, USize]( recover val Generators.ascii_printable(1, 20) end, - recover val Generators.usize(0, 12) end, h)( + recover val Generators.usize(0, 12) end, + h)( {(base, skip_idx, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) let b: String val = base.clone() - let uploader_obj = _TestUserJson(b) + let uploader_obj = _TestUserJSON(b) var obj = JsonObject if skip_idx != 0 then obj = obj.update("id", I64(42)) @@ -615,26 +631,28 @@ class \nodoc\ _TestAssetJsonConverterMissingField is UnitTest obj = obj.update("url", "url_" + b) end if skip_idx != 12 then - obj = obj.update( + obj = + obj.update( "browser_download_url", "bd_" + b) end let json = JsonNav(obj) try - AssetJsonConverter(json, creds)? + AssetJSONConverter(json, creds)? h.fail( "converter should have raised for missing " + "field at index " + skip_idx.string()) end })? -class \nodoc\ _TestGistFileJsonConverterPreservesValues is UnitTest +class \nodoc\ _TestGistFileJSONConverterPreservesValues is UnitTest fun name(): String => "gist-file-json-converter/preserves-values" fun ref apply(h: TestHelper) ? => PonyCheck.for_all2[String, Bool]( recover val Generators.ascii_printable(1, 20) end, - recover val Generators.bool() end, h)( + recover val Generators.bool() end, + h)( {(base, lang_is_null, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) @@ -661,37 +679,37 @@ class \nodoc\ _TestGistFileJsonConverterPreservesValues is UnitTest end let json = JsonNav(obj) try - let gf = GistFileJsonConverter(json, creds)? + let gf = GistFileJSONConverter(json, creds)? h.assert_eq[String](fn_val, gf.filename) h.assert_eq[String](ct_val, gf.content_type) h.assert_eq[String](raw_val, gf.raw_url) h.assert_eq[I64](size_val, gf.size) - match gf.content + match \exhaustive\ gf.content | let s: String => h.assert_eq[String](content_val, s) | None => h.fail("content should be String") end - match gf.encoding + match \exhaustive\ gf.encoding | let s: String => h.assert_eq[String](encoding_val, s) | None => h.fail("encoding should be String") end - match gf.truncated + match \exhaustive\ gf.truncated | let t: Bool => h.assert_false(t, "truncated should be false") | None => h.fail("truncated should be Bool") end if lang_is_null then - match gf.language + match \exhaustive\ gf.language | None => None | let _: String => h.fail("language should be None") end else - match gf.language + match \exhaustive\ gf.language | let s: String => h.assert_eq[String](lang_val, s) | None => @@ -703,14 +721,15 @@ class \nodoc\ _TestGistFileJsonConverterPreservesValues is UnitTest end })? -class \nodoc\ _TestGistFileJsonConverterMissingField is UnitTest +class \nodoc\ _TestGistFileJSONConverterMissingField is UnitTest fun name(): String => "gist-file-json-converter/missing-field" fun ref apply(h: TestHelper) ? => PonyCheck.for_all2[String, USize]( recover val Generators.ascii_printable(1, 20) end, - recover val Generators.usize(0, 4) end, h)( + recover val Generators.usize(0, 4) end, + h)( {(base, skip_idx, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) @@ -733,20 +752,21 @@ class \nodoc\ _TestGistFileJsonConverterMissingField is UnitTest end let json = JsonNav(obj) try - GistFileJsonConverter(json, creds)? + GistFileJSONConverter(json, creds)? h.fail( "converter should have raised for missing " + "field at index " + skip_idx.string()) end })? -class \nodoc\ _TestGistFileJsonConverterAbsentOptionalFields is UnitTest +class \nodoc\ _TestGistFileJSONConverterAbsentOptionalFields is UnitTest fun name(): String => "gist-file-json-converter/absent-optional-fields" fun ref apply(h: TestHelper) ? => PonyCheck.for_all[String]( - recover val Generators.ascii_printable(1, 20) end, h)( + recover val Generators.ascii_printable(1, 20) end, + h)( {(base, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) @@ -759,21 +779,21 @@ class \nodoc\ _TestGistFileJsonConverterAbsentOptionalFields is UnitTest .update("size", I64(100)) let json = JsonNav(obj) try - let gf = GistFileJsonConverter(json, creds)? + let gf = GistFileJSONConverter(json, creds)? h.assert_eq[String]("fn_" + b, gf.filename) h.assert_eq[String]("ct_" + b, gf.content_type) h.assert_eq[I64](I64(100), gf.size) - match gf.content + match \exhaustive\ gf.content | None => None | let _: String => h.fail("content should be None") end - match gf.encoding + match \exhaustive\ gf.encoding | None => None | let _: String => h.fail("encoding should be None") end - match gf.truncated + match \exhaustive\ gf.truncated | None => None | let _: Bool => h.fail("truncated should be None") @@ -783,13 +803,14 @@ class \nodoc\ _TestGistFileJsonConverterAbsentOptionalFields is UnitTest end })? -class \nodoc\ _TestGitCommitJsonConverterPreservesValues is UnitTest +class \nodoc\ _TestGitCommitJSONConverterPreservesValues is UnitTest fun name(): String => "git-commit-json-converter/preserves-values" fun ref apply(h: TestHelper) ? => PonyCheck.for_all[String]( - recover val Generators.ascii_printable(1, 20) end, h)( + recover val Generators.ascii_printable(1, 20) end, + h)( {(base, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) @@ -797,19 +818,22 @@ class \nodoc\ _TestGitCommitJsonConverterPreservesValues is UnitTest let message_val: String val = "message_" + b let url_val: String val = "gcurl_" + b let obj = JsonObject - .update("author", _TestGitPersonJson(b)) - .update("committer", _TestGitPersonJson(b)) + .update("author", _TestGitPersonJSON(b)) + .update("committer", _TestGitPersonJSON(b)) .update("message", message_val) .update("url", url_val) let json = JsonNav(obj) try - let gc = GitCommitJsonConverter(json, creds)? + let gc = GitCommitJSONConverter(json, creds)? h.assert_eq[String]("name_" + b, gc.author.name) - h.assert_eq[String]("email_" + b, + h.assert_eq[String]( + "email_" + b, gc.author.email) - h.assert_eq[String]("name_" + b, + h.assert_eq[String]( + "name_" + b, gc.committer.name) - h.assert_eq[String]("email_" + b, + h.assert_eq[String]( + "email_" + b, gc.committer.email) h.assert_eq[String](message_val, gc.message) h.assert_eq[String](url_val, gc.url) @@ -818,26 +842,31 @@ class \nodoc\ _TestGitCommitJsonConverterPreservesValues is UnitTest end })? -class \nodoc\ _TestGitCommitJsonConverterMissingField is UnitTest +class \nodoc\ _TestGitCommitJSONConverterMissingField is UnitTest fun name(): String => "git-commit-json-converter/missing-field" fun ref apply(h: TestHelper) ? => PonyCheck.for_all2[String, USize]( recover val Generators.ascii_printable(1, 20) end, - recover val Generators.usize(0, 3) end, h)( + recover val Generators.usize(0, 3) end, + h)( {(base, skip_idx, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) let b: String val = base.clone() var obj = JsonObject if skip_idx != 0 then - obj = obj.update("author", - _TestGitPersonJson(b)) + obj = + obj.update( + "author", + _TestGitPersonJSON(b)) end if skip_idx != 1 then - obj = obj.update("committer", - _TestGitPersonJson(b)) + obj = + obj.update( + "committer", + _TestGitPersonJSON(b)) end if skip_idx != 2 then obj = obj.update("message", "message_" + b) @@ -847,20 +876,21 @@ class \nodoc\ _TestGitCommitJsonConverterMissingField is UnitTest end let json = JsonNav(obj) try - GitCommitJsonConverter(json, creds)? + GitCommitJSONConverter(json, creds)? h.fail( "converter should have raised for missing " + "field at index " + skip_idx.string()) end })? -class \nodoc\ _TestCommitJsonConverterPreservesValues is UnitTest +class \nodoc\ _TestCommitJSONConverterPreservesValues is UnitTest fun name(): String => "commit-json-converter/preserves-values" fun ref apply(h: TestHelper) ? => PonyCheck.for_all[String]( - recover val Generators.ascii_printable(1, 20) end, h)( + recover val Generators.ascii_printable(1, 20) end, + h)( {(base, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) @@ -871,54 +901,65 @@ class \nodoc\ _TestCommitJsonConverterPreservesValues is UnitTest let comments_url_val: String val = "curl_" + b let obj = JsonObject .update("sha", sha_val) - .update("files", - JsonArray.push(_TestCommitFileJson(b))) - .update("commit", _TestGitCommitJson(b)) + .update( + "files", + JsonArray.push(_TestCommitFileJSON(b))) + .update("commit", _TestGitCommitJSON(b)) .update("url", url_val) .update("html_url", html_url_val) .update("comments_url", comments_url_val) let json = JsonNav(obj) try - let c = CommitJsonConverter(json, creds)? + let c = CommitJSONConverter(json, creds)? h.assert_eq[String](sha_val, c.sha) h.assert_eq[USize](1, c.files.size()) try - h.assert_eq[String]("sha_" + b, + h.assert_eq[String]( + "sha_" + b, c.files(0)?.sha) - h.assert_eq[String]("status_" + b, + h.assert_eq[String]( + "status_" + b, c.files(0)?.status) - h.assert_eq[String]("filename_" + b, + h.assert_eq[String]( + "filename_" + b, c.files(0)?.filename) else h.fail( "files array access raised an error") end - h.assert_eq[String]("name_" + b, + h.assert_eq[String]( + "name_" + b, c.git_commit.author.name) - h.assert_eq[String]("email_" + b, + h.assert_eq[String]( + "email_" + b, c.git_commit.author.email) - h.assert_eq[String]("message_" + b, + h.assert_eq[String]( + "message_" + b, c.git_commit.message) - h.assert_eq[String]("gcurl_" + b, + h.assert_eq[String]( + "gcurl_" + b, c.git_commit.url) h.assert_eq[String](url_val, c.url) - h.assert_eq[String](html_url_val, + h.assert_eq[String]( + html_url_val, c.html_url) - h.assert_eq[String](comments_url_val, + h.assert_eq[String]( + comments_url_val, c.comments_url) else h.fail("converter raised an error") end })? -class \nodoc\ _TestCommitJsonConverterMissingField is UnitTest +class \nodoc\ _TestCommitJSONConverterMissingField is UnitTest fun name(): String => "commit-json-converter/missing-field" fun ref apply(h: TestHelper) ? => PonyCheck.for_all2[String, USize]( recover val Generators.ascii_printable(1, 20) end, - recover val Generators.usize(0, 5) end, h)( + recover val Generators.usize(0, 5) end, + h)( {(base, skip_idx, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) @@ -928,12 +969,16 @@ class \nodoc\ _TestCommitJsonConverterMissingField is UnitTest obj = obj.update("sha", "sha_" + b) end if skip_idx != 1 then - obj = obj.update("files", - JsonArray.push(_TestCommitFileJson(b))) + obj = + obj.update( + "files", + JsonArray.push(_TestCommitFileJSON(b))) end if skip_idx != 2 then - obj = obj.update("commit", - _TestGitCommitJson(b)) + obj = + obj.update( + "commit", + _TestGitCommitJSON(b)) end if skip_idx != 3 then obj = obj.update("url", "url_" + b) @@ -942,19 +987,21 @@ class \nodoc\ _TestCommitJsonConverterMissingField is UnitTest obj = obj.update("html_url", "html_" + b) end if skip_idx != 5 then - obj = obj.update("comments_url", + obj = + obj.update( + "comments_url", "curl_" + b) end let json = JsonNav(obj) try - CommitJsonConverter(json, creds)? + CommitJSONConverter(json, creds)? h.fail( "converter should have raised for missing " + "field at index " + skip_idx.string()) end })? -class \nodoc\ _TestIssueJsonConverterPreservesValues is UnitTest +class \nodoc\ _TestIssueJSONConverterPreservesValues is UnitTest fun name(): String => "issue-json-converter/preserves-values" @@ -962,7 +1009,8 @@ class \nodoc\ _TestIssueJsonConverterPreservesValues is UnitTest PonyCheck.for_all3[String, Bool, Bool]( recover val Generators.ascii_printable(1, 20) end, recover val Generators.bool() end, - recover val Generators.bool() end, h)( + recover val Generators.bool() end, + h)( {(base, state_is_null, body_is_null, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) @@ -986,11 +1034,13 @@ class \nodoc\ _TestIssueJsonConverterPreservesValues is UnitTest .update("html_url", html_url_val) .update("number", number_val) .update("title", title_val) - .update("user", _TestUserJson(b)) - .update("labels", - JsonArray.push(_TestLabelJson(b))) - .update("pull_request", - _TestIssuePullRequestJson(b)) + .update("user", _TestUserJSON(b)) + .update( + "labels", + JsonArray.push(_TestLabelJSON(b))) + .update( + "pull_request", + _TestIssuePullRequestJSON(b)) if state_is_null then obj = obj.update("state", None) else @@ -1004,38 +1054,45 @@ class \nodoc\ _TestIssueJsonConverterPreservesValues is UnitTest let json = JsonNav(obj) try let issue = - IssueJsonConverter(json, creds)? + IssueJSONConverter(json, creds)? h.assert_eq[String](url_val, issue.url) - h.assert_eq[String](repo_url_val, + h.assert_eq[String]( + repo_url_val, issue.respository_url) - h.assert_eq[String](labels_url_val, + h.assert_eq[String]( + labels_url_val, issue.labels_url) - h.assert_eq[String](cmnts_url_val, + h.assert_eq[String]( + cmnts_url_val, issue.comments_url) - h.assert_eq[String](events_url_val, + h.assert_eq[String]( + events_url_val, issue.events_url) - h.assert_eq[String](html_url_val, + h.assert_eq[String]( + html_url_val, issue.html_url) h.assert_eq[I64](number_val, issue.number) h.assert_eq[String](title_val, issue.title) - h.assert_eq[String]("login_" + b, + h.assert_eq[String]( + "login_" + b, issue.user.login) h.assert_eq[USize](1, issue.labels.size()) try - h.assert_eq[String]("lname_" + b, + h.assert_eq[String]( + "lname_" + b, issue.labels(0)?.name) else h.fail( "labels array access raised an error") end if state_is_null then - match issue.state + match \exhaustive\ issue.state | None => None | let _: String => h.fail("state should be None") end else - match issue.state + match \exhaustive\ issue.state | let s: String => h.assert_eq[String](state_val, s) | None => @@ -1043,24 +1100,26 @@ class \nodoc\ _TestIssueJsonConverterPreservesValues is UnitTest end end if body_is_null then - match issue.body + match \exhaustive\ issue.body | None => None | let _: String => h.fail("body should be None") end else - match issue.body + match \exhaustive\ issue.body | let s: String => h.assert_eq[String](body_val, s) | None => h.fail("body should be String") end end - match issue.pull_request + match \exhaustive\ issue.pull_request | let pr: IssuePullRequest => - h.assert_eq[String]("prurl_" + b, + h.assert_eq[String]( + "prurl_" + b, pr.url) - h.assert_eq[String]("prhtml_" + b, + h.assert_eq[String]( + "prhtml_" + b, pr.html_url) | None => h.fail( @@ -1071,7 +1130,7 @@ class \nodoc\ _TestIssueJsonConverterPreservesValues is UnitTest end })? -primitive \nodoc\ _TestLicenseJson +primitive \nodoc\ _TestLicenseJSON """ Builds a valid License JSON object for testing converters that nest a License. @@ -1084,7 +1143,7 @@ primitive \nodoc\ _TestLicenseJson .update("spdx_id", "licspdx_" + b) .update("url", "licurl_" + b) -primitive \nodoc\ _TestGistFileJson +primitive \nodoc\ _TestGistFileJSON """ Builds a fully-populated GistFile JSON object for testing converters that nest a GistFile. Includes all optional fields @@ -1101,10 +1160,10 @@ primitive \nodoc\ _TestGistFileJson .update("encoding", "utf-8") .update("truncated", false) -primitive \nodoc\ _TestRepositoryJson +primitive \nodoc\ _TestRepositoryJSON """ Builds a complete valid Repository JSON object for testing - RepositoryJsonConverter. Includes all required and optional + RepositoryJSONConverter. Includes all required and optional fields with non-null values. """ fun apply(b: String val): JsonObject => @@ -1114,7 +1173,7 @@ primitive \nodoc\ _TestRepositoryJson .update("name", "rname_" + b) .update("full_name", "rfull_" + b) .update("description", "rdesc_" + b) - .update("owner", _TestUserJson(b)) + .update("owner", _TestUserJSON(b)) .update("private", false) .update("fork", false) .update("created_at", "rca_" + b) @@ -1122,7 +1181,7 @@ primitive \nodoc\ _TestRepositoryJson .update("updated_at", "rua_" + b) .update("homepage", "rhome_" + b) .update("default_branch", "rdb_" + b) - .update("organization", _TestUserJson(b)) + .update("organization", _TestUserJSON(b)) .update("size", I64(100)) .update("forks", I64(5)) .update("forks_count", I64(5)) @@ -1134,7 +1193,7 @@ primitive \nodoc\ _TestRepositoryJson .update("watchers", I64(50)) .update("watchers_count", I64(50)) .update("language", "rlang_" + b) - .update("license", _TestLicenseJson(b)) + .update("license", _TestLicenseJSON(b)) .update("archived", false) .update("disabled", false) .update("has_downloads", true) @@ -1174,7 +1233,8 @@ primitive \nodoc\ _TestRepositoryJson .update("stargazers_url", "rstargazers_" + b) .update("statuses_url", "rstatuses_" + b) .update("subscribers_url", "rsubs_" + b) - .update("subscription_url", + .update( + "subscription_url", "rsubscription_" + b) .update("tags_url", "rtags_" + b) .update("trees_url", "rtrees_" + b) @@ -1184,10 +1244,10 @@ primitive \nodoc\ _TestRepositoryJson .update("ssh_url", "rssh_" + b) .update("svn_url", "rsvn_" + b) -primitive \nodoc\ _TestGistJson +primitive \nodoc\ _TestGistJSON """ Builds a complete valid Gist JSON object for testing - GistJsonConverter. Sets comments_enabled to false (not the + GistJSONConverter. Sets comments_enabled to false (not the default) so preserves-values can verify the explicit value and absent-optional can verify the default. """ @@ -1197,11 +1257,12 @@ primitive \nodoc\ _TestGistJson .update("node_id", "gnid_" + b) .update("description", "gdesc_" + b) .update("public", true) - .update("owner", _TestUserJson(b)) - .update("user", _TestUserJson(b)) - .update("files", + .update("owner", _TestUserJSON(b)) + .update("user", _TestUserJSON(b)) + .update( + "files", JsonObject.update( - "file1_" + b, _TestGistFileJson(b))) + "file1_" + b, _TestGistFileJSON(b))) .update("comments", I64(5)) .update("comments_enabled", false) .update("truncated", false) @@ -1215,14 +1276,15 @@ primitive \nodoc\ _TestGistJson .update("git_pull_url", "gpullurl_" + b) .update("git_push_url", "gpushurl_" + b) -class \nodoc\ _TestIssueJsonConverterMissingField is UnitTest +class \nodoc\ _TestIssueJSONConverterMissingField is UnitTest fun name(): String => "issue-json-converter/missing-field" fun ref apply(h: TestHelper) ? => PonyCheck.for_all2[String, USize]( recover val Generators.ascii_printable(1, 20) end, - recover val Generators.usize(0, 11) end, h)( + recover val Generators.usize(0, 11) end, + h)( {(base, skip_idx, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) @@ -1232,19 +1294,27 @@ class \nodoc\ _TestIssueJsonConverterMissingField is UnitTest obj = obj.update("url", "url_" + b) end if skip_idx != 1 then - obj = obj.update("repository_url", + obj = + obj.update( + "repository_url", "rurl_" + b) end if skip_idx != 2 then - obj = obj.update("labels_url", + obj = + obj.update( + "labels_url", "lsurl_" + b) end if skip_idx != 3 then - obj = obj.update("comments_url", + obj = + obj.update( + "comments_url", "curl_" + b) end if skip_idx != 4 then - obj = obj.update("events_url", + obj = + obj.update( + "events_url", "evurl_" + b) end if skip_idx != 5 then @@ -1257,7 +1327,7 @@ class \nodoc\ _TestIssueJsonConverterMissingField is UnitTest obj = obj.update("title", "title_" + b) end if skip_idx != 8 then - obj = obj.update("user", _TestUserJson(b)) + obj = obj.update("user", _TestUserJSON(b)) end if skip_idx != 9 then obj = obj.update("state", "open") @@ -1266,25 +1336,28 @@ class \nodoc\ _TestIssueJsonConverterMissingField is UnitTest obj = obj.update("body", "body_" + b) end if skip_idx != 11 then - obj = obj.update("labels", - JsonArray.push(_TestLabelJson(b))) + obj = + obj.update( + "labels", + JsonArray.push(_TestLabelJSON(b))) end let json = JsonNav(obj) try - IssueJsonConverter(json, creds)? + IssueJSONConverter(json, creds)? h.fail( "converter should have raised for missing " + "field at index " + skip_idx.string()) end })? -class \nodoc\ _TestIssueJsonConverterAbsentPullRequest is UnitTest +class \nodoc\ _TestIssueJSONConverterAbsentPullRequest is UnitTest fun name(): String => "issue-json-converter/absent-pull-request" fun ref apply(h: TestHelper) ? => PonyCheck.for_all[String]( - recover val Generators.ascii_printable(1, 20) end, h)( + recover val Generators.ascii_printable(1, 20) end, + h)( {(base, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) @@ -1298,16 +1371,17 @@ class \nodoc\ _TestIssueJsonConverterAbsentPullRequest is UnitTest .update("html_url", "html_" + b) .update("number", I64(42)) .update("title", "title_" + b) - .update("user", _TestUserJson(b)) + .update("user", _TestUserJSON(b)) .update("state", "open") .update("body", "body_" + b) - .update("labels", - JsonArray.push(_TestLabelJson(b))) + .update( + "labels", + JsonArray.push(_TestLabelJSON(b))) let json = JsonNav(obj) try let issue = - IssueJsonConverter(json, creds)? - match issue.pull_request + IssueJSONConverter(json, creds)? + match \exhaustive\ issue.pull_request | None => None | let _: IssuePullRequest => h.fail( @@ -1318,7 +1392,7 @@ class \nodoc\ _TestIssueJsonConverterAbsentPullRequest is UnitTest end })? -class \nodoc\ _TestRepoJsonConverterPreservesValues +class \nodoc\ _TestRepoJSONConverterPreservesValues is UnitTest fun name(): String => "repo-json-converter/preserves-values" @@ -1326,12 +1400,13 @@ class \nodoc\ _TestRepoJsonConverterPreservesValues fun ref apply(h: TestHelper) ? => PonyCheck.for_all2[String, USize]( recover val Generators.ascii_printable(1, 20) end, - recover val Generators.usize(0, 15) end, h)( + recover val Generators.usize(0, 15) end, + h)( {(base, mask, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) let b: String val = base.clone() - var obj = _TestRepositoryJson(b) + var obj = _TestRepositoryJSON(b) if (mask and 1) != 0 then obj = obj.update("description", None) end @@ -1347,23 +1422,26 @@ class \nodoc\ _TestRepoJsonConverterPreservesValues let json = JsonNav(obj) try let repo = - RepositoryJsonConverter(json, creds)? + RepositoryJSONConverter(json, creds)? h.assert_eq[I64](I64(1), repo.id) - h.assert_eq[String]("rnid_" + b, + h.assert_eq[String]( + "rnid_" + b, repo.node_id) - h.assert_eq[String]("rname_" + b, + h.assert_eq[String]( + "rname_" + b, repo.name) - h.assert_eq[String]("rfull_" + b, + h.assert_eq[String]( + "rfull_" + b, repo.full_name) if (mask and 1) != 0 then - match repo.description + match \exhaustive\ repo.description | None => None | let _: String => h.fail( "description should be None") end else - match repo.description + match \exhaustive\ repo.description | let s: String => h.assert_eq[String]( "rdesc_" + b, s) @@ -1372,26 +1450,32 @@ class \nodoc\ _TestRepoJsonConverterPreservesValues "description should be String") end end - h.assert_eq[String]("login_" + b, + h.assert_eq[String]( + "login_" + b, repo.owner.login) - h.assert_false(repo.private, + h.assert_false( + repo.private, "private should be false") - h.assert_false(repo.fork, + h.assert_false( + repo.fork, "fork should be false") - h.assert_eq[String]("rca_" + b, + h.assert_eq[String]( + "rca_" + b, repo.created_at) - h.assert_eq[String]("rpa_" + b, + h.assert_eq[String]( + "rpa_" + b, repo.pushed_at) - h.assert_eq[String]("rua_" + b, + h.assert_eq[String]( + "rua_" + b, repo.updated_at) if (mask and 2) != 0 then - match repo.homepage + match \exhaustive\ repo.homepage | None => None | let _: String => h.fail("homepage should be None") end else - match repo.homepage + match \exhaustive\ repo.homepage | let s: String => h.assert_eq[String]( "rhome_" + b, s) @@ -1400,11 +1484,13 @@ class \nodoc\ _TestRepoJsonConverterPreservesValues "homepage should be String") end end - h.assert_eq[String]("rdb_" + b, + h.assert_eq[String]( + "rdb_" + b, repo.default_branch) - match repo.organization + match \exhaustive\ repo.organization | let u: User => - h.assert_eq[String]("login_" + b, + h.assert_eq[String]( + "login_" + b, u.login) | None => h.fail( @@ -1412,22 +1498,26 @@ class \nodoc\ _TestRepoJsonConverterPreservesValues end h.assert_eq[I64](I64(100), repo.size) h.assert_eq[I64](I64(5), repo.forks) - h.assert_eq[I64](I64(5), + h.assert_eq[I64]( + I64(5), repo.forks_count) - match repo.network_count + match \exhaustive\ repo.network_count | let n: I64 => h.assert_eq[I64](I64(10), n) | None => h.fail( "network_count should be present") end - h.assert_eq[I64](I64(3), + h.assert_eq[I64]( + I64(3), repo.open_issues) - h.assert_eq[I64](I64(3), + h.assert_eq[I64]( + I64(3), repo.open_issues_count) - h.assert_eq[I64](I64(50), + h.assert_eq[I64]( + I64(50), repo.stargazers_count) - match repo.subscribers_count + match \exhaustive\ repo.subscribers_count | let n: I64 => h.assert_eq[I64](I64(20), n) | None => @@ -1435,18 +1525,20 @@ class \nodoc\ _TestRepoJsonConverterPreservesValues "subscribers_count should be " + "present") end - h.assert_eq[I64](I64(50), + h.assert_eq[I64]( + I64(50), repo.watchers) - h.assert_eq[I64](I64(50), + h.assert_eq[I64]( + I64(50), repo.watchers_count) if (mask and 4) != 0 then - match repo.language + match \exhaustive\ repo.language | None => None | let _: String => h.fail("language should be None") end else - match repo.language + match \exhaustive\ repo.language | let s: String => h.assert_eq[String]( "rlang_" + b, s) @@ -1455,30 +1547,39 @@ class \nodoc\ _TestRepoJsonConverterPreservesValues "language should be String") end end - match repo.license + match \exhaustive\ repo.license | let l: License => h.assert_eq[String]( "lickey_" + b, l.key) | None => h.fail("license should be present") end - h.assert_false(repo.archived, + h.assert_false( + repo.archived, "archived should be false") - h.assert_false(repo.disabled, + h.assert_false( + repo.disabled, "disabled should be false") - h.assert_true(repo.has_downloads, + h.assert_true( + repo.has_downloads, "has_downloads should be true") - h.assert_true(repo.has_issues, + h.assert_true( + repo.has_issues, "has_issues should be true") - h.assert_false(repo.has_pages, + h.assert_false( + repo.has_pages, "has_pages should be false") - h.assert_true(repo.has_projects, + h.assert_true( + repo.has_projects, "has_projects should be true") - h.assert_true(repo.has_wiki, + h.assert_true( + repo.has_wiki, "has_wiki should be true") - h.assert_eq[String]("rurl_" + b, + h.assert_eq[String]( + "rurl_" + b, repo.url) - h.assert_eq[String]("rhurl_" + b, + h.assert_eq[String]( + "rhurl_" + b, repo.html_url) h.assert_eq[String]( "rarchive_" + b, @@ -1575,14 +1676,14 @@ class \nodoc\ _TestRepoJsonConverterPreservesValues h.assert_eq[String]( "rgit_" + b, repo.git_url) if (mask and 8) != 0 then - match repo.mirror_url + match \exhaustive\ repo.mirror_url | None => None | let _: String => h.fail( "mirror_url should be None") end else - match repo.mirror_url + match \exhaustive\ repo.mirror_url | let s: String => h.assert_eq[String]( "rmirror_" + b, s) @@ -1600,7 +1701,7 @@ class \nodoc\ _TestRepoJsonConverterPreservesValues end })? -class \nodoc\ _TestRepoJsonConverterMissingField +class \nodoc\ _TestRepoJSONConverterMissingField is UnitTest fun name(): String => "repo-json-converter/missing-field" @@ -1654,16 +1755,17 @@ class \nodoc\ _TestRepoJsonConverterMissingField end, recover val Generators.usize(0, 68) - end, h)( + end, + h)( {(base, skip_idx, h)(required) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) let b: String val = base.clone() try - let obj = _TestRepositoryJson(b) + let obj = _TestRepositoryJSON(b) .remove(required(skip_idx)?) let json = JsonNav(obj) - RepositoryJsonConverter(json, creds)? + RepositoryJSONConverter(json, creds)? h.fail( "converter should have raised for " + "missing field at index " @@ -1671,7 +1773,7 @@ class \nodoc\ _TestRepoJsonConverterMissingField end })? -class \nodoc\ _TestRepoJsonConverterAbsentOptionalFields +class \nodoc\ _TestRepoJSONConverterAbsentOptionalFields is UnitTest fun name(): String => "repo-json-converter/absent-optional-fields" @@ -1680,12 +1782,13 @@ class \nodoc\ _TestRepoJsonConverterAbsentOptionalFields PonyCheck.for_all[String]( recover val Generators.ascii_printable(1, 20) - end, h)( + end, + h)( {(base, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) let b: String val = base.clone() - let obj = _TestRepositoryJson(b) + let obj = _TestRepositoryJSON(b) .remove("organization") .remove("license") .remove("network_count") @@ -1693,42 +1796,44 @@ class \nodoc\ _TestRepoJsonConverterAbsentOptionalFields let json = JsonNav(obj) try let repo = - RepositoryJsonConverter(json, creds)? - match repo.organization + RepositoryJSONConverter(json, creds)? + match \exhaustive\ repo.organization | None => None | let _: User => h.fail( "organization should be None") end - match repo.license + match \exhaustive\ repo.license | None => None | let _: License => h.fail("license should be None") end - match repo.network_count + match \exhaustive\ repo.network_count | None => None | let _: I64 => h.fail( "network_count should be None") end - match repo.subscribers_count + match \exhaustive\ repo.subscribers_count | None => None | let _: I64 => h.fail( "subscribers_count should be " + "None") end - h.assert_eq[String]("rname_" + b, + h.assert_eq[String]( + "rname_" + b, repo.name) h.assert_eq[I64](I64(1), repo.id) - h.assert_eq[String]("rurl_" + b, + h.assert_eq[String]( + "rurl_" + b, repo.url) else h.fail("converter raised an error") end })? -class \nodoc\ _TestGistJsonConverterPreservesValues +class \nodoc\ _TestGistJSONConverterPreservesValues is UnitTest fun name(): String => "gist-json-converter/preserves-values" @@ -1738,32 +1843,35 @@ class \nodoc\ _TestGistJsonConverterPreservesValues recover val Generators.ascii_printable(1, 20) end, - recover val Generators.bool() end, h)( + recover val Generators.bool() end, + h)( {(base, desc_is_null, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) let b: String val = base.clone() - var obj = _TestGistJson(b) + var obj = _TestGistJSON(b) if desc_is_null then obj = obj.update("description", None) end let json = JsonNav(obj) try let gist = - GistJsonConverter(json, creds)? - h.assert_eq[String]("gid_" + b, + GistJSONConverter(json, creds)? + h.assert_eq[String]( + "gid_" + b, gist.id) - h.assert_eq[String]("gnid_" + b, + h.assert_eq[String]( + "gnid_" + b, gist.node_id) if desc_is_null then - match gist.description + match \exhaustive\ gist.description | None => None | let _: String => h.fail( "description should be None") end else - match gist.description + match \exhaustive\ gist.description | let s: String => h.assert_eq[String]( "gdesc_" + b, s) @@ -1772,9 +1880,11 @@ class \nodoc\ _TestGistJsonConverterPreservesValues "description should be String") end end - h.assert_true(gist.public, + h.assert_true( + gist.public, "public should be true") - h.assert_eq[USize](1, + h.assert_eq[USize]( + 1, gist.files.size()) try h.assert_eq[String]( @@ -1787,20 +1897,26 @@ class \nodoc\ _TestGistJsonConverterPreservesValues h.fail( "files array access raised error") end - h.assert_eq[I64](I64(5), + h.assert_eq[I64]( + I64(5), gist.comments) h.assert_false( gist.comments_enabled, "comments_enabled should be false") - h.assert_false(gist.truncated, + h.assert_false( + gist.truncated, "truncated should be false") - h.assert_eq[String]("gca_" + b, + h.assert_eq[String]( + "gca_" + b, gist.created_at) - h.assert_eq[String]("gua_" + b, + h.assert_eq[String]( + "gua_" + b, gist.updated_at) - h.assert_eq[String]("gurl_" + b, + h.assert_eq[String]( + "gurl_" + b, gist.url) - h.assert_eq[String]("ghurl_" + b, + h.assert_eq[String]( + "ghurl_" + b, gist.html_url) h.assert_eq[String]( "gforksurl_" + b, @@ -1817,16 +1933,18 @@ class \nodoc\ _TestGistJsonConverterPreservesValues h.assert_eq[String]( "gpushurl_" + b, gist.git_push_url) - match gist.owner + match \exhaustive\ gist.owner | let u: User => - h.assert_eq[String]("login_" + b, + h.assert_eq[String]( + "login_" + b, u.login) | None => h.fail("owner should be present") end - match gist.user + match \exhaustive\ gist.user | let u: User => - h.assert_eq[String]("login_" + b, + h.assert_eq[String]( + "login_" + b, u.login) | None => h.fail("user should be present") @@ -1836,7 +1954,7 @@ class \nodoc\ _TestGistJsonConverterPreservesValues end })? -class \nodoc\ _TestGistJsonConverterMissingField +class \nodoc\ _TestGistJSONConverterMissingField is UnitTest fun name(): String => "gist-json-converter/missing-field" @@ -1860,16 +1978,17 @@ class \nodoc\ _TestGistJsonConverterMissingField end, recover val Generators.usize(0, 15) - end, h)( + end, + h)( {(base, skip_idx, h)(required) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) let b: String val = base.clone() try - let obj = _TestGistJson(b) + let obj = _TestGistJSON(b) .remove(required(skip_idx)?) let json = JsonNav(obj) - GistJsonConverter(json, creds)? + GistJSONConverter(json, creds)? h.fail( "converter should have raised for " + "missing field at index " @@ -1877,7 +1996,7 @@ class \nodoc\ _TestGistJsonConverterMissingField end })? -class \nodoc\ _TestGistJsonConverterAbsentOptionalFields +class \nodoc\ _TestGistJSONConverterAbsentOptionalFields is UnitTest fun name(): String => "gist-json-converter/absent-optional-fields" @@ -1886,25 +2005,26 @@ class \nodoc\ _TestGistJsonConverterAbsentOptionalFields PonyCheck.for_all[String]( recover val Generators.ascii_printable(1, 20) - end, h)( + end, + h)( {(base, h) => let auth = lori.TCPConnectAuth(h.env.root) let creds = req.Credentials(auth) let b: String val = base.clone() - let obj = _TestGistJson(b) + let obj = _TestGistJSON(b) .remove("owner") .remove("user") .remove("comments_enabled") let json = JsonNav(obj) try let gist = - GistJsonConverter(json, creds)? - match gist.owner + GistJSONConverter(json, creds)? + match \exhaustive\ gist.owner | None => None | let _: User => h.fail("owner should be None") end - match gist.user + match \exhaustive\ gist.user | None => None | let _: User => h.fail("user should be None") @@ -1913,9 +2033,11 @@ class \nodoc\ _TestGistJsonConverterAbsentOptionalFields gist.comments_enabled, "comments_enabled should default " + "to true") - h.assert_eq[String]("gid_" + b, + h.assert_eq[String]( + "gid_" + b, gist.id) - h.assert_eq[String]("gurl_" + b, + h.assert_eq[String]( + "gurl_" + b, gist.url) else h.fail("converter raised an error") @@ -1931,13 +2053,14 @@ class \nodoc\ _TestStringOrNoneReturnsString PonyCheck.for_all[String]( recover val Generators.ascii_printable(1, 20) - end, h)( + end, + h)( {(base, h) => let b: String val = base.clone() let obj = JsonObject.update("key", b) let json = JsonNav(obj) try - match JsonNavUtil.string_or_none( + match \exhaustive\ JSONNavUtil.string_or_none( json("key"))? | let s: String => h.assert_eq[String](b, s) @@ -1959,7 +2082,7 @@ class \nodoc\ _TestStringOrNoneReturnsNone fun ref apply(h: TestHelper) ? => let obj = JsonObject.update("key", None) let json = JsonNav(obj) - match JsonNavUtil.string_or_none( + match \exhaustive\ JSONNavUtil.string_or_none( json("key"))? | None => None | let _: String => @@ -1974,13 +2097,14 @@ class \nodoc\ _TestStringOrNoneRaisesOnInvalid fun ref apply(h: TestHelper) ? => PonyCheck.for_all[I64]( - recover val Generators.i64() end, h)( + recover val Generators.i64() end, + h)( {(value, h) => let obj = JsonObject.update("key", value) let json = JsonNav(obj) try - JsonNavUtil.string_or_none( + JSONNavUtil.string_or_none( json("key"))? h.fail( "should raise for I64 value " @@ -1991,19 +2115,20 @@ class \nodoc\ _TestStringOrNoneRaisesOnInvalid let empty = JsonObject let json = JsonNav(empty) try - JsonNavUtil.string_or_none( + JSONNavUtil.string_or_none( json("missing"))? h.fail("should raise for missing key") end -class \nodoc\ _TestJsonTypeStringAllArms is UnitTest +class \nodoc\ _TestJSONTypeStringAllArms is UnitTest fun name(): String => "json-type-string/all-arms" fun ref apply(h: TestHelper) => let obj = JsonObject.update("a", "b") let arr = JsonArray.push("x") - let nav = JsonNav( + let nav = + JsonNav( JsonObject .update("obj", obj) .update("arr", arr) @@ -2012,35 +2137,45 @@ class \nodoc\ _TestJsonTypeStringAllArms is UnitTest .update("f64", F64(3.14)) .update("bool", true) .update("null", None)) - h.assert_eq[String](obj.print(), - req.JsonTypeString(nav("obj"))) - h.assert_eq[String](arr.print(), - req.JsonTypeString(nav("arr"))) - h.assert_eq[String]("hello", - req.JsonTypeString(nav("str"))) - h.assert_eq[String](I64(42).string(), - req.JsonTypeString(nav("i64"))) - h.assert_eq[String](F64(3.14).string(), - req.JsonTypeString(nav("f64"))) - h.assert_eq[String]("true", - req.JsonTypeString(nav("bool"))) - h.assert_eq[String]("null", - req.JsonTypeString(nav("null"))) - h.assert_eq[String]("JsonNotFound", - req.JsonTypeString(nav("missing"))) - -class \nodoc\ _TestJsonTypeStringI64Property + h.assert_eq[String]( + obj.print(), + req.JSONTypeString(nav("obj"))) + h.assert_eq[String]( + arr.print(), + req.JSONTypeString(nav("arr"))) + h.assert_eq[String]( + "hello", + req.JSONTypeString(nav("str"))) + h.assert_eq[String]( + I64(42).string(), + req.JSONTypeString(nav("i64"))) + h.assert_eq[String]( + F64(3.14).string(), + req.JSONTypeString(nav("f64"))) + h.assert_eq[String]( + "true", + req.JSONTypeString(nav("bool"))) + h.assert_eq[String]( + "null", + req.JSONTypeString(nav("null"))) + h.assert_eq[String]( + "JsonNotFound", + req.JSONTypeString(nav("missing"))) + +class \nodoc\ _TestJSONTypeStringI64Property is UnitTest fun name(): String => "json-type-string/i64-property" fun ref apply(h: TestHelper) ? => PonyCheck.for_all[I64]( - recover val Generators.i64() end, h)( + recover val Generators.i64() end, + h)( {(value, h) => let obj = JsonObject.update("k", value) let json = JsonNav(obj) - h.assert_eq[String](value.string(), - req.JsonTypeString(json("k"))) + h.assert_eq[String]( + value.string(), + req.JSONTypeString(json("k"))) })? diff --git a/github_rest_api/_test_mock_http_server.pony b/github_rest_api/_test_mock_http_server.pony index bf0e8db..f109c1f 100644 --- a/github_rest_api/_test_mock_http_server.pony +++ b/github_rest_api/_test_mock_http_server.pony @@ -22,13 +22,13 @@ primitive \nodoc\ _TestSSLContext let file_auth = FileAuth(h.env.root) recover val ssl.SSLContext - .>set_authority( + .> set_authority( FilePath(file_auth, "assets/cert.pem"))? - .>set_cert( + .> set_cert( FilePath(file_auth, "assets/cert.pem"), FilePath(file_auth, "assets/key.pem"))? - .>set_client_verify(false) - .>set_server_verify(false) + .> set_client_verify(false) + .> set_server_verify(false) end // Type aliases can't carry annotations; the underscore prefix keeps it @@ -57,7 +57,8 @@ actor \nodoc\ _MockHTTPListener is lori.TCPListenerActor _sslctx = sslctx _responder = responder _on_listening_cb = on_listening_cb - _tcp_listener = lori.TCPListener( + _tcp_listener = + lori.TCPListener( lori.TCPListenAuth(h.env.root), _TestHost(), port, @@ -93,7 +94,8 @@ actor \nodoc\ _MockHTTPConnection responder: _Responder) => _responder = responder - _tcp_connection = lori.TCPConnection.ssl_server( + _tcp_connection = + lori.TCPConnection.ssl_server( server_auth, sslctx, fd, diff --git a/github_rest_api/_test_request_actors.pony b/github_rest_api/_test_request_actors.pony index 983ce3e..2eaeb9b 100644 --- a/github_rest_api/_test_request_actors.pony +++ b/github_rest_api/_test_request_actors.pony @@ -6,7 +6,7 @@ use ssl = "ssl/net" // --- Test receiver actors --- -actor \nodoc\ _TestJsonSuccessReceiver is req.JsonRequesterResultReceiver +actor \nodoc\ _TestJSONSuccessReceiver is req.JSONRequesterResultReceiver let _h: TestHelper let _expected_key: String let _expected_value: String @@ -35,7 +35,7 @@ actor \nodoc\ _TestJsonSuccessReceiver is req.JsonRequesterResultReceiver + " body=" + response_body + " msg=" + message) _h.complete(false) -actor \nodoc\ _TestJsonFailureReceiver is req.JsonRequesterResultReceiver +actor \nodoc\ _TestJSONFailureReceiver is req.JSONRequesterResultReceiver let _h: TestHelper let _expected_status: U16 let _expected_body: String @@ -195,8 +195,7 @@ actor \nodoc\ _TestLinkedFailureReceiver is LinkedResultReceiver _h.complete(true) // --- Test classes --- - -class \nodoc\ _TestJsonRequesterGetSuccess is UnitTest +class \nodoc\ _TestJSONRequesterGetSuccess is UnitTest fun name(): String => "request-actors/json-requester/get-success" fun ref apply(h: TestHelper) ? => @@ -204,10 +203,11 @@ class \nodoc\ _TestJsonRequesterGetSuccess is UnitTest let sslctx = _TestSSLContext(h)? let host = _TestHost() let port: String = "48100" - let url = _TestUrl(host, port, "/test") - let creds = req.Credentials( + let url = _TestURL(host, port, "/test") + let creds = + req.Credentials( lori.TCPConnectAuth(h.env.root) where ssl_ctx' = sslctx) - let receiver = _TestJsonSuccessReceiver(h, "greeting", "hello") + let receiver = _TestJSONSuccessReceiver(h, "greeting", "hello") let responder: _Responder = {(request: String): String => let body = """{"greeting":"hello"}""" @@ -216,13 +216,18 @@ class \nodoc\ _TestJsonRequesterGetSuccess is UnitTest + "\r\n" + body } val - let listener = _MockHTTPListener(h, port, sslctx, responder, + let listener = + _MockHTTPListener( + h, + port, + sslctx, + responder, {()(creds, url, receiver) => - req.JsonRequester.get(creds, url, receiver) + req.JSONRequester.get(creds, url, receiver) } val) h.dispose_when_done(listener) -class \nodoc\ _TestJsonRequesterGetFailure is UnitTest +class \nodoc\ _TestJSONRequesterGetFailure is UnitTest fun name(): String => "request-actors/json-requester/get-failure" fun ref apply(h: TestHelper) ? => @@ -230,10 +235,11 @@ class \nodoc\ _TestJsonRequesterGetFailure is UnitTest let sslctx = _TestSSLContext(h)? let host = _TestHost() let port: String = "48101" - let url = _TestUrl(host, port, "/missing") - let creds = req.Credentials( + let url = _TestURL(host, port, "/missing") + let creds = + req.Credentials( lori.TCPConnectAuth(h.env.root) where ssl_ctx' = sslctx) - let receiver = _TestJsonFailureReceiver(h, 404, "not found here", "") + let receiver = _TestJSONFailureReceiver(h, 404, "not found here", "") let responder: _Responder = {(request: String): String => let body = "not found here" @@ -242,13 +248,18 @@ class \nodoc\ _TestJsonRequesterGetFailure is UnitTest + "\r\n" + body } val - let listener = _MockHTTPListener(h, port, sslctx, responder, + let listener = + _MockHTTPListener( + h, + port, + sslctx, + responder, {()(creds, url, receiver) => - req.JsonRequester.get(creds, url, receiver) + req.JSONRequester.get(creds, url, receiver) } val) h.dispose_when_done(listener) -class \nodoc\ _TestJsonRequesterPostSuccess is UnitTest +class \nodoc\ _TestJSONRequesterPostSuccess is UnitTest fun name(): String => "request-actors/json-requester/post-success" fun ref apply(h: TestHelper) ? => @@ -256,10 +267,11 @@ class \nodoc\ _TestJsonRequesterPostSuccess is UnitTest let sslctx = _TestSSLContext(h)? let host = _TestHost() let port: String = "48102" - let url = _TestUrl(host, port, "/create") - let creds = req.Credentials( + let url = _TestURL(host, port, "/create") + let creds = + req.Credentials( lori.TCPConnectAuth(h.env.root) where ssl_ctx' = sslctx) - let receiver = _TestJsonSuccessReceiver(h, "id", "42") + let receiver = _TestJSONSuccessReceiver(h, "id", "42") let responder: _Responder = {(request: String): String => let body = """{"id":"42"}""" @@ -268,13 +280,18 @@ class \nodoc\ _TestJsonRequesterPostSuccess is UnitTest + "\r\n" + body } val - let listener = _MockHTTPListener(h, port, sslctx, responder, + let listener = + _MockHTTPListener( + h, + port, + sslctx, + responder, {()(creds, url, receiver) => - req.JsonRequester.post(creds, url, "{}", receiver) + req.JSONRequester.post(creds, url, "{}", receiver) } val) h.dispose_when_done(listener) -class \nodoc\ _TestJsonRequesterGetRedirect is UnitTest +class \nodoc\ _TestJSONRequesterGetRedirect is UnitTest fun name(): String => "request-actors/json-requester/get-redirect" fun ref apply(h: TestHelper) ? => @@ -282,11 +299,12 @@ class \nodoc\ _TestJsonRequesterGetRedirect is UnitTest let sslctx = _TestSSLContext(h)? let host = _TestHost() let port: String = "48103" - let url = _TestUrl(host, port, "/original") - let redirect_target = _TestUrl(host, port, "/redirected") - let creds = req.Credentials( + let url = _TestURL(host, port, "/original") + let redirect_target = _TestURL(host, port, "/redirected") + let creds = + req.Credentials( lori.TCPConnectAuth(h.env.root) where ssl_ctx' = sslctx) - let receiver = _TestJsonSuccessReceiver(h, "status", "redirected") + let receiver = _TestJSONSuccessReceiver(h, "status", "redirected") let responder: _Responder = {(request: String)(redirect_target): String => if request.contains("GET /redirected") then @@ -302,13 +320,18 @@ class \nodoc\ _TestJsonRequesterGetRedirect is UnitTest + "\r\n" end } val - let listener = _MockHTTPListener(h, port, sslctx, responder, + let listener = + _MockHTTPListener( + h, + port, + sslctx, + responder, {()(creds, url, receiver) => - req.JsonRequester.get(creds, url, receiver) + req.JSONRequester.get(creds, url, receiver) } val) h.dispose_when_done(listener) -class \nodoc\ _TestJsonRequesterGetParseError is UnitTest +class \nodoc\ _TestJSONRequesterGetParseError is UnitTest fun name(): String => "request-actors/json-requester/get-parse-error" @@ -317,10 +340,12 @@ class \nodoc\ _TestJsonRequesterGetParseError is UnitTest let sslctx = _TestSSLContext(h)? let host = _TestHost() let port: String = "48104" - let url = _TestUrl(host, port, "/bad-json") - let creds = req.Credentials( + let url = _TestURL(host, port, "/bad-json") + let creds = + req.Credentials( lori.TCPConnectAuth(h.env.root) where ssl_ctx' = sslctx) - let receiver = _TestJsonFailureReceiver( + let receiver = + _TestJSONFailureReceiver( h, 200, "", "Failed to parse response") let responder: _Responder = {(request: String): String => @@ -330,9 +355,14 @@ class \nodoc\ _TestJsonRequesterGetParseError is UnitTest + "\r\n" + body } val - let listener = _MockHTTPListener(h, port, sslctx, responder, + let listener = + _MockHTTPListener( + h, + port, + sslctx, + responder, {()(creds, url, receiver) => - req.JsonRequester.get(creds, url, receiver) + req.JSONRequester.get(creds, url, receiver) } val) h.dispose_when_done(listener) @@ -345,8 +375,9 @@ class \nodoc\ _TestNoContentDeleteSuccess is UnitTest let sslctx = _TestSSLContext(h)? let host = _TestHost() let port: String = "48105" - let url = _TestUrl(host, port, "/delete-me") - let creds = req.Credentials( + let url = _TestURL(host, port, "/delete-me") + let creds = + req.Credentials( lori.TCPConnectAuth(h.env.root) where ssl_ctx' = sslctx) let receiver = _TestDeleteSuccessReceiver(h) let responder: _Responder = @@ -355,7 +386,12 @@ class \nodoc\ _TestNoContentDeleteSuccess is UnitTest + "Content-Length: 0\r\n" + "\r\n" } val - let listener = _MockHTTPListener(h, port, sslctx, responder, + let listener = + _MockHTTPListener( + h, + port, + sslctx, + responder, {()(creds, url, receiver) => req.NoContentRequester.delete(creds, url, receiver) } val) @@ -370,8 +406,9 @@ class \nodoc\ _TestNoContentDeleteFailure is UnitTest let sslctx = _TestSSLContext(h)? let host = _TestHost() let port: String = "48106" - let url = _TestUrl(host, port, "/no-access") - let creds = req.Credentials( + let url = _TestURL(host, port, "/no-access") + let creds = + req.Credentials( lori.TCPConnectAuth(h.env.root) where ssl_ctx' = sslctx) let receiver = _TestDeleteFailureReceiver(h, 403, "forbidden") let responder: _Responder = @@ -382,7 +419,12 @@ class \nodoc\ _TestNoContentDeleteFailure is UnitTest + "\r\n" + body } val - let listener = _MockHTTPListener(h, port, sslctx, responder, + let listener = + _MockHTTPListener( + h, + port, + sslctx, + responder, {()(creds, url, receiver) => req.NoContentRequester.delete(creds, url, receiver) } val) @@ -396,8 +438,9 @@ class \nodoc\ _TestCheckRequester204 is UnitTest let sslctx = _TestSSLContext(h)? let host = _TestHost() let port: String = "48107" - let url = _TestUrl(host, port, "/starred") - let creds = req.Credentials( + let url = _TestURL(host, port, "/starred") + let creds = + req.Credentials( lori.TCPConnectAuth(h.env.root) where ssl_ctx' = sslctx) let receiver = _TestCheckSuccessReceiver(h, true) let responder: _Responder = @@ -406,7 +449,12 @@ class \nodoc\ _TestCheckRequester204 is UnitTest + "Content-Length: 0\r\n" + "\r\n" } val - let listener = _MockHTTPListener(h, port, sslctx, responder, + let listener = + _MockHTTPListener( + h, + port, + sslctx, + responder, {()(creds, url, receiver) => req.CheckRequester(creds, url, receiver) } val) @@ -420,8 +468,9 @@ class \nodoc\ _TestCheckRequester404 is UnitTest let sslctx = _TestSSLContext(h)? let host = _TestHost() let port: String = "48108" - let url = _TestUrl(host, port, "/not-starred") - let creds = req.Credentials( + let url = _TestURL(host, port, "/not-starred") + let creds = + req.Credentials( lori.TCPConnectAuth(h.env.root) where ssl_ctx' = sslctx) let receiver = _TestCheckSuccessReceiver(h, false) let responder: _Responder = @@ -430,7 +479,12 @@ class \nodoc\ _TestCheckRequester404 is UnitTest + "Content-Length: 0\r\n" + "\r\n" } val - let listener = _MockHTTPListener(h, port, sslctx, responder, + let listener = + _MockHTTPListener( + h, + port, + sslctx, + responder, {()(creds, url, receiver) => req.CheckRequester(creds, url, receiver) } val) @@ -444,8 +498,9 @@ class \nodoc\ _TestCheckRequesterOther is UnitTest let sslctx = _TestSSLContext(h)? let host = _TestHost() let port: String = "48109" - let url = _TestUrl(host, port, "/broken") - let creds = req.Credentials( + let url = _TestURL(host, port, "/broken") + let creds = + req.Credentials( lori.TCPConnectAuth(h.env.root) where ssl_ctx' = sslctx) let receiver = _TestCheckFailureReceiver(h, 500, "server error") let responder: _Responder = @@ -456,7 +511,12 @@ class \nodoc\ _TestCheckRequesterOther is UnitTest + "\r\n" + body } val - let listener = _MockHTTPListener(h, port, sslctx, responder, + let listener = + _MockHTTPListener( + h, + port, + sslctx, + responder, {()(creds, url, receiver) => req.CheckRequester(creds, url, receiver) } val) @@ -471,12 +531,14 @@ class \nodoc\ _TestLinkedWithLink is UnitTest let sslctx = _TestSSLContext(h)? let host = _TestHost() let port: String = "48110" - let url = _TestUrl(host, port, "/list") - let creds = req.Credentials( + let url = _TestURL(host, port, "/list") + let creds = + req.Credentials( lori.TCPConnectAuth(h.env.root) where ssl_ctx' = sslctx) let link_value = "; rel=\"next\"" - let receiver = _TestLinkedSuccessReceiver( + let receiver = + _TestLinkedSuccessReceiver( h, "item", "one", link_value) let responder: _Responder = {(request: String)(link_value): String => @@ -487,9 +549,14 @@ class \nodoc\ _TestLinkedWithLink is UnitTest + "\r\n" + body } val - let listener = _MockHTTPListener(h, port, sslctx, responder, + let listener = + _MockHTTPListener( + h, + port, + sslctx, + responder, {()(creds, url, receiver) => - LinkedJsonRequester(creds, url, receiver) + LinkedJSONRequester(creds, url, receiver) } val) h.dispose_when_done(listener) @@ -502,8 +569,9 @@ class \nodoc\ _TestLinkedNoLink is UnitTest let sslctx = _TestSSLContext(h)? let host = _TestHost() let port: String = "48111" - let url = _TestUrl(host, port, "/list") - let creds = req.Credentials( + let url = _TestURL(host, port, "/list") + let creds = + req.Credentials( lori.TCPConnectAuth(h.env.root) where ssl_ctx' = sslctx) let receiver = _TestLinkedSuccessReceiver(h, "item", "two", "") let responder: _Responder = @@ -514,9 +582,14 @@ class \nodoc\ _TestLinkedNoLink is UnitTest + "\r\n" + body } val - let listener = _MockHTTPListener(h, port, sslctx, responder, + let listener = + _MockHTTPListener( + h, + port, + sslctx, + responder, {()(creds, url, receiver) => - LinkedJsonRequester(creds, url, receiver) + LinkedJSONRequester(creds, url, receiver) } val) h.dispose_when_done(listener) @@ -529,8 +602,9 @@ class \nodoc\ _TestLinkedFailure is UnitTest let sslctx = _TestSSLContext(h)? let host = _TestHost() let port: String = "48112" - let url = _TestUrl(host, port, "/broken") - let creds = req.Credentials( + let url = _TestURL(host, port, "/broken") + let creds = + req.Credentials( lori.TCPConnectAuth(h.env.root) where ssl_ctx' = sslctx) let receiver = _TestLinkedFailureReceiver(h, 500, "internal error") let responder: _Responder = @@ -541,9 +615,14 @@ class \nodoc\ _TestLinkedFailure is UnitTest + "\r\n" + body } val - let listener = _MockHTTPListener(h, port, sslctx, responder, + let listener = + _MockHTTPListener( + h, + port, + sslctx, + responder, {()(creds, url, receiver) => - LinkedJsonRequester(creds, url, receiver) + LinkedJSONRequester(creds, url, receiver) } val) h.dispose_when_done(listener) @@ -555,11 +634,12 @@ class \nodoc\ _TestBearerTokenSent is UnitTest let sslctx = _TestSSLContext(h)? let host = _TestHost() let port: String = "48113" - let url = _TestUrl(host, port, "/auth-check") - let creds = req.Credentials( + let url = _TestURL(host, port, "/auth-check") + let creds = + req.Credentials( lori.TCPConnectAuth(h.env.root) where token' = "ghp_test_token_12345", ssl_ctx' = sslctx) - let receiver = _TestJsonSuccessReceiver(h, "result", "ok") + let receiver = _TestJSONSuccessReceiver(h, "result", "ok") let responder: _Responder = {(request: String): String => let body = @@ -572,9 +652,14 @@ class \nodoc\ _TestBearerTokenSent is UnitTest + "\r\n" + body } val - let listener = _MockHTTPListener(h, port, sslctx, responder, + let listener = + _MockHTTPListener( + h, + port, + sslctx, + responder, {()(creds, url, receiver) => - req.JsonRequester.get(creds, url, receiver) + req.JSONRequester.get(creds, url, receiver) } val) h.dispose_when_done(listener) @@ -586,10 +671,11 @@ class \nodoc\ _TestNoTokenNoAuthHeader is UnitTest let sslctx = _TestSSLContext(h)? let host = _TestHost() let port: String = "48114" - let url = _TestUrl(host, port, "/no-auth-check") - let creds = req.Credentials( + let url = _TestURL(host, port, "/no-auth-check") + let creds = + req.Credentials( lori.TCPConnectAuth(h.env.root) where ssl_ctx' = sslctx) - let receiver = _TestJsonSuccessReceiver(h, "result", "ok") + let receiver = _TestJSONSuccessReceiver(h, "result", "ok") let responder: _Responder = {(request: String): String => let body = @@ -602,15 +688,19 @@ class \nodoc\ _TestNoTokenNoAuthHeader is UnitTest + "\r\n" + body } val - let listener = _MockHTTPListener(h, port, sslctx, responder, + let listener = + _MockHTTPListener( + h, + port, + sslctx, + responder, {()(creds, url, receiver) => - req.JsonRequester.get(creds, url, receiver) + req.JSONRequester.get(creds, url, receiver) } val) h.dispose_when_done(listener) // --- URL helper --- - -primitive \nodoc\ _TestUrl +primitive \nodoc\ _TestURL fun apply(host: String, port: String, path: String): String val => recover val "https://" + host + ":" + port + path diff --git a/github_rest_api/_test_result_receivers.pony b/github_rest_api/_test_result_receivers.pony index 1050f17..064e29f 100644 --- a/github_rest_api/_test_result_receivers.pony +++ b/github_rest_api/_test_result_receivers.pony @@ -4,7 +4,7 @@ use "promises" use "pony_test" use req = "request" -primitive \nodoc\ _TestStringConverter is req.JsonConverter[String] +primitive \nodoc\ _TestStringConverter is req.JSONConverter[String] fun apply(json: JsonNav, creds: req.Credentials): String ? => json("value").as_string()? @@ -16,7 +16,7 @@ class \nodoc\ _TestDeletedResultReceiverSuccess is UnitTest let p = Promise[req.DeletedOrError] p.next[None]( {(result: req.DeletedOrError)(h) => - match result + match \exhaustive\ result | let _: req.Deleted => h.complete(true) | let e: req.RequestError => @@ -35,7 +35,7 @@ class \nodoc\ _TestDeletedResultReceiverFailure is UnitTest let p = Promise[req.DeletedOrError] p.next[None]( {(result: req.DeletedOrError)(h) => - match result + match \exhaustive\ result | let _: req.Deleted => h.fail("Expected RequestError, got Deleted") h.complete(false) @@ -57,7 +57,7 @@ class \nodoc\ _TestBoolResultReceiverSuccessTrue is UnitTest let p = Promise[req.BoolOrError] p.next[None]( {(result: req.BoolOrError)(h) => - match result + match \exhaustive\ result | let b: Bool => h.assert_true(b, "Expected true") h.complete(true) @@ -77,7 +77,7 @@ class \nodoc\ _TestBoolResultReceiverSuccessFalse is UnitTest let p = Promise[req.BoolOrError] p.next[None]( {(result: req.BoolOrError)(h) => - match result + match \exhaustive\ result | let b: Bool => h.assert_false(b, "Expected false") h.complete(true) @@ -97,7 +97,7 @@ class \nodoc\ _TestBoolResultReceiverFailure is UnitTest let p = Promise[req.BoolOrError] p.next[None]( {(result: req.BoolOrError)(h) => - match result + match \exhaustive\ result | let _: Bool => h.fail("Expected RequestError, got Bool") h.complete(false) @@ -119,7 +119,7 @@ class \nodoc\ _TestResultReceiverSuccess is UnitTest let p = Promise[(String | req.RequestError)] p.next[None]( {(result: (String | req.RequestError))(h) => - match result + match \exhaustive\ result | let s: String => h.assert_eq[String]("hello", s) h.complete(true) @@ -130,7 +130,8 @@ class \nodoc\ _TestResultReceiverSuccess is UnitTest end }) let creds = req.Credentials(lori.TCPConnectAuth(h.env.root)) - let receiver = req.ResultReceiver[String]( + let receiver = + req.ResultReceiver[String]( creds, p, _TestStringConverter) let obj = JsonObject.update("value", "hello") receiver.success(JsonNav(obj)) @@ -143,7 +144,7 @@ class \nodoc\ _TestResultReceiverConverterError is UnitTest let p = Promise[(String | req.RequestError)] p.next[None]( {(result: (String | req.RequestError))(h) => - match result + match \exhaustive\ result | let _: String => h.fail("Expected RequestError, got String") h.complete(false) @@ -156,7 +157,8 @@ class \nodoc\ _TestResultReceiverConverterError is UnitTest end }) let creds = req.Credentials(lori.TCPConnectAuth(h.env.root)) - let receiver = req.ResultReceiver[String]( + let receiver = + req.ResultReceiver[String]( creds, p, _TestStringConverter) receiver.success(JsonNav(JsonObject)) @@ -168,7 +170,7 @@ class \nodoc\ _TestResultReceiverFailure is UnitTest let p = Promise[(String | req.RequestError)] p.next[None]( {(result: (String | req.RequestError))(h) => - match result + match \exhaustive\ result | let _: String => h.fail("Expected RequestError, got String") h.complete(false) @@ -180,7 +182,8 @@ class \nodoc\ _TestResultReceiverFailure is UnitTest end }) let creds = req.Credentials(lori.TCPConnectAuth(h.env.root)) - let receiver = req.ResultReceiver[String]( + let receiver = + req.ResultReceiver[String]( creds, p, _TestStringConverter) receiver.failure(500, "server error", "internal") @@ -192,7 +195,7 @@ class \nodoc\ _TestPaginatedResultReceiverSuccess is UnitTest let p = Promise[(PaginatedList[String] | req.RequestError)] p.next[None]( {(result: (PaginatedList[String] | req.RequestError))(h) => - match result + match \exhaustive\ result | let pl: PaginatedList[String] => h.assert_eq[USize](1, pl.results.size()) try @@ -209,9 +212,11 @@ class \nodoc\ _TestPaginatedResultReceiverSuccess is UnitTest end }) let creds = req.Credentials(lori.TCPConnectAuth(h.env.root)) - let converter = PaginatedListJsonConverter[String]( + let converter = + PaginatedListJSONConverter[String]( creds, _TestStringConverter) - let receiver = PaginatedResultReceiver[String]( + let receiver = + PaginatedResultReceiver[String]( creds, p, converter) let arr = JsonArray .push(JsonObject.update("value", "item1")) @@ -226,7 +231,7 @@ class \nodoc\ _TestPaginatedResultReceiverConverterError is UnitTest let p = Promise[(PaginatedList[String] | req.RequestError)] p.next[None]( {(result: (PaginatedList[String] | req.RequestError))(h) => - match result + match \exhaustive\ result | let _: PaginatedList[String] => h.fail("Expected RequestError, got PaginatedList") h.complete(false) @@ -239,9 +244,11 @@ class \nodoc\ _TestPaginatedResultReceiverConverterError is UnitTest end }) let creds = req.Credentials(lori.TCPConnectAuth(h.env.root)) - let converter = PaginatedListJsonConverter[String]( + let converter = + PaginatedListJSONConverter[String]( creds, _TestStringConverter) - let receiver = PaginatedResultReceiver[String]( + let receiver = + PaginatedResultReceiver[String]( creds, p, converter) receiver.success(JsonNav("not-an-array"), "") @@ -253,7 +260,7 @@ class \nodoc\ _TestPaginatedResultReceiverFailure is UnitTest let p = Promise[(PaginatedList[String] | req.RequestError)] p.next[None]( {(result: (PaginatedList[String] | req.RequestError))(h) => - match result + match \exhaustive\ result | let _: PaginatedList[String] => h.fail("Expected RequestError, got PaginatedList") h.complete(false) @@ -265,9 +272,11 @@ class \nodoc\ _TestPaginatedResultReceiverFailure is UnitTest end }) let creds = req.Credentials(lori.TCPConnectAuth(h.env.root)) - let converter = PaginatedListJsonConverter[String]( + let converter = + PaginatedListJSONConverter[String]( creds, _TestStringConverter) - let receiver = PaginatedResultReceiver[String]( + let receiver = + PaginatedResultReceiver[String]( creds, p, converter) receiver.failure(403, "forbidden", "auth failed") @@ -279,7 +288,7 @@ class \nodoc\ _TestSearchResultReceiverSuccess is UnitTest let p = Promise[(SearchResults[String] | req.RequestError)] p.next[None]( {(result: (SearchResults[String] | req.RequestError))(h) => - match result + match \exhaustive\ result | let sr: SearchResults[String] => h.assert_eq[I64](42, sr.total_count) h.assert_false(sr.incomplete_results) @@ -298,9 +307,11 @@ class \nodoc\ _TestSearchResultReceiverSuccess is UnitTest end }) let creds = req.Credentials(lori.TCPConnectAuth(h.env.root)) - let converter = PaginatedSearchJsonConverter[String]( + let converter = + PaginatedSearchJSONConverter[String]( creds, _TestStringConverter) - let receiver = SearchResultReceiver[String]( + let receiver = + SearchResultReceiver[String]( creds, p, converter) let items_arr = JsonArray .push(JsonObject.update("value", "result1")) @@ -319,7 +330,7 @@ class \nodoc\ _TestSearchResultReceiverConverterError is UnitTest let p = Promise[(SearchResults[String] | req.RequestError)] p.next[None]( {(result: (SearchResults[String] | req.RequestError))(h) => - match result + match \exhaustive\ result | let _: SearchResults[String] => h.fail("Expected RequestError, got SearchResults") h.complete(false) @@ -332,9 +343,11 @@ class \nodoc\ _TestSearchResultReceiverConverterError is UnitTest end }) let creds = req.Credentials(lori.TCPConnectAuth(h.env.root)) - let converter = PaginatedSearchJsonConverter[String]( + let converter = + PaginatedSearchJSONConverter[String]( creds, _TestStringConverter) - let receiver = SearchResultReceiver[String]( + let receiver = + SearchResultReceiver[String]( creds, p, converter) receiver.success(JsonNav(JsonObject), "") @@ -346,7 +359,7 @@ class \nodoc\ _TestSearchResultReceiverFailure is UnitTest let p = Promise[(SearchResults[String] | req.RequestError)] p.next[None]( {(result: (SearchResults[String] | req.RequestError))(h) => - match result + match \exhaustive\ result | let _: SearchResults[String] => h.fail("Expected RequestError, got SearchResults") h.complete(false) @@ -358,8 +371,10 @@ class \nodoc\ _TestSearchResultReceiverFailure is UnitTest end }) let creds = req.Credentials(lori.TCPConnectAuth(h.env.root)) - let converter = PaginatedSearchJsonConverter[String]( + let converter = + PaginatedSearchJSONConverter[String]( creds, _TestStringConverter) - let receiver = SearchResultReceiver[String]( + let receiver = + SearchResultReceiver[String]( creds, p, converter) receiver.failure(401, "unauthorized", "bad token") diff --git a/github_rest_api/_test_search_and_pagination.pony b/github_rest_api/_test_search_and_pagination.pony index 15a2c2b..080980f 100644 --- a/github_rest_api/_test_search_and_pagination.pony +++ b/github_rest_api/_test_search_and_pagination.pony @@ -13,7 +13,8 @@ class \nodoc\ _TestSearchConverterExtractsLinks is UnitTest fun ref apply(h: TestHelper) => h.long_test(2_000_000_000) let creds = req.Credentials(lori.TCPConnectAuth(h.env.root)) - let converter = PaginatedSearchJsonConverter[String]( + let converter = + PaginatedSearchJSONConverter[String]( creds, _TestStringConverter) let items_arr = JsonArray .push(JsonObject.update("value", "a")) @@ -22,7 +23,8 @@ class \nodoc\ _TestSearchConverterExtractsLinks is UnitTest .update("total_count", I64(10)) .update("incomplete_results", true) .update("items", items_arr) - let link = recover val + let link = + recover val "; rel=\"prev\", " + "; rel=\"next\"" end @@ -33,9 +35,11 @@ class \nodoc\ _TestSearchConverterExtractsLinks is UnitTest h.assert_eq[USize](2, sr.items.size()) h.assert_eq[String]("a", sr.items(0)?) h.assert_eq[String]("b", sr.items(1)?) - h.assert_true(sr.next_page() isnt None, + h.assert_true( + sr.next_page() isnt None, "next_page should not be None") - h.assert_true(sr.prev_page() isnt None, + h.assert_true( + sr.prev_page() isnt None, "prev_page should not be None") h.complete(true) else @@ -49,7 +53,8 @@ class \nodoc\ _TestSearchConverterNoLinks is UnitTest fun ref apply(h: TestHelper) => h.long_test(2_000_000_000) let creds = req.Credentials(lori.TCPConnectAuth(h.env.root)) - let converter = PaginatedSearchJsonConverter[String]( + let converter = + PaginatedSearchJSONConverter[String]( creds, _TestStringConverter) let items_arr = JsonArray .push(JsonObject.update("value", "x")) @@ -61,9 +66,11 @@ class \nodoc\ _TestSearchConverterNoLinks is UnitTest let sr = converter(JsonNav(envelope), "", creds)? h.assert_eq[USize](1, sr.items.size()) h.assert_eq[String]("x", sr.items(0)?) - h.assert_true(sr.next_page() is None, + h.assert_true( + sr.next_page() is None, "next_page should be None") - h.assert_true(sr.prev_page() is None, + h.assert_true( + sr.prev_page() is None, "prev_page should be None") h.complete(true) else @@ -77,12 +84,14 @@ class \nodoc\ _TestListConverterExtractsLinks is UnitTest fun ref apply(h: TestHelper) => h.long_test(2_000_000_000) let creds = req.Credentials(lori.TCPConnectAuth(h.env.root)) - let converter = PaginatedListJsonConverter[String]( + let converter = + PaginatedListJSONConverter[String]( creds, _TestStringConverter) let arr = JsonArray .push(JsonObject.update("value", "p")) .push(JsonObject.update("value", "q")) - let link = recover val + let link = + recover val "; rel=\"prev\", " + "; rel=\"next\"" end @@ -91,9 +100,11 @@ class \nodoc\ _TestListConverterExtractsLinks is UnitTest h.assert_eq[USize](2, pl.results.size()) h.assert_eq[String]("p", pl.results(0)?) h.assert_eq[String]("q", pl.results(1)?) - h.assert_true(pl.next_page() isnt None, + h.assert_true( + pl.next_page() isnt None, "next_page should not be None") - h.assert_true(pl.prev_page() isnt None, + h.assert_true( + pl.prev_page() isnt None, "prev_page should not be None") h.complete(true) else @@ -107,7 +118,8 @@ class \nodoc\ _TestListConverterNoLinks is UnitTest fun ref apply(h: TestHelper) => h.long_test(2_000_000_000) let creds = req.Credentials(lori.TCPConnectAuth(h.env.root)) - let converter = PaginatedListJsonConverter[String]( + let converter = + PaginatedListJSONConverter[String]( creds, _TestStringConverter) let arr = JsonArray .push(JsonObject.update("value", "z")) @@ -115,9 +127,11 @@ class \nodoc\ _TestListConverterNoLinks is UnitTest let pl = converter(JsonNav(arr), "", creds)? h.assert_eq[USize](1, pl.results.size()) h.assert_eq[String]("z", pl.results(0)?) - h.assert_true(pl.next_page() is None, + h.assert_true( + pl.next_page() is None, "next_page should be None") - h.assert_true(pl.prev_page() is None, + h.assert_true( + pl.prev_page() is None, "prev_page should be None") h.complete(true) else @@ -126,7 +140,6 @@ class \nodoc\ _TestListConverterNoLinks is UnitTest end // --- Mock HTTP tests: pagination behavior --- - class \nodoc\ _TestSearchNextPageFollowsLink is UnitTest fun name(): String => "search-pagination/search/next-page-follows-link" @@ -135,17 +148,19 @@ class \nodoc\ _TestSearchNextPageFollowsLink is UnitTest let sslctx = _TestSSLContext(h)? let host = _TestHost() let port: String = "48115" - let page1_url = _TestUrl(host, port, "/page1") - let creds = req.Credentials( + let page1_url = _TestURL(host, port, "/page1") + let creds = + req.Credentials( lori.TCPConnectAuth(h.env.root) where ssl_ctx' = sslctx) - let converter = PaginatedSearchJsonConverter[String]( + let converter = + PaginatedSearchJSONConverter[String]( creds, _TestStringConverter) let p = Promise[(SearchResults[String] | req.RequestError)] p.next[None]( {(result: (SearchResults[String] | req.RequestError))(h, creds, converter) => - match result + match \exhaustive\ result | let sr: SearchResults[String] => try h.assert_eq[USize](1, sr.items.size()) @@ -156,16 +171,17 @@ class \nodoc\ _TestSearchNextPageFollowsLink is UnitTest h.complete(false) return end - match sr.next_page() + match \exhaustive\ sr.next_page() | let p2: Promise[(SearchResults[String] | req.RequestError)] => p2.next[None]( {(result2: (SearchResults[String] | req.RequestError))(h) => - match result2 + match \exhaustive\ result2 | let sr2: SearchResults[String] => try h.assert_eq[USize](1, sr2.items.size()) h.assert_eq[String]("b", sr2.items(0)?) - h.assert_true(sr2.next_page() is None, + h.assert_true( + sr2.next_page() is None, "page 2 next_page should be None") h.complete(true) else @@ -187,19 +203,21 @@ class \nodoc\ _TestSearchNextPageFollowsLink is UnitTest end }) - let page2_link = _TestUrl(host, port, "/page2") + let page2_link = _TestURL(host, port, "/page2") let responder: _Responder = {(request: String)(page2_link): String => if request.contains("GET /page2") then let body = - """{"total_count":3,"incomplete_results":false,"items":[{"value":"b"}]}""" + """{"total_count":3,"incomplete_results":false,""" + + """"items":[{"value":"b"}]}""" "HTTP/1.1 200 OK\r\n" + "Content-Length: " + body.size().string() + "\r\n" + "\r\n" + body else let body = - """{"total_count":3,"incomplete_results":false,"items":[{"value":"a"}]}""" + """{"total_count":3,"incomplete_results":false,""" + + """"items":[{"value":"a"}]}""" "HTTP/1.1 200 OK\r\n" + "Content-Length: " + body.size().string() + "\r\n" + "Link: <" + page2_link + ">; rel=\"next\"\r\n" @@ -209,9 +227,14 @@ class \nodoc\ _TestSearchNextPageFollowsLink is UnitTest } val let receiver = SearchResultReceiver[String](creds, p, converter) - let listener = _MockHTTPListener(h, port, sslctx, responder, + let listener = + _MockHTTPListener( + h, + port, + sslctx, + responder, {()(creds, page1_url, receiver) => - LinkedJsonRequester(creds, page1_url, receiver) + LinkedJSONRequester(creds, page1_url, receiver) } val) h.dispose_when_done(listener) @@ -223,17 +246,19 @@ class \nodoc\ _TestSearchPrevPageFollowsLink is UnitTest let sslctx = _TestSSLContext(h)? let host = _TestHost() let port: String = "48116" - let page2_url = _TestUrl(host, port, "/page2") - let creds = req.Credentials( + let page2_url = _TestURL(host, port, "/page2") + let creds = + req.Credentials( lori.TCPConnectAuth(h.env.root) where ssl_ctx' = sslctx) - let converter = PaginatedSearchJsonConverter[String]( + let converter = + PaginatedSearchJSONConverter[String]( creds, _TestStringConverter) let p = Promise[(SearchResults[String] | req.RequestError)] p.next[None]( {(result: (SearchResults[String] | req.RequestError))(h, creds, converter) => - match result + match \exhaustive\ result | let sr: SearchResults[String] => try h.assert_eq[USize](1, sr.items.size()) @@ -243,16 +268,17 @@ class \nodoc\ _TestSearchPrevPageFollowsLink is UnitTest h.complete(false) return end - match sr.prev_page() + match \exhaustive\ sr.prev_page() | let p1: Promise[(SearchResults[String] | req.RequestError)] => p1.next[None]( {(result2: (SearchResults[String] | req.RequestError))(h) => - match result2 + match \exhaustive\ result2 | let sr2: SearchResults[String] => try h.assert_eq[USize](1, sr2.items.size()) h.assert_eq[String]("a", sr2.items(0)?) - h.assert_true(sr2.prev_page() is None, + h.assert_true( + sr2.prev_page() is None, "page 1 prev_page should be None") h.complete(true) else @@ -274,19 +300,21 @@ class \nodoc\ _TestSearchPrevPageFollowsLink is UnitTest end }) - let page1_link = _TestUrl(host, port, "/page1") + let page1_link = _TestURL(host, port, "/page1") let responder: _Responder = {(request: String)(page1_link): String => if request.contains("GET /page1") then let body = - """{"total_count":3,"incomplete_results":false,"items":[{"value":"a"}]}""" + """{"total_count":3,"incomplete_results":false,""" + + """"items":[{"value":"a"}]}""" "HTTP/1.1 200 OK\r\n" + "Content-Length: " + body.size().string() + "\r\n" + "\r\n" + body else let body = - """{"total_count":3,"incomplete_results":false,"items":[{"value":"b"}]}""" + """{"total_count":3,"incomplete_results":false,""" + + """"items":[{"value":"b"}]}""" "HTTP/1.1 200 OK\r\n" + "Content-Length: " + body.size().string() + "\r\n" + "Link: <" + page1_link + ">; rel=\"prev\"\r\n" @@ -296,9 +324,14 @@ class \nodoc\ _TestSearchPrevPageFollowsLink is UnitTest } val let receiver = SearchResultReceiver[String](creds, p, converter) - let listener = _MockHTTPListener(h, port, sslctx, responder, + let listener = + _MockHTTPListener( + h, + port, + sslctx, + responder, {()(creds, page2_url, receiver) => - LinkedJsonRequester(creds, page2_url, receiver) + LinkedJSONRequester(creds, page2_url, receiver) } val) h.dispose_when_done(listener) @@ -310,17 +343,19 @@ class \nodoc\ _TestListNextPageFollowsLink is UnitTest let sslctx = _TestSSLContext(h)? let host = _TestHost() let port: String = "48117" - let page1_url = _TestUrl(host, port, "/page1") - let creds = req.Credentials( + let page1_url = _TestURL(host, port, "/page1") + let creds = + req.Credentials( lori.TCPConnectAuth(h.env.root) where ssl_ctx' = sslctx) - let converter = PaginatedListJsonConverter[String]( + let converter = + PaginatedListJSONConverter[String]( creds, _TestStringConverter) let p = Promise[(PaginatedList[String] | req.RequestError)] p.next[None]( {(result: (PaginatedList[String] | req.RequestError))(h, creds, converter) => - match result + match \exhaustive\ result | let pl: PaginatedList[String] => try h.assert_eq[USize](1, pl.results.size()) @@ -330,16 +365,17 @@ class \nodoc\ _TestListNextPageFollowsLink is UnitTest h.complete(false) return end - match pl.next_page() + match \exhaustive\ pl.next_page() | let p2: Promise[(PaginatedList[String] | req.RequestError)] => p2.next[None]( {(result2: (PaginatedList[String] | req.RequestError))(h) => - match result2 + match \exhaustive\ result2 | let pl2: PaginatedList[String] => try h.assert_eq[USize](1, pl2.results.size()) h.assert_eq[String]("y", pl2.results(0)?) - h.assert_true(pl2.next_page() is None, + h.assert_true( + pl2.next_page() is None, "page 2 next_page should be None") h.complete(true) else @@ -361,7 +397,7 @@ class \nodoc\ _TestListNextPageFollowsLink is UnitTest end }) - let page2_link = _TestUrl(host, port, "/page2") + let page2_link = _TestURL(host, port, "/page2") let responder: _Responder = {(request: String)(page2_link): String => if request.contains("GET /page2") then @@ -381,9 +417,14 @@ class \nodoc\ _TestListNextPageFollowsLink is UnitTest } val let receiver = PaginatedResultReceiver[String](creds, p, converter) - let listener = _MockHTTPListener(h, port, sslctx, responder, + let listener = + _MockHTTPListener( + h, + port, + sslctx, + responder, {()(creds, page1_url, receiver) => - LinkedJsonRequester(creds, page1_url, receiver) + LinkedJSONRequester(creds, page1_url, receiver) } val) h.dispose_when_done(listener) @@ -395,17 +436,19 @@ class \nodoc\ _TestListPrevPageFollowsLink is UnitTest let sslctx = _TestSSLContext(h)? let host = _TestHost() let port: String = "48118" - let page2_url = _TestUrl(host, port, "/page2") - let creds = req.Credentials( + let page2_url = _TestURL(host, port, "/page2") + let creds = + req.Credentials( lori.TCPConnectAuth(h.env.root) where ssl_ctx' = sslctx) - let converter = PaginatedListJsonConverter[String]( + let converter = + PaginatedListJSONConverter[String]( creds, _TestStringConverter) let p = Promise[(PaginatedList[String] | req.RequestError)] p.next[None]( {(result: (PaginatedList[String] | req.RequestError))(h, creds, converter) => - match result + match \exhaustive\ result | let pl: PaginatedList[String] => try h.assert_eq[USize](1, pl.results.size()) @@ -415,16 +458,17 @@ class \nodoc\ _TestListPrevPageFollowsLink is UnitTest h.complete(false) return end - match pl.prev_page() + match \exhaustive\ pl.prev_page() | let p1: Promise[(PaginatedList[String] | req.RequestError)] => p1.next[None]( {(result2: (PaginatedList[String] | req.RequestError))(h) => - match result2 + match \exhaustive\ result2 | let pl2: PaginatedList[String] => try h.assert_eq[USize](1, pl2.results.size()) h.assert_eq[String]("x", pl2.results(0)?) - h.assert_true(pl2.prev_page() is None, + h.assert_true( + pl2.prev_page() is None, "page 1 prev_page should be None") h.complete(true) else @@ -446,7 +490,7 @@ class \nodoc\ _TestListPrevPageFollowsLink is UnitTest end }) - let page1_link = _TestUrl(host, port, "/page1") + let page1_link = _TestURL(host, port, "/page1") let responder: _Responder = {(request: String)(page1_link): String => if request.contains("GET /page1") then @@ -466,8 +510,13 @@ class \nodoc\ _TestListPrevPageFollowsLink is UnitTest } val let receiver = PaginatedResultReceiver[String](creds, p, converter) - let listener = _MockHTTPListener(h, port, sslctx, responder, + let listener = + _MockHTTPListener( + h, + port, + sslctx, + responder, {()(creds, page2_url, receiver) => - LinkedJsonRequester(creds, page2_url, receiver) + LinkedJSONRequester(creds, page2_url, receiver) } val) h.dispose_when_done(listener) diff --git a/github_rest_api/asset.pony b/github_rest_api/asset.pony index 795098f..a4446c8 100644 --- a/github_rest_api/asset.pony +++ b/github_rest_api/asset.pony @@ -7,7 +7,6 @@ class val Asset its name, size, download count, and the browser download URL. """ let _creds: req.Credentials - let id: I64 let node_id: String let name: String @@ -19,7 +18,6 @@ class val Asset let download_count: I64 let created_at: String let updated_at: String - let url: String let browser_download_url: String @@ -53,16 +51,19 @@ class val Asset url = url' browser_download_url = browser_download_url' -primitive AssetJsonConverter is req.JsonConverter[Asset] +primitive AssetJSONConverter is req.JSONConverter[Asset] """ Converts a JSON object into an Asset. """ fun apply(json: JsonNav, creds: req.Credentials): Asset ? => + """ + Parse a JSON object into an Asset. + """ let id = json("id").as_i64()? let node_id = json("node_id").as_string()? let name = json("name").as_string()? - let label = JsonNavUtil.string_or_none(json("label"))? - let uploader = UserJsonConverter(json("uploader"), creds)? + let label = JSONNavUtil.string_or_none(json("label"))? + let uploader = UserJSONConverter(json("uploader"), creds)? let content_type = json("content_type").as_string()? let state = json("state").as_string()? let size = json("size").as_i64()? @@ -72,7 +73,8 @@ primitive AssetJsonConverter is req.JsonConverter[Asset] let url = json("url").as_string()? let browser_download_url = json("browser_download_url").as_string()? - Asset(creds, + Asset( + creds, id, node_id, name, diff --git a/github_rest_api/commit.pony b/github_rest_api/commit.pony index 23cdf4b..9558bba 100644 --- a/github_rest_api/commit.pony +++ b/github_rest_api/commit.pony @@ -47,41 +47,49 @@ primitive GetCommit "https://api.github.com/repos{/owner}{/repo}/commits{/sha}") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("owner", owner) - .>set("repo", repo) - .>set("sha", sha) + .> set("owner", owner) + .> set("repo", repo) + .> set("sha", sha) let u: String val = tpl.expand(vars) by_url(u, creds) | let e: ut.URITemplateParseError => - Promise[CommitOrError].>apply(req.RequestError(where message' = e.message)) + Promise[CommitOrError] + .> apply(req.RequestError(where message' = e.message)) end fun by_url(url: String, creds: req.Credentials): Promise[CommitOrError] => + """ + Fetches a commit by its full API URL. + """ let p = Promise[CommitOrError] - let receiver = req.ResultReceiver[Commit](creds, p, CommitJsonConverter) + let receiver = req.ResultReceiver[Commit](creds, p, CommitJSONConverter) - req.JsonRequester.get(creds, url, receiver) + req.JSONRequester.get(creds, url, receiver) p -primitive CommitJsonConverter is req.JsonConverter[Commit] +primitive CommitJSONConverter is req.JSONConverter[Commit] """ Converts a JSON object from the commits API into a Commit. """ fun apply(json: JsonNav, creds: req.Credentials): Commit ? => + """ + Parse a JSON object into a Commit. + """ let sha = json("sha").as_string()? let files = recover trn Array[CommitFile] end for f in json("files").as_array()?.values() do - let file = CommitFileJsonConverter(JsonNav(f), creds)? + let file = CommitFileJSONConverter(JsonNav(f), creds)? files.push(file) end - let git_commit = GitCommitJsonConverter(json("commit"), creds)? + let git_commit = GitCommitJSONConverter(json("commit"), creds)? let url = json("url").as_string()? let html_url = json("html_url").as_string()? let comments_url = json("comments_url").as_string()? - Commit(creds, + Commit( + creds, sha, consume files, git_commit, diff --git a/github_rest_api/commit_file.pony b/github_rest_api/commit_file.pony index efb5c6d..25b23a7 100644 --- a/github_rest_api/commit_file.pony +++ b/github_rest_api/commit_file.pony @@ -21,13 +21,16 @@ class val CommitFile status = status' filename = filename' -primitive CommitFileJsonConverter is req.JsonConverter[CommitFile] +primitive CommitFileJSONConverter is req.JSONConverter[CommitFile] """ Converts a JSON object into a CommitFile. """ fun apply(json: JsonNav, creds: req.Credentials): CommitFile ? => + """ + Parse a JSON object into a CommitFile. + """ let sha = json("sha").as_string()? let status = json("status").as_string()? let filename = json("filename").as_string()? diff --git a/github_rest_api/gist.pony b/github_rest_api/gist.pony index f4465cf..ce1af61 100644 --- a/github_rest_api/gist.pony +++ b/github_rest_api/gist.pony @@ -166,22 +166,28 @@ primitive GetGist fun apply(gist_id: String, creds: req.Credentials): Promise[GistOrError] => - match \exhaustive\ ut.URITemplateParse("https://api.github.com/gists{/gist_id}") + match \exhaustive\ ut.URITemplateParse( + "https://api.github.com/gists{/gist_id}") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("gist_id", gist_id) + .> set("gist_id", gist_id) let u: String val = tpl.expand(vars) by_url(u, creds) | let e: ut.URITemplateParseError => - Promise[GistOrError].>apply( - req.RequestError(where message' = e.message)) + Promise[GistOrError] + .> apply(req.RequestError(where message' = e.message)) end - fun by_url(url: String, creds: req.Credentials): Promise[GistOrError] => + fun by_url(url: String, + creds: req.Credentials): Promise[GistOrError] + => + """ + Fetches a gist by its full API URL. + """ let p = Promise[GistOrError] - let r = req.ResultReceiver[Gist](creds, p, GistJsonConverter) + let r = req.ResultReceiver[Gist](creds, p, GistJSONConverter) - req.JsonRequester.get(creds, url, r) + req.JSONRequester.get(creds, url, r) p primitive CreateGist @@ -194,7 +200,8 @@ primitive CreateGist description: (String | None) = None, is_public: Bool = false): Promise[GistOrError] => - by_url("https://api.github.com/gists", + by_url( + "https://api.github.com/gists", files, creds, description, @@ -206,13 +213,18 @@ primitive CreateGist description: (String | None) = None, is_public: Bool = false): Promise[GistOrError] => + """ + Creates a gist by posting to the given API URL. + """ let p = Promise[GistOrError] - let r = req.ResultReceiver[Gist](creds, p, GistJsonConverter) + let r = req.ResultReceiver[Gist](creds, p, GistJSONConverter) var files_obj = JsonObject for (name, content) in files.values() do - files_obj = files_obj.update(name, - JsonObject.update("content", content)) + files_obj = + files_obj.update( + name, + JsonObject.update("content", content)) end var obj = JsonObject @@ -223,7 +235,7 @@ primitive CreateGist end let json = obj.print() - req.JsonRequester.post(creds, url, consume json, r) + req.JSONRequester.post(creds, url, consume json, r) p primitive UpdateGist @@ -238,15 +250,16 @@ primitive UpdateGist creds: req.Credentials, description: (String | None) = None): Promise[GistOrError] => - match \exhaustive\ ut.URITemplateParse("https://api.github.com/gists{/gist_id}") + match \exhaustive\ ut.URITemplateParse( + "https://api.github.com/gists{/gist_id}") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("gist_id", gist_id) + .> set("gist_id", gist_id) let u: String val = tpl.expand(vars) by_url(u, files, creds, description) | let e: ut.URITemplateParseError => - Promise[GistOrError].>apply( - req.RequestError(where message' = e.message)) + Promise[GistOrError] + .> apply(req.RequestError(where message' = e.message)) end fun by_url(url: String, @@ -254,15 +267,20 @@ primitive UpdateGist creds: req.Credentials, description: (String | None) = None): Promise[GistOrError] => + """ + Updates a gist by patching the given API URL. + """ let p = Promise[GistOrError] - let r = req.ResultReceiver[Gist](creds, p, GistJsonConverter) + let r = req.ResultReceiver[Gist](creds, p, GistJSONConverter) var files_obj = JsonObject for (name, update) in files.values() do match \exhaustive\ update | let edit: GistFileEdit => - files_obj = files_obj.update(name, - JsonObject.update("content", edit.content)) + files_obj = + files_obj.update( + name, + JsonObject.update("content", edit.content)) | let rename: GistFileRename => var entry = JsonObject.update("filename", rename.filename) match rename.content @@ -280,7 +298,7 @@ primitive UpdateGist end let json = obj.print() - req.JsonRequester.patch(creds, url, consume json, r) + req.JSONRequester.patch(creds, url, consume json, r) p primitive DeleteGist @@ -290,20 +308,24 @@ primitive DeleteGist fun apply(gist_id: String, creds: req.Credentials): Promise[req.DeletedOrError] => - match \exhaustive\ ut.URITemplateParse("https://api.github.com/gists{/gist_id}") + match \exhaustive\ ut.URITemplateParse( + "https://api.github.com/gists{/gist_id}") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("gist_id", gist_id) + .> set("gist_id", gist_id) let u: String val = tpl.expand(vars) by_url(u, creds) | let e: ut.URITemplateParseError => - Promise[req.DeletedOrError].>apply( - req.RequestError(where message' = e.message)) + Promise[req.DeletedOrError] + .> apply(req.RequestError(where message' = e.message)) end fun by_url(url: String, creds: req.Credentials): Promise[req.DeletedOrError] => + """ + Deletes a gist by its full API URL. + """ let p = Promise[req.DeletedOrError] let r = req.DeletedResultReceiver(p) @@ -326,7 +348,8 @@ primitive GetPublicGists fun apply(creds: req.Credentials) : Promise[(PaginatedList[Gist] | req.RequestError)] => - _GetPaginatedGists.by_url("https://api.github.com/gists/public", creds) + _GetPaginatedGists.by_url( + "https://api.github.com/gists/public", creds) primitive GetStarredGists """ @@ -335,7 +358,8 @@ primitive GetStarredGists fun apply(creds: req.Credentials) : Promise[(PaginatedList[Gist] | req.RequestError)] => - _GetPaginatedGists.by_url("https://api.github.com/gists/starred", creds) + _GetPaginatedGists.by_url( + "https://api.github.com/gists/starred", creds) primitive GetUsernameGists """ @@ -349,12 +373,12 @@ primitive GetUsernameGists "https://api.github.com/users{/username}/gists") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("username", username) + .> set("username", username) let u: String val = tpl.expand(vars) _GetPaginatedGists.by_url(u, creds) | let e: ut.URITemplateParseError => - Promise[(PaginatedList[Gist] | req.RequestError)].>apply( - req.RequestError(where message' = e.message)) + Promise[(PaginatedList[Gist] | req.RequestError)] + .> apply(req.RequestError(where message' = e.message)) end primitive GetGistRevision @@ -369,13 +393,13 @@ primitive GetGistRevision "https://api.github.com/gists{/gist_id}{/sha}") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("gist_id", gist_id) - .>set("sha", sha) + .> set("gist_id", gist_id) + .> set("sha", sha) let u: String val = tpl.expand(vars) GetGist.by_url(u, creds) | let e: ut.URITemplateParseError => - Promise[GistOrError].>apply( - req.RequestError(where message' = e.message)) + Promise[GistOrError] + .> apply(req.RequestError(where message' = e.message)) end primitive ForkGist @@ -389,21 +413,24 @@ primitive ForkGist "https://api.github.com/gists{/gist_id}/forks") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("gist_id", gist_id) + .> set("gist_id", gist_id) let u: String val = tpl.expand(vars) by_url(u, creds) | let e: ut.URITemplateParseError => - Promise[GistOrError].>apply( - req.RequestError(where message' = e.message)) + Promise[GistOrError] + .> apply(req.RequestError(where message' = e.message)) end fun by_url(url: String, creds: req.Credentials): Promise[GistOrError] => + """ + Forks a gist by posting to the given API URL. + """ let p = Promise[GistOrError] - let r = req.ResultReceiver[Gist](creds, p, GistJsonConverter) + let r = req.ResultReceiver[Gist](creds, p, GistJSONConverter) - req.JsonRequester.post(creds, url, "", r) + req.JSONRequester.post(creds, url, "", r) p primitive GetGistForks @@ -418,12 +445,12 @@ primitive GetGistForks "https://api.github.com/gists{/gist_id}/forks") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("gist_id", gist_id) + .> set("gist_id", gist_id) let u: String val = tpl.expand(vars) _GetPaginatedGists.by_url(u, creds) | let e: ut.URITemplateParseError => - Promise[(PaginatedList[Gist] | req.RequestError)].>apply( - req.RequestError(where message' = e.message)) + Promise[(PaginatedList[Gist] | req.RequestError)] + .> apply(req.RequestError(where message' = e.message)) end primitive GetGistCommits @@ -438,24 +465,27 @@ primitive GetGistCommits "https://api.github.com/gists{/gist_id}/commits") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("gist_id", gist_id) + .> set("gist_id", gist_id) let u: String val = tpl.expand(vars) by_url(u, creds) | let e: ut.URITemplateParseError => - Promise[(PaginatedList[GistCommit] | req.RequestError)].>apply( - req.RequestError(where message' = e.message)) + Promise[(PaginatedList[GistCommit] | req.RequestError)] + .> apply(req.RequestError(where message' = e.message)) end fun by_url(url: String, creds: req.Credentials) : Promise[(PaginatedList[GistCommit] | req.RequestError)] => - let gc = GistCommitJsonConverter - let plc = PaginatedListJsonConverter[GistCommit](creds, gc) + """ + Lists gist commits by fetching from the given API URL. + """ + let gc = GistCommitJSONConverter + let plc = PaginatedListJSONConverter[GistCommit](creds, gc) let p = Promise[(PaginatedList[GistCommit] | req.RequestError)] let r = PaginatedResultReceiver[GistCommit](creds, p, plc) - LinkedJsonRequester(creds, url, r) + LinkedJSONRequester(creds, url, r) p primitive StarGist @@ -469,17 +499,20 @@ primitive StarGist "https://api.github.com/gists{/gist_id}/star") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("gist_id", gist_id) + .> set("gist_id", gist_id) let u: String val = tpl.expand(vars) by_url(u, creds) | let e: ut.URITemplateParseError => - Promise[req.DeletedOrError].>apply( - req.RequestError(where message' = e.message)) + Promise[req.DeletedOrError] + .> apply(req.RequestError(where message' = e.message)) end fun by_url(url: String, creds: req.Credentials): Promise[req.DeletedOrError] => + """ + Stars a gist by sending a PUT to the given API URL. + """ let p = Promise[req.DeletedOrError] let r = req.DeletedResultReceiver(p) @@ -497,17 +530,20 @@ primitive UnstarGist "https://api.github.com/gists{/gist_id}/star") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("gist_id", gist_id) + .> set("gist_id", gist_id) let u: String val = tpl.expand(vars) by_url(u, creds) | let e: ut.URITemplateParseError => - Promise[req.DeletedOrError].>apply( - req.RequestError(where message' = e.message)) + Promise[req.DeletedOrError] + .> apply(req.RequestError(where message' = e.message)) end fun by_url(url: String, creds: req.Credentials): Promise[req.DeletedOrError] => + """ + Unstars a gist by sending a DELETE to the given API URL. + """ let p = Promise[req.DeletedOrError] let r = req.DeletedResultReceiver(p) @@ -526,17 +562,20 @@ primitive CheckGistStar "https://api.github.com/gists{/gist_id}/star") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("gist_id", gist_id) + .> set("gist_id", gist_id) let u: String val = tpl.expand(vars) by_url(u, creds) | let e: ut.URITemplateParseError => - Promise[req.BoolOrError].>apply( - req.RequestError(where message' = e.message)) + Promise[req.BoolOrError] + .> apply(req.RequestError(where message' = e.message)) end fun by_url(url: String, creds: req.Credentials): Promise[req.BoolOrError] => + """ + Checks a gist's star status by its full API URL. + """ let p = Promise[req.BoolOrError] let r = req.BoolResultReceiver(p) @@ -552,31 +591,34 @@ primitive _GetPaginatedGists creds: req.Credentials) : Promise[(PaginatedList[Gist] | req.RequestError)] => - let gc = GistJsonConverter - let plc = PaginatedListJsonConverter[Gist](creds, gc) + let gc = GistJSONConverter + let plc = PaginatedListJSONConverter[Gist](creds, gc) let p = Promise[(PaginatedList[Gist] | req.RequestError)] let r = PaginatedResultReceiver[Gist](creds, p, plc) - LinkedJsonRequester(creds, url, r) + LinkedJSONRequester(creds, url, r) p -primitive GistJsonConverter is req.JsonConverter[Gist] +primitive GistJSONConverter is req.JSONConverter[Gist] """ Converts a JSON object from the GitHub gist API into a Gist. Handles the files object by iterating its key-value pairs and converting each value with - GistFileJsonConverter. + GistFileJSONConverter. """ fun apply(json: JsonNav, creds: req.Credentials): Gist ? => + """ + Parse a JSON object into a Gist. + """ let id = json("id").as_string()? let node_id = json("node_id").as_string()? - let description = JsonNavUtil.string_or_none(json("description"))? + let description = JSONNavUtil.string_or_none(json("description"))? let public = json("public").as_bool()? - let owner = try UserJsonConverter(json("owner"), creds)? else None end - let user = try UserJsonConverter(json("user"), creds)? else None end + let owner = try UserJSONConverter(json("owner"), creds)? else None end + let user = try UserJSONConverter(json("user"), creds)? else None end let files = recover trn Array[(String, GistFile)] end for (name, value) in json("files").as_object()?.pairs() do - let gf = GistFileJsonConverter(JsonNav(value), creds)? + let gf = GistFileJSONConverter(JsonNav(value), creds)? files.push((name, gf)) end @@ -595,7 +637,8 @@ primitive GistJsonConverter is req.JsonConverter[Gist] let git_pull_url = json("git_pull_url").as_string()? let git_push_url = json("git_push_url").as_string()? - Gist(creds, + Gist( + creds, id, node_id, description, diff --git a/github_rest_api/gist_comment.pony b/github_rest_api/gist_comment.pony index 09c821d..b0e763a 100644 --- a/github_rest_api/gist_comment.pony +++ b/github_rest_api/gist_comment.pony @@ -64,24 +64,29 @@ primitive GetGistComment "https://api.github.com/gists{/gist_id}/comments{/comment_id}") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("gist_id", gist_id) - .>set("comment_id", comment_id.string()) + .> set("gist_id", gist_id) + .> set("comment_id", comment_id.string()) let u: String val = tpl.expand(vars) by_url(u, creds) | let e: ut.URITemplateParseError => - Promise[GistCommentOrError].>apply( - req.RequestError(where message' = e.message)) + Promise[GistCommentOrError] + .> apply(req.RequestError(where message' = e.message)) end fun by_url(url: String, creds: req.Credentials): Promise[GistCommentOrError] => + """ + Fetches a gist comment by its full API URL. + """ let p = Promise[GistCommentOrError] - let r = req.ResultReceiver[GistComment](creds, - p, - GistCommentJsonConverter) + let r = + req.ResultReceiver[GistComment]( + creds, + p, + GistCommentJSONConverter) - req.JsonRequester.get(creds, url, r) + req.JSONRequester.get(creds, url, r) p primitive GetGistComments @@ -96,24 +101,27 @@ primitive GetGistComments "https://api.github.com/gists{/gist_id}/comments") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("gist_id", gist_id) + .> set("gist_id", gist_id) let u: String val = tpl.expand(vars) by_url(u, creds) | let e: ut.URITemplateParseError => - Promise[(PaginatedList[GistComment] | req.RequestError)].>apply( - req.RequestError(where message' = e.message)) + Promise[(PaginatedList[GistComment] | req.RequestError)] + .> apply(req.RequestError(where message' = e.message)) end fun by_url(url: String, creds: req.Credentials) : Promise[(PaginatedList[GistComment] | req.RequestError)] => - let gc = GistCommentJsonConverter - let plc = PaginatedListJsonConverter[GistComment](creds, gc) + """ + Fetches gist comments by their full API URL. + """ + let gc = GistCommentJSONConverter + let plc = PaginatedListJSONConverter[GistComment](creds, gc) let p = Promise[(PaginatedList[GistComment] | req.RequestError)] let r = PaginatedResultReceiver[GistComment](creds, p, plc) - LinkedJsonRequester(creds, url, r) + LinkedJSONRequester(creds, url, r) p primitive CreateGistComment @@ -128,25 +136,30 @@ primitive CreateGistComment "https://api.github.com/gists{/gist_id}/comments") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("gist_id", gist_id) + .> set("gist_id", gist_id) let u: String val = tpl.expand(vars) by_url(u, body, creds) | let e: ut.URITemplateParseError => - Promise[GistCommentOrError].>apply( - req.RequestError(where message' = e.message)) + Promise[GistCommentOrError] + .> apply(req.RequestError(where message' = e.message)) end fun by_url(url: String, body: String, creds: req.Credentials): Promise[GistCommentOrError] => + """ + Creates a gist comment by posting to the given API URL. + """ let p = Promise[GistCommentOrError] - let r = req.ResultReceiver[GistComment](creds, - p, - GistCommentJsonConverter) + let r = + req.ResultReceiver[GistComment]( + creds, + p, + GistCommentJSONConverter) let json = JsonObject.update("body", body).print() - req.JsonRequester.post(creds, url, consume json, r) + req.JSONRequester.post(creds, url, consume json, r) p primitive UpdateGistComment @@ -162,26 +175,31 @@ primitive UpdateGistComment "https://api.github.com/gists{/gist_id}/comments{/comment_id}") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("gist_id", gist_id) - .>set("comment_id", comment_id.string()) + .> set("gist_id", gist_id) + .> set("comment_id", comment_id.string()) let u: String val = tpl.expand(vars) by_url(u, body, creds) | let e: ut.URITemplateParseError => - Promise[GistCommentOrError].>apply( - req.RequestError(where message' = e.message)) + Promise[GistCommentOrError] + .> apply(req.RequestError(where message' = e.message)) end fun by_url(url: String, body: String, creds: req.Credentials): Promise[GistCommentOrError] => + """ + Updates a gist comment by patching the given API URL. + """ let p = Promise[GistCommentOrError] - let r = req.ResultReceiver[GistComment](creds, - p, - GistCommentJsonConverter) + let r = + req.ResultReceiver[GistComment]( + creds, + p, + GistCommentJSONConverter) let json = JsonObject.update("body", body).print() - req.JsonRequester.patch(creds, url, consume json, r) + req.JSONRequester.patch(creds, url, consume json, r) p primitive DeleteGistComment @@ -196,39 +214,46 @@ primitive DeleteGistComment "https://api.github.com/gists{/gist_id}/comments{/comment_id}") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("gist_id", gist_id) - .>set("comment_id", comment_id.string()) + .> set("gist_id", gist_id) + .> set("comment_id", comment_id.string()) let u: String val = tpl.expand(vars) by_url(u, creds) | let e: ut.URITemplateParseError => - Promise[req.DeletedOrError].>apply( - req.RequestError(where message' = e.message)) + Promise[req.DeletedOrError] + .> apply(req.RequestError(where message' = e.message)) end fun by_url(url: String, creds: req.Credentials): Promise[req.DeletedOrError] => + """ + Deletes a gist comment by its full API URL. + """ let p = Promise[req.DeletedOrError] let r = req.DeletedResultReceiver(p) req.NoContentRequester.delete(creds, url, r) p -primitive GistCommentJsonConverter is req.JsonConverter[GistComment] +primitive GistCommentJSONConverter is req.JSONConverter[GistComment] """ Converts a JSON object from the gist comments API into a GistComment. """ fun apply(json: JsonNav, creds: req.Credentials): GistComment ? => + """ + Parse a JSON object into a GistComment. + """ let id = json("id").as_i64()? let node_id = json("node_id").as_string()? let url = json("url").as_string()? let body = json("body").as_string()? - let user = try UserJsonConverter(json("user"), creds)? else None end + let user = try UserJSONConverter(json("user"), creds)? else None end let author_association = json("author_association").as_string()? let created_at = json("created_at").as_string()? let updated_at = json("updated_at").as_string()? - GistComment(creds, + GistComment( + creds, id, node_id, url, diff --git a/github_rest_api/gist_commit.pony b/github_rest_api/gist_commit.pony index 9fa77e6..ba216af 100644 --- a/github_rest_api/gist_commit.pony +++ b/github_rest_api/gist_commit.pony @@ -14,12 +14,15 @@ class val GistChangeStatus deletions = deletions' total = total' -primitive GistChangeStatusJsonConverter is req.JsonConverter[GistChangeStatus] +primitive GistChangeStatusJSONConverter is req.JSONConverter[GistChangeStatus] """ Converts a JSON object representing a gist commit's change_status into a GistChangeStatus. """ fun apply(json: JsonNav, creds: req.Credentials): GistChangeStatus ? => + """ + Parse a JSON object into a GistChangeStatus. + """ let additions = json("additions").as_i64()? let deletions = json("deletions").as_i64()? let total = json("total").as_i64()? @@ -52,19 +55,23 @@ class val GistCommit change_status = change_status' user = user' -primitive GistCommitJsonConverter is req.JsonConverter[GistCommit] +primitive GistCommitJSONConverter is req.JSONConverter[GistCommit] """ Converts a JSON object from the gist commits endpoint into a GistCommit. """ fun apply(json: JsonNav, creds: req.Credentials): GistCommit ? => + """ + Parse a JSON object into a GistCommit. + """ let version = json("version").as_string()? let url = json("url").as_string()? let committed_at = json("committed_at").as_string()? let change_status = - GistChangeStatusJsonConverter(json("change_status"), creds)? - let user = try UserJsonConverter(json("user"), creds)? else None end + GistChangeStatusJSONConverter(json("change_status"), creds)? + let user = try UserJSONConverter(json("user"), creds)? else None end - GistCommit(creds, + GistCommit( + creds, version, url, committed_at, diff --git a/github_rest_api/gist_file.pony b/github_rest_api/gist_file.pony index a788881..4f15fc0 100644 --- a/github_rest_api/gist_file.pony +++ b/github_rest_api/gist_file.pony @@ -37,24 +37,28 @@ class val GistFile encoding = encoding' truncated = truncated' -primitive GistFileJsonConverter is req.JsonConverter[GistFile] +primitive GistFileJSONConverter is req.JSONConverter[GistFile] """ Converts a JSON object representing a single gist file into a GistFile. Optional fields that may be absent in list responses are extracted with try/else None. """ fun apply(json: JsonNav, creds: req.Credentials): GistFile ? => + """ + Parse a JSON object into a GistFile. + """ let filename = json("filename").as_string()? let content_type = json("type").as_string()? - let language = JsonNavUtil.string_or_none(json("language"))? + let language = JSONNavUtil.string_or_none(json("language"))? let raw_url = json("raw_url").as_string()? let size = json("size").as_i64()? - let content = try JsonNavUtil.string_or_none(json("content"))? else None end + let content = try JSONNavUtil.string_or_none(json("content"))? else None end let encoding = - try JsonNavUtil.string_or_none(json("encoding"))? else None end + try JSONNavUtil.string_or_none(json("encoding"))? else None end let truncated = try json("truncated").as_bool()? else None end - GistFile(filename, + GistFile( + filename, content_type, language, raw_url, diff --git a/github_rest_api/git_commit.pony b/github_rest_api/git_commit.pony index a3800f4..8cde7a3 100644 --- a/github_rest_api/git_commit.pony +++ b/github_rest_api/git_commit.pony @@ -25,13 +25,16 @@ class val GitCommit message = message' url = url' -primitive GitCommitJsonConverter is req.JsonConverter[GitCommit] +primitive GitCommitJSONConverter is req.JSONConverter[GitCommit] """ Converts a JSON object into a GitCommit. """ fun apply(json: JsonNav, creds: req.Credentials): GitCommit ? => - let author = GitPersonJsonConverter(json("author"), creds)? - let committer = GitPersonJsonConverter(json("committer"), creds)? + """ + Parse a JSON object into a GitCommit. + """ + let author = GitPersonJSONConverter(json("author"), creds)? + let committer = GitPersonJSONConverter(json("committer"), creds)? let message = json("message").as_string()? let url = json("url").as_string()? diff --git a/github_rest_api/git_person.pony b/github_rest_api/git_person.pony index 1d64257..6b6760c 100644 --- a/github_rest_api/git_person.pony +++ b/github_rest_api/git_person.pony @@ -12,7 +12,7 @@ class val GitPerson name = name' email = email' -primitive GitPersonJsonConverter is req.JsonConverter[GitPerson] +primitive GitPersonJSONConverter is req.JSONConverter[GitPerson] """ Converts a JSON object into a GitPerson. """ diff --git a/github_rest_api/issue.pony b/github_rest_api/issue.pony index 23c87e0..9854c37 100644 --- a/github_rest_api/issue.pony +++ b/github_rest_api/issue.pony @@ -74,16 +74,13 @@ class val Issue issue is actually a pull request. """ let _creds: req.Credentials - let number: I64 let title: String let user: User let labels: Array[Label] val let state: (String | None) let body: (String | None) - let pull_request: (IssuePullRequest | None) - let url: String let respository_url: String let labels_url: String @@ -146,20 +143,24 @@ primitive GetIssue "https://api.github.com/repos{/owner}{/repo}/issues{/number}") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("owner", owner) - .>set("repo", repo) - .>set("number", number.string()) + .> set("owner", owner) + .> set("repo", repo) + .> set("number", number.string()) let u: String val = tpl.expand(vars) by_url(u, creds) | let e: ut.URITemplateParseError => - Promise[IssueOrError].>apply(req.RequestError(where message' = e.message)) + Promise[IssueOrError] + .> apply(req.RequestError(where message' = e.message)) end fun by_url(url: String, creds: req.Credentials): Promise[IssueOrError] => + """ + Fetches an issue by its full API URL. + """ let p = Promise[IssueOrError] - let receiver = req.ResultReceiver[Issue](creds, p, IssueJsonConverter) + let receiver = req.ResultReceiver[Issue](creds, p, IssueJSONConverter) - req.JsonRequester.get(creds, url, receiver) + req.JSONRequester.get(creds, url, receiver) p primitive GetRepositoryIssues @@ -177,54 +178,62 @@ primitive GetRepositoryIssues sort: IssueSort = SortByCreated, direction: SortDirection = SortDescending, since: String = "", - per_page: (I64 | None) = None): Promise[(PaginatedList[Issue] | req.RequestError)] + per_page: (I64 | None) = None): + Promise[(PaginatedList[Issue] | req.RequestError)] => match \exhaustive\ ut.URITemplateParse( "https://api.github.com/repos{/owner}{/repo}/issues") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("owner", owner) - .>set("repo", repo) + .> set("owner", owner) + .> set("repo", repo) let u: String val = tpl.expand(vars) - let params = recover val - let p = Array[(String, String)] - p.push(("state", state)) - p.push(("sort", sort.query_value())) - p.push(("direction", direction.query_value())) - if labels.size() > 0 then - p.push(("labels", labels)) - end - if since.size() > 0 then - p.push(("since", since)) + let params = + recover val + let p = Array[(String, String)] + p.push(("state", state)) + p.push(("sort", sort.query_value())) + p.push(("direction", direction.query_value())) + if labels.size() > 0 then + p.push(("labels", labels)) + end + if since.size() > 0 then + p.push(("since", since)) + end + match per_page + | let n: I64 => p.push(("per_page", n.string())) + end + p end - match per_page - | let n: I64 => p.push(("per_page", n.string())) - end - p - end by_url(u + req.QueryParams(params), creds) | let e: ut.URITemplateParseError => - Promise[(PaginatedList[Issue] | req.RequestError)].>apply( - req.RequestError(where message' = e.message)) + Promise[(PaginatedList[Issue] | req.RequestError)] + .> apply(req.RequestError(where message' = e.message)) end fun by_url(url: String, - creds: req.Credentials): Promise[(PaginatedList[Issue] | req.RequestError)] + creds: req.Credentials): + Promise[(PaginatedList[Issue] | req.RequestError)] => - let ic = IssueJsonConverter - let plc = PaginatedListJsonConverter[Issue](creds, ic) + """ + Lists issues by fetching from the given API URL. + """ + let ic = IssueJSONConverter + let plc = PaginatedListJSONConverter[Issue](creds, ic) let p = Promise[(PaginatedList[Issue] | req.RequestError)] let r = PaginatedResultReceiver[Issue](creds, p, plc) - LinkedJsonRequester(creds, url, r) + LinkedJSONRequester(creds, url, r) p - -primitive IssueJsonConverter is req.JsonConverter[Issue] +primitive IssueJSONConverter is req.JSONConverter[Issue] """ Converts a JSON object from the issues API into an Issue. """ fun apply(json: JsonNav, creds: req.Credentials): Issue ? => + """ + Parse a JSON object into an Issue. + """ let url = json("url").as_string()? let respository_url = json("repository_url").as_string()? let labels_url = json("labels_url").as_string()? @@ -234,25 +243,27 @@ primitive IssueJsonConverter is req.JsonConverter[Issue] let number = json("number").as_i64()? let title = json("title").as_string()? - let user = UserJsonConverter(json("user"), creds)? - let state = JsonNavUtil.string_or_none(json("state"))? - let body = JsonNavUtil.string_or_none(json("body"))? + let user = UserJSONConverter(json("user"), creds)? + let state = JSONNavUtil.string_or_none(json("state"))? + let body = JSONNavUtil.string_or_none(json("body"))? let labels = recover trn Array[Label] end for i in json("labels").as_array()?.values() do - let l = LabelJsonConverter(JsonNav(i), creds)? + let l = LabelJSONConverter(JsonNav(i), creds)? labels.push(l) end let pr_json = json("pull_request") - let pull_request = match pr_json.json() - | let _: JsonValue => - IssuePullRequestJsonConverter(pr_json, creds)? - else - None - end + let pull_request = + match pr_json.json() + | let _: JsonValue => + IssuePullRequestJSONConverter(pr_json, creds)? + else + None + end - Issue(creds, + Issue( + creds, url, respository_url, labels_url, diff --git a/github_rest_api/issue_comment.pony b/github_rest_api/issue_comment.pony index 2e062ca..cd41521 100644 --- a/github_rest_api/issue_comment.pony +++ b/github_rest_api/issue_comment.pony @@ -45,21 +45,26 @@ primitive CreateIssueComment | let u': String => by_url(u', comment, creds) | let e: ut.URITemplateParseError => - Promise[IssueCommentOrError].>apply( - req.RequestError(where message' = e.message)) + Promise[IssueCommentOrError] + .> apply(req.RequestError(where message' = e.message)) end fun by_url(url: String, comment: String, creds: req.Credentials): Promise[IssueCommentOrError] => + """ + Creates a comment by posting to the given API URL. + """ let p = Promise[IssueCommentOrError] - let r = req.ResultReceiver[IssueComment](creds, - p, - IssueCommentJsonConverter) + let r = + req.ResultReceiver[IssueComment]( + creds, + p, + IssueCommentJSONConverter) let json = JsonObject.update("body", comment).print() - req.JsonRequester.post(creds, url, consume json, r) + req.JSONRequester.post(creds, url, consume json, r) p primitive GetIssueComments @@ -77,17 +82,24 @@ primitive GetIssueComments | let u': String => by_url(u', creds) | let e: ut.URITemplateParseError => - Promise[IssueCommentsOrError].>apply( - req.RequestError(where message' = e.message)) + Promise[IssueCommentsOrError] + .> apply(req.RequestError(where message' = e.message)) end - fun by_url(url: String, creds: req.Credentials): Promise[IssueCommentsOrError] => + fun by_url(url: String, + creds: req.Credentials): Promise[IssueCommentsOrError] + => + """ + Fetches issue comments by their full API URL. + """ let p = Promise[IssueCommentsOrError] - let r = req.ResultReceiver[IssueComments](creds, - p, - IssueCommentsJsonConverter) + let r = + req.ResultReceiver[IssueComments]( + creds, + p, + IssueCommentsJSONConverter) - req.JsonRequester.get(creds, url, r) + req.JSONRequester.get(creds, url, r) p primitive IssueCommentsURL @@ -102,21 +114,24 @@ primitive IssueCommentsURL "https://api.github.com/repos{/owner}{/repo}/issues{/number}/comments") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("owner", owner) - .>set("repo", repo) - .>set("number", number.string()) + .> set("owner", owner) + .> set("repo", repo) + .> set("number", number.string()) tpl.expand(vars) | let e: ut.URITemplateParseError => e end -primitive IssueCommentJsonConverter is req.JsonConverter[IssueComment] +primitive IssueCommentJSONConverter is req.JSONConverter[IssueComment] """ Converts a JSON object into an IssueComment. """ fun apply(json: JsonNav, creds: req.Credentials): IssueComment ? => + """ + Parse a JSON object into an IssueComment. + """ let body = json("body").as_string()? let url = json("url").as_string()? let html_url = json("html_url").as_string()? @@ -124,17 +139,22 @@ primitive IssueCommentJsonConverter is req.JsonConverter[IssueComment] IssueComment(creds, body, url, html_url, issue_url) -primitive IssueCommentsJsonConverter is req.JsonConverter[Array[IssueComment] val] +primitive IssueCommentsJSONConverter is + req.JSONConverter[Array[IssueComment] val] """ - Converts a JSON array of issue comment objects into an Array of IssueComment. + Converts a JSON array of issue comment objects into an Array of + IssueComment. """ fun apply(json: JsonNav, creds: req.Credentials): Array[IssueComment] val ? => + """ + Parse a JSON array into an Array of IssueComment. + """ let comments = recover trn Array[IssueComment] end for i in json.as_array()?.values() do - let comment = IssueCommentJsonConverter(JsonNav(i), creds)? + let comment = IssueCommentJSONConverter(JsonNav(i), creds)? comments.push(comment) end diff --git a/github_rest_api/issue_pull_request.pony b/github_rest_api/issue_pull_request.pony index c897462..30fc974 100644 --- a/github_rest_api/issue_pull_request.pony +++ b/github_rest_api/issue_pull_request.pony @@ -28,15 +28,18 @@ class val IssuePullRequest patch_url = patch_url' merged_at = merged_at' -primitive IssuePullRequestJsonConverter is req.JsonConverter[IssuePullRequest] +primitive IssuePullRequestJSONConverter is req.JSONConverter[IssuePullRequest] """ Converts a JSON object into an IssuePullRequest. """ fun apply(json: JsonNav, creds: req.Credentials): IssuePullRequest ? => + """ + Parse a JSON object into an IssuePullRequest. + """ let url = json("url").as_string()? let html_url = json("html_url").as_string()? let diff_url = json("diff_url").as_string()? let patch_url = json("patch_url").as_string()? - let merged_at = JsonNavUtil.string_or_none(json("merged_at"))? + let merged_at = JSONNavUtil.string_or_none(json("merged_at"))? IssuePullRequest(url, html_url, diff_url, patch_url, merged_at) diff --git a/github_rest_api/json_nav_util.pony b/github_rest_api/json_nav_util.pony index e239be1..1057105 100644 --- a/github_rest_api/json_nav_util.pony +++ b/github_rest_api/json_nav_util.pony @@ -1,6 +1,6 @@ use "json" -primitive JsonNavUtil +primitive JSONNavUtil """ Utility for extracting optional string fields from JSON. diff --git a/github_rest_api/label.pony b/github_rest_api/label.pony index 5305325..322edf5 100644 --- a/github_rest_api/label.pony +++ b/github_rest_api/label.pony @@ -51,13 +51,13 @@ primitive CreateLabel "https://api.github.com/repos{/owner}{/repo}/labels") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("owner", owner) - .>set("repo", repo) + .> set("owner", owner) + .> set("repo", repo) let u: String val = tpl.expand(vars) by_url(u, name, creds, color, description) | let e: ut.URITemplateParseError => - Promise[LabelOrError].>apply( - req.RequestError(where message' = e.message)) + Promise[LabelOrError] + .> apply(req.RequestError(where message' = e.message)) end fun by_url(url: String, @@ -66,10 +66,15 @@ primitive CreateLabel color: (String | None) = None, description: (String | None) = None): Promise[LabelOrError] => + """ + Creates a label by posting to the given API URL. + """ let p = Promise[LabelOrError] - let r = req.ResultReceiver[Label](creds, - p, - LabelJsonConverter) + let r = + req.ResultReceiver[Label]( + creds, + p, + LabelJSONConverter) var obj = JsonObject.update("name", name) match color @@ -79,7 +84,7 @@ primitive CreateLabel | let d: String => obj = obj.update("description", d) end let json = obj.print() - req.JsonRequester.post(creds, url, consume json, r) + req.JSONRequester.post(creds, url, consume json, r) p primitive DeleteLabel @@ -95,41 +100,47 @@ primitive DeleteLabel "https://api.github.com/repos{/owner}{/repo}/labels{/name}") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("owner", owner) - .>set("repo", repo) - .>set("name", name) + .> set("owner", owner) + .> set("repo", repo) + .> set("name", name) let u: String val = tpl.expand(vars) by_url(u, name, creds) | let e: ut.URITemplateParseError => - Promise[req.DeletedOrError].>apply( - req.RequestError(where message' = e.message)) + Promise[req.DeletedOrError] + .> apply(req.RequestError(where message' = e.message)) end - fun by_url(url: String, name: String, creds: req.Credentials): Promise[req.DeletedOrError] => + """ + Deletes a label by its full API URL. + """ let p = Promise[req.DeletedOrError] let r = req.DeletedResultReceiver(p) req.NoContentRequester.delete(creds, url, r) p -primitive LabelJsonConverter is req.JsonConverter[Label] +primitive LabelJSONConverter is req.JSONConverter[Label] """ Converts a JSON object into a Label. """ fun apply(json: JsonNav, creds: req.Credentials): Label ? => + """ + Parse a JSON object into a Label. + """ let id = json("id").as_i64()? let node_id = json("node_id").as_string()? let url = json("url").as_string()? let name = json("name").as_string()? let color = json("color").as_string()? let default = json("default").as_bool()? - let description = JsonNavUtil.string_or_none(json("description"))? + let description = JSONNavUtil.string_or_none(json("description"))? - Label(creds, + Label( + creds, id, node_id, url, diff --git a/github_rest_api/license.pony b/github_rest_api/license.pony index c02c961..b1a810c 100644 --- a/github_rest_api/license.pony +++ b/github_rest_api/license.pony @@ -27,18 +27,22 @@ class val License spdx_id = spdx_id' url = url' -primitive LicenseJsonConverter is req.JsonConverter[License] +primitive LicenseJSONConverter is req.JSONConverter[License] """ Converts a JSON object into a License. """ fun apply(json: JsonNav, creds: req.Credentials): License ? => + """ + Parse a JSON object into a License. + """ let node_id = json("node_id").as_string()? let name = json("name").as_string()? let key = json("key").as_string()? let spdx_id = json("spdx_id").as_string()? let url = json("url").as_string()? - License(creds, + License( + creds, node_id, name, key, diff --git a/github_rest_api/paginated_list.pony b/github_rest_api/paginated_list.pony index 92ec403..f715d68 100644 --- a/github_rest_api/paginated_list.pony +++ b/github_rest_api/paginated_list.pony @@ -11,7 +11,16 @@ interface tag LinkedResultReceiver Link header. Used by both paginated list and search result requesters. """ be success(json: JsonNav, link_header: String) + """ + Called when the request succeeds with a parsed JSON response and the raw + Link header value. + """ + be failure(status: U16, response_body: String, message: String) + """ + Called when the request fails with an unexpected status code or connection + error. + """ class val PaginatedList[A: Any val] """ @@ -20,20 +29,19 @@ class val PaginatedList[A: Any val] adjacent page, or None if no such page exists. """ let _creds: req.Credentials - let _converter: PaginatedListJsonConverter[A] + let _converter: PaginatedListJSONConverter[A] let _prev_link: (String | None) let _next_link: (String | None) - let results: Array[A] val new val _from_array(creds: req.Credentials, - converter: req.JsonConverter[A], + converter: req.JSONConverter[A], results': Array[A] val, prev_link: (String | None) = None, next_link: (String | None) = None) => _creds = creds - _converter = PaginatedListJsonConverter[A](_creds, converter) + _converter = PaginatedListJSONConverter[A](_creds, converter) results = results' _prev_link = prev_link _next_link = next_link @@ -65,19 +73,19 @@ class val PaginatedList[A: Any val] => let p = Promise[(PaginatedList[A] | req.RequestError)] let r = PaginatedResultReceiver[A](_creds, p, _converter) - LinkedJsonRequester(_creds, link, r) + LinkedJSONRequester(_creds, link, r) p -class val PaginatedListJsonConverter[A: Any val] +class val PaginatedListJSONConverter[A: Any val] """ Converts a JSON array response with Link header pagination into a PaginatedList. Delegates individual item conversion to the wrapped - JsonConverter. + JSONConverter. """ let _creds: req.Credentials - let _converter: req.JsonConverter[A] + let _converter: req.JSONConverter[A] - new val create(creds: req.Credentials, converter: req.JsonConverter[A]) => + new val create(creds: req.Credentials, converter: req.JSONConverter[A]) => _creds = creds _converter = converter @@ -85,6 +93,9 @@ class val PaginatedListJsonConverter[A: Any val] link_header: String, creds: req.Credentials): PaginatedList[A] ? => + """ + Parse a JSON array response into a PaginatedList. + """ let entries = recover trn Array[A] end for i in json.as_array()?.values() do @@ -94,7 +105,8 @@ class val PaginatedListJsonConverter[A: Any val] (let prev, let next) = _ExtractPaginationLinks(link_header) - PaginatedList[A]._from_array(_creds, + PaginatedList[A]._from_array( + _creds, _converter, consume entries, prev, @@ -107,11 +119,11 @@ actor PaginatedResultReceiver[A: Any val] """ let _creds: req.Credentials let _p: Promise[(PaginatedList[A] | req.RequestError)] - let _converter: PaginatedListJsonConverter[A] + let _converter: PaginatedListJSONConverter[A] new create(creds: req.Credentials, p: Promise[(PaginatedList[A] | req.RequestError)], - c: PaginatedListJsonConverter[A]) + c: PaginatedListJSONConverter[A]) => _creds = creds _p = p @@ -121,9 +133,10 @@ actor PaginatedResultReceiver[A: Any val] try _p(_converter(json, link_header, _creds)?) else - let m = recover val - "Unable to convert json for " + req.JsonTypeString(json) - end + let m = + recover val + "Unable to convert json for " + req.JSONTypeString(json) + end _p(req.RequestError(where message' = m)) end @@ -131,7 +144,7 @@ actor PaginatedResultReceiver[A: Any val] be failure(status: U16, response_body: String, message: String) => _p(req.RequestError(status, response_body, message)) -actor LinkedJsonRequester is courier.HTTPClientConnectionActor +actor LinkedJSONRequester is courier.HTTPClientConnectionActor """ Issues an HTTP GET request and delivers the JSON response along with the Link header to a LinkedResultReceiver. Used by both paginated list and search @@ -159,17 +172,23 @@ actor LinkedJsonRequester is courier.HTTPClientConnectionActor _connect(url) fun ref _connect(url: String) => - match courier.URL.parse(url) + match \exhaustive\ courier.URL.parse(url) | let parsed: courier.ParsedURL => _request_path = parsed.request_path() - let ctx = match _creds.ssl_ctx - | let c: ssl.SSLContext val => c - | None => req.SSLContextFactory() - end + let ctx = + match \exhaustive\ _creds.ssl_ctx + | let c: ssl.SSLContext val => c + | None => req.SSLContextFactory() + end let config = courier.ClientConnectionConfig - _http = courier.HTTPClientConnection.ssl( - _creds.auth, ctx, parsed.host, parsed.port, - this, config) + _http = + courier.HTTPClientConnection.ssl( + _creds.auth, + ctx, + parsed.host, + parsed.port, + this, + config) | let _: courier.URLParseError => _fail("Unable to parse URL: " + url) end @@ -177,7 +196,12 @@ actor LinkedJsonRequester is courier.HTTPClientConnectionActor fun ref _http_client_connection(): courier.HTTPClientConnection => _http - fun ref on_connected() => + fun ref on_connected() + => + """ + Builds and sends the HTTP GET request with appropriate headers once the + connection is established. + """ let hdrs = recover trn courier.Headers end hdrs.set("User-Agent", "Pony GitHub Rest API Client") hdrs.set("Accept", "application/vnd.github.v3+json") @@ -186,25 +210,32 @@ actor LinkedJsonRequester is courier.HTTPClientConnectionActor (let n, let v) = courier.BearerAuth(t) hdrs.set(n, v) end - let request = courier.HTTPRequest( - courier.GET, - _request_path, - consume hdrs) + let request = + courier.HTTPRequest( + courier.GET, + _request_path, + consume hdrs) _http.send_request(request) - fun ref on_response(response: courier.Response val) => + fun ref on_response(response: courier.Response val) + => + """ + Handles the HTTP response. Extracts the Link header for pagination and + follows 301/307 redirects. + """ _status = response.status - _link_header = match response.headers.get("link") - | let h: String => h - | None => "" - end + _link_header = + match \exhaustive\ response.headers.get("link") + | let h: String => h + | None => "" + end if (_status == 301) or (_status == 307) then match response.headers.get("location") | let loc: String => _redirected = true _http.close() - LinkedJsonRequester(_creds, loc, _receiver) + LinkedJSONRequester(_creds, loc, _receiver) return end end @@ -236,13 +267,14 @@ actor LinkedJsonRequester is courier.HTTPClientConnectionActor end fun ref on_connection_failure(reason: courier.ConnectionFailureReason) => - let msg = match \exhaustive\ reason - | courier.ConnectionFailedDNS => "DNS resolution failed" - | courier.ConnectionFailedTCP => "Unable to connect" - | courier.ConnectionFailedSSL => "SSL handshake failed" - | courier.ConnectionFailedTimeout => "Connection timed out" - | courier.ConnectionFailedTimerError => "Connect timer failed" - end + let msg = + match \exhaustive\ reason + | courier.ConnectionFailedDNS => "DNS resolution failed" + | courier.ConnectionFailedTCP => "Unable to connect" + | courier.ConnectionFailedSSL => "SSL handshake failed" + | courier.ConnectionFailedTimeout => "Connection timed out" + | courier.ConnectionFailedTimerError => "Connect timer failed" + end _receiver.failure(0, "", consume msg) fun ref on_parse_error(err: courier.ParseError) => diff --git a/github_rest_api/pull_request.pony b/github_rest_api/pull_request.pony index 5e976ff..b99f746 100644 --- a/github_rest_api/pull_request.pony +++ b/github_rest_api/pull_request.pony @@ -11,7 +11,6 @@ class val PullRequest changed in this pull request. """ let _creds: req.Credentials - let number: I64 let title: String let body: (String | None) @@ -65,48 +64,59 @@ primitive GetPullRequest "https://api.github.com/repos{/owner}{/repo}/pulls{/number}") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("owner", owner) - .>set("repo", repo) - .>set("number", number.string()) + .> set("owner", owner) + .> set("repo", repo) + .> set("number", number.string()) let u: String val = tpl.expand(vars) by_url(u, creds) | let e: ut.URITemplateParseError => - Promise[PullRequestOrError].>apply( - req.RequestError(where message' = e.message)) + Promise[PullRequestOrError] + .> apply(req.RequestError(where message' = e.message)) end - fun by_url(url: String, creds: req.Credentials): Promise[PullRequestOrError] => + fun by_url(url: String, + creds: req.Credentials): Promise[PullRequestOrError] + => + """ + Fetches a pull request by its full API URL. + """ let p = Promise[PullRequestOrError] - let r = req.ResultReceiver[PullRequest](creds, - p, - PullRequestJsonConverter) + let r = + req.ResultReceiver[PullRequest]( + creds, + p, + PullRequestJSONConverter) - req.JsonRequester.get(creds, url, r) + req.JSONRequester.get(creds, url, r) p -primitive PullRequestJsonConverter is req.JsonConverter[PullRequest] +primitive PullRequestJSONConverter is req.JSONConverter[PullRequest] """ Converts a JSON object from the pulls API into a PullRequest. """ fun apply(json: JsonNav, creds: req.Credentials): PullRequest ? => + """ + Parse a JSON object into a PullRequest. + """ let number = json("number").as_i64()? let title = json("title").as_string()? - let body = JsonNavUtil.string_or_none(json("body"))? + let body = JSONNavUtil.string_or_none(json("body"))? let state = json("state").as_string()? let labels = recover trn Array[Label] end for i in json("labels").as_array()?.values() do - let l = LabelJsonConverter(JsonNav(i), creds)? + let l = LabelJSONConverter(JsonNav(i), creds)? labels.push(l) end - let base = PullRequestBaseJsonConverter(json("base"), creds)? + let base = PullRequestBaseJSONConverter(json("base"), creds)? let url = json("url").as_string()? let html_url = json("html_url").as_string()? let comments_url = json("comments_url").as_string()? - PullRequest(creds, + PullRequest( + creds, number, title, body, diff --git a/github_rest_api/pull_request_base.pony b/github_rest_api/pull_request_base.pony index 3d27352..b533b3a 100644 --- a/github_rest_api/pull_request_base.pony +++ b/github_rest_api/pull_request_base.pony @@ -27,15 +27,18 @@ class val PullRequestBase user = user' repo = repo' -primitive PullRequestBaseJsonConverter is req.JsonConverter[PullRequestBase] +primitive PullRequestBaseJSONConverter is req.JSONConverter[PullRequestBase] """ Converts a JSON object into a PullRequestBase. """ fun apply(json: JsonNav, creds: req.Credentials): PullRequestBase ? => + """ + Parse a JSON object into a PullRequestBase. + """ let label = json("label").as_string()? let reference = json("ref").as_string()? let sha = json("sha").as_string()? - let user = UserJsonConverter(json("user"), creds)? - let repo = RepositoryJsonConverter(json("repo"), creds)? + let user = UserJSONConverter(json("user"), creds)? + let repo = RepositoryJSONConverter(json("repo"), creds)? PullRequestBase(creds, label, reference, sha, user, repo) diff --git a/github_rest_api/pull_request_file.pony b/github_rest_api/pull_request_file.pony index 96331ea..002e462 100644 --- a/github_rest_api/pull_request_file.pony +++ b/github_rest_api/pull_request_file.pony @@ -30,29 +30,34 @@ primitive GetPullRequestFiles "https://api.github.com/repos{/owner}{/repo}/pulls{/number}/files") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("owner", owner) - .>set("repo", repo) - .>set("number", number.string()) + .> set("owner", owner) + .> set("repo", repo) + .> set("number", number.string()) let u: String val = tpl.expand(vars) by_url(u, creds) | let e: ut.URITemplateParseError => - Promise[PullRequestFilesOrError].>apply( - req.RequestError(where message' = e.message)) + Promise[PullRequestFilesOrError] + .> apply(req.RequestError(where message' = e.message)) end fun by_url(url: String, creds: req.Credentials): Promise[PullRequestFilesOrError] => + """ + Fetches pull request files by their full API URL. + """ let p = Promise[PullRequestFilesOrError] - let r = req.ResultReceiver[PullRequestFiles](creds, - p, - PullRequestFilesJsonConverter) + let r = + req.ResultReceiver[PullRequestFiles]( + creds, + p, + PullRequestFilesJSONConverter) - req.JsonRequester.get(creds, url, r) + req.JSONRequester.get(creds, url, r) p -primitive PullRequestFilesJsonConverter is - req.JsonConverter[Array[PullRequestFile] val] +primitive PullRequestFilesJSONConverter is + req.JSONConverter[Array[PullRequestFile] val] """ Converts a JSON array of pull request file objects into an Array of PullRequestFile. @@ -60,6 +65,9 @@ primitive PullRequestFilesJsonConverter is fun apply(json: JsonNav, creds: req.Credentials): Array[PullRequestFile] val ? => + """ + Parse a JSON array into an Array of PullRequestFile. + """ let files = recover trn Array[PullRequestFile] end for i in json.as_array()?.values() do diff --git a/github_rest_api/release.pony b/github_rest_api/release.pony index bb4e2cf..ea3acb4 100644 --- a/github_rest_api/release.pony +++ b/github_rest_api/release.pony @@ -11,7 +11,6 @@ class val Release draft/prerelease status, and associated assets. """ let _creds: req.Credentials - let id: I64 let node_id: String let author: User @@ -21,11 +20,9 @@ class val Release let body: String let draft: Bool let prerelease: Bool - let created_at: String let published_at: String let assets: Array[Asset] val - let url: String let assets_url: String let upload_url: String @@ -91,10 +88,11 @@ primitive CreateRelease "https://api.github.com/repos{/owner}{/repo}/releases") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("owner", owner) - .>set("repo", repo) + .> set("owner", owner) + .> set("repo", repo) let u: String val = tpl.expand(vars) - by_url(u, + by_url( + u, tag_name, name, body, @@ -103,7 +101,8 @@ primitive CreateRelease draft, prerelease) | let e: ut.URITemplateParseError => - Promise[ReleaseOrError].>apply(req.RequestError(where message' = e.message)) + Promise[ReleaseOrError] + .> apply(req.RequestError(where message' = e.message)) end fun by_url(url: String, @@ -115,10 +114,15 @@ primitive CreateRelease draft: Bool = false, prerelease: Bool = false): Promise[ReleaseOrError] => + """ + Creates a release by posting to the given API URL. + """ let p = Promise[ReleaseOrError] - let r = req.ResultReceiver[Release](creds, - p, - ReleaseJsonConverter) + let r = + req.ResultReceiver[Release]( + creds, + p, + ReleaseJSONConverter) var obj = JsonObject .update("tag_name", tag_name) @@ -130,17 +134,20 @@ primitive CreateRelease end obj = obj.update("draft", draft).update("prerelease", prerelease) let json = obj.print() - req.JsonRequester.post(creds, url, consume json, r) + req.JSONRequester.post(creds, url, consume json, r) p -primitive ReleaseJsonConverter is req.JsonConverter[Release] +primitive ReleaseJSONConverter is req.JSONConverter[Release] """ Converts a JSON object from the releases API into a Release. """ fun apply(json: JsonNav, creds: req.Credentials): Release ? => + """ + Parse a JSON object into a Release. + """ let id = json("id").as_i64()? let node_id = json("node_id").as_string()? - let author = UserJsonConverter(json("author"), creds)? + let author = UserJSONConverter(json("author"), creds)? let tag_name = json("tag_name").as_string()? let target_commitish = json("target_commitish").as_string()? let name = json("name").as_string()? @@ -152,7 +159,7 @@ primitive ReleaseJsonConverter is req.JsonConverter[Release] let assets = recover trn Array[Asset] end for i in json("assets").as_array()?.values() do - let a = AssetJsonConverter(JsonNav(i), creds)? + let a = AssetJSONConverter(JsonNav(i), creds)? assets.push(a) end @@ -163,7 +170,8 @@ primitive ReleaseJsonConverter is req.JsonConverter[Release] let tarball_url = json("tarball_url").as_string()? let zipball_url = json("zipball_url").as_string()? - Release(creds, + Release( + creds, id, node_id, author, diff --git a/github_rest_api/repository.pony b/github_rest_api/repository.pony index cc23d7b..3b6a079 100644 --- a/github_rest_api/repository.pony +++ b/github_rest_api/repository.pony @@ -19,15 +19,12 @@ class val Repository let owner: User let private: Bool let fork: Bool - let created_at: String let pushed_at: String let updated_at: String - let homepage: (String | None) let default_branch: String let organization: (User | None) - let size: I64 let forks: I64 let forks_count: I64 @@ -38,19 +35,15 @@ class val Repository let subscribers_count: (I64 | None) let watchers: I64 let watchers_count: I64 - let language: (String | None) let license: (License | None) - let archived: Bool let disabled: Bool - let has_downloads: Bool let has_issues: Bool let has_pages: Bool let has_projects: Bool let has_wiki: Bool - let url: String let html_url: String let archive_url: String @@ -86,13 +79,11 @@ class val Repository let subscription_url: String let tags_url: String let trees_url: String - let clone_url: String let git_url: String let mirror_url: (String | None) let ssh_url: String let svn_url: String - // TODO temp_clone_token: ? | None new val create(creds: req.Credentials, id': I64, @@ -254,13 +245,15 @@ class val Repository match \exhaustive\ ut.URITemplateParse(labels_url) | let tpl: ut.URITemplate => let u: String val = tpl.expand(ut.URITemplateVariables) - CreateLabel.by_url(u, + CreateLabel.by_url( + u, label_name, _creds, color, label_description) | let e: ut.URITemplateParseError => - Promise[LabelOrError].>apply(req.RequestError(where message' = e.message)) + Promise[LabelOrError] + .> apply(req.RequestError(where message' = e.message)) end fun create_release(tag_name: String, @@ -276,7 +269,8 @@ class val Repository match \exhaustive\ ut.URITemplateParse(releases_url) | let tpl: ut.URITemplate => let u: String val = tpl.expand(ut.URITemplateVariables) - CreateRelease.by_url(u, + CreateRelease.by_url( + u, tag_name, release_name, body, @@ -285,7 +279,8 @@ class val Repository draft, prerelease) | let e: ut.URITemplateParseError => - Promise[ReleaseOrError].>apply(req.RequestError(where message' = e.message)) + Promise[ReleaseOrError] + .> apply(req.RequestError(where message' = e.message)) end fun delete_label(label_name: String): Promise[req.DeletedOrError] => @@ -295,11 +290,12 @@ class val Repository match \exhaustive\ ut.URITemplateParse(labels_url) | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("name", label_name) + .> set("name", label_name) let u: String val = tpl.expand(vars) DeleteLabel.by_url(u, label_name, _creds) | let e: ut.URITemplateParseError => - Promise[req.DeletedOrError].>apply(req.RequestError(where message' = e.message)) + Promise[req.DeletedOrError] + .> apply(req.RequestError(where message' = e.message)) end fun get_commit(sha: String): Promise[CommitOrError] => @@ -309,11 +305,12 @@ class val Repository match \exhaustive\ ut.URITemplateParse(commits_url) | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("sha", sha) + .> set("sha", sha) let u: String val = tpl.expand(vars) GetCommit.by_url(u, _creds) | let e: ut.URITemplateParseError => - Promise[CommitOrError].>apply(req.RequestError(where message' = e.message)) + Promise[CommitOrError] + .> apply(req.RequestError(where message' = e.message)) end fun get_issue(number: I64): Promise[IssueOrError] => @@ -323,11 +320,12 @@ class val Repository match \exhaustive\ ut.URITemplateParse(issues_url) | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("number", number.string()) + .> set("number", number.string()) let u: String val = tpl.expand(vars) GetIssue.by_url(u, _creds) | let e: ut.URITemplateParseError => - Promise[IssueOrError].>apply(req.RequestError(where message' = e.message)) + Promise[IssueOrError] + .> apply(req.RequestError(where message' = e.message)) end fun get_issues(labels: String = "", @@ -347,26 +345,28 @@ class val Repository match \exhaustive\ ut.URITemplateParse(issues_url) | let tpl: ut.URITemplate => let u: String val = tpl.expand(ut.URITemplateVariables) - let params = recover val - let p = Array[(String, String)] - p.push(("state", state)) - p.push(("sort", sort.query_value())) - p.push(("direction", direction.query_value())) - if labels.size() > 0 then - p.push(("labels", labels)) - end - if since.size() > 0 then - p.push(("since", since)) + let params = + recover val + let p = Array[(String, String)] + p.push(("state", state)) + p.push(("sort", sort.query_value())) + p.push(("direction", direction.query_value())) + if labels.size() > 0 then + p.push(("labels", labels)) + end + if since.size() > 0 then + p.push(("since", since)) + end + match per_page + | let n: I64 => p.push(("per_page", n.string())) + end + p end - match per_page - | let n: I64 => p.push(("per_page", n.string())) - end - p - end - GetRepositoryIssues.by_url(u + req.QueryParams(params), _creds) + GetRepositoryIssues.by_url( + u + req.QueryParams(params), _creds) | let e: ut.URITemplateParseError => - Promise[(PaginatedList[Issue] | req.RequestError)].>apply( - req.RequestError(where message' = e.message)) + Promise[(PaginatedList[Issue] | req.RequestError)] + .> apply(req.RequestError(where message' = e.message)) end fun get_pull_request(number: I64): Promise[PullRequestOrError] => @@ -376,12 +376,12 @@ class val Repository match \exhaustive\ ut.URITemplateParse(pulls_url) | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("number", number.string()) + .> set("number", number.string()) let u: String val = tpl.expand(vars) GetPullRequest.by_url(u, _creds) | let e: ut.URITemplateParseError => - Promise[PullRequestOrError].>apply( - req.RequestError(where message' = e.message)) + Promise[PullRequestOrError] + .> apply(req.RequestError(where message' = e.message)) end primitive GetRepository @@ -392,25 +392,33 @@ primitive GetRepository repo: String, creds: req.Credentials): Promise[RepositoryOrError] => - match \exhaustive\ ut.URITemplateParse("https://api.github.com/repos{/owner}{/repo}") + match \exhaustive\ ut.URITemplateParse( + "https://api.github.com/repos{/owner}{/repo}") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("owner", owner) - .>set("repo", repo) + .> set("owner", owner) + .> set("repo", repo) let u: String val = tpl.expand(vars) by_url(u, creds) | let e: ut.URITemplateParseError => - Promise[RepositoryOrError].>apply( - req.RequestError(where message' = e.message)) + Promise[RepositoryOrError] + .> apply(req.RequestError(where message' = e.message)) end - fun by_url(url: String, creds: req.Credentials): Promise[RepositoryOrError] => + fun by_url(url: String, + creds: req.Credentials): Promise[RepositoryOrError] + => + """ + Fetches a repository by its full API URL. + """ let p = Promise[RepositoryOrError] - let r = req.ResultReceiver[Repository](creds, - p, - RepositoryJsonConverter) + let r = + req.ResultReceiver[Repository]( + creds, + p, + RepositoryJSONConverter) - req.JsonRequester.get(creds, url, r) + req.JSONRequester.get(creds, url, r) p primitive GetRepositoryLabels @@ -419,30 +427,35 @@ primitive GetRepositoryLabels """ fun apply(owner: String, repo: String, - creds: req.Credentials): Promise[(PaginatedList[Label] | req.RequestError)] + creds: req.Credentials): + Promise[(PaginatedList[Label] | req.RequestError)] => match \exhaustive\ ut.URITemplateParse( "https://api.github.com/repos{/owner}{/repo}/labels") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("owner", owner) - .>set("repo", repo) + .> set("owner", owner) + .> set("repo", repo) let u: String val = tpl.expand(vars) by_url(u, creds) | let e: ut.URITemplateParseError => - Promise[(PaginatedList[Label] | req.RequestError)].>apply( - req.RequestError(where message' = e.message)) + Promise[(PaginatedList[Label] | req.RequestError)] + .> apply(req.RequestError(where message' = e.message)) end fun by_url(url: String, - creds: req.Credentials): Promise[(PaginatedList[Label] | req.RequestError)] + creds: req.Credentials): + Promise[(PaginatedList[Label] | req.RequestError)] => - let lc = LabelJsonConverter - let plc = PaginatedListJsonConverter[Label](creds, lc) + """ + Fetches repository labels by their full API URL. + """ + let lc = LabelJSONConverter + let plc = PaginatedListJSONConverter[Label](creds, lc) let p = Promise[(PaginatedList[Label] | req.RequestError)] let r = PaginatedResultReceiver[Label](creds, p, plc) - LinkedJsonRequester(creds, url, r) + LinkedJSONRequester(creds, url, r) p primitive GetOrganizationRepositories @@ -450,55 +463,65 @@ primitive GetOrganizationRepositories Lists all repositories in a GitHub organization as a paginated list. """ fun apply(org: String, - creds: req.Credentials): Promise[(PaginatedList[Repository] | req.RequestError)] + creds: req.Credentials): + Promise[(PaginatedList[Repository] | req.RequestError)] => - match \exhaustive\ ut.URITemplateParse("https://api.github.com/orgs{/org}/repos") + match \exhaustive\ ut.URITemplateParse( + "https://api.github.com/orgs{/org}/repos") | let tpl: ut.URITemplate => let vars = ut.URITemplateVariables - .>set("org", org) + .> set("org", org) let u: String val = tpl.expand(vars) by_url(u, creds) | let e: ut.URITemplateParseError => - Promise[(PaginatedList[Repository] | req.RequestError)].>apply( - req.RequestError(where message' = e.message)) + Promise[(PaginatedList[Repository] | req.RequestError)] + .> apply(req.RequestError(where message' = e.message)) end fun by_url(url: String, - creds: req.Credentials): Promise[(PaginatedList[Repository] | req.RequestError)] + creds: req.Credentials): + Promise[(PaginatedList[Repository] | req.RequestError)] => - let rc = RepositoryJsonConverter - let plc = PaginatedListJsonConverter[Repository](creds, rc) + """ + Lists organization repositories by their full API URL. + """ + let rc = RepositoryJSONConverter + let plc = PaginatedListJSONConverter[Repository](creds, rc) let p = Promise[(PaginatedList[Repository] | req.RequestError)] let r = PaginatedResultReceiver[Repository](creds, p, plc) - LinkedJsonRequester(creds, url, r) + LinkedJSONRequester(creds, url, r) p -primitive RepositoryJsonConverter is req.JsonConverter[Repository] +primitive RepositoryJSONConverter is req.JSONConverter[Repository] """ Converts a JSON object from the repositories API into a Repository. """ fun apply(json: JsonNav, creds: req.Credentials): Repository ? => + """ + Parse a JSON object into a Repository. + """ let id = json("id").as_i64()? let node_id = json("node_id").as_string()? let name = json("name").as_string()? let full_name = json("full_name").as_string()? - let description = JsonNavUtil.string_or_none(json("description"))? - let owner = UserJsonConverter(json("owner"), creds)? + let description = JSONNavUtil.string_or_none(json("description"))? + let owner = UserJSONConverter(json("owner"), creds)? let private = json("private").as_bool()? let fork = json("fork").as_bool()? let created_at = json("created_at").as_string()? let pushed_at = json("pushed_at").as_string()? let updated_at = json("updated_at").as_string()? - let homepage = JsonNavUtil.string_or_none(json("homepage"))? + let homepage = JSONNavUtil.string_or_none(json("homepage"))? let default_branch = json("default_branch").as_string()? - let organization = try - UserJsonConverter(json("organization"), creds)? - else - None - end + let organization = + try + UserJSONConverter(json("organization"), creds)? + else + None + end let size = json("size").as_i64()? let forks = json("forks").as_i64()? @@ -512,12 +535,13 @@ primitive RepositoryJsonConverter is req.JsonConverter[Repository] try json("subscribers_count").as_i64()? else None end let watchers = json("watchers").as_i64()? let watchers_count = json("watchers_count").as_i64()? - let language = JsonNavUtil.string_or_none(json("language"))? - let license = try - LicenseJsonConverter(json("license"), creds)? - else - None - end + let language = JSONNavUtil.string_or_none(json("language"))? + let license = + try + LicenseJSONConverter(json("license"), creds)? + else + None + end let archived = json("archived").as_bool()? let disabled = json("disabled").as_bool()? @@ -565,11 +589,12 @@ primitive RepositoryJsonConverter is req.JsonConverter[Repository] let clone_url = json("clone_url").as_string()? let git_url = json("git_url").as_string()? - let mirror_url = JsonNavUtil.string_or_none(json("mirror_url"))? + let mirror_url = JSONNavUtil.string_or_none(json("mirror_url"))? let ssh_url = json("ssh_url").as_string()? let svn_url = json("svn_url").as_string()? - Repository(creds, + Repository( + creds, id, node_id, name, diff --git a/github_rest_api/request/_ssl.pony b/github_rest_api/request/_ssl.pony index b82e9da..cfdf249 100644 --- a/github_rest_api/request/_ssl.pony +++ b/github_rest_api/request/_ssl.pony @@ -13,11 +13,11 @@ primitive SSLContextFactory try recover val ssl.SSLContext - .>set_client_verify(true) - .>set_authority(None)? + .> set_client_verify(true) + .> set_authority(None)? end else recover val - ssl.SSLContext.>set_client_verify(false) + ssl.SSLContext .> set_client_verify(false) end end diff --git a/github_rest_api/request/_test.pony b/github_rest_api/request/_test.pony index ea490da..c4658cf 100644 --- a/github_rest_api/request/_test.pony +++ b/github_rest_api/request/_test.pony @@ -41,7 +41,8 @@ class \nodoc\ _TestQueryParamsMultiple is UnitTest fun name(): String => "request/query-params/multiple" fun ref apply(h: TestHelper) => - let params = recover val + let params = + recover val [("state", "open"); ("labels", "bug")] end h.assert_eq[String]("?state=open&labels=bug", QueryParams(params)) @@ -96,7 +97,8 @@ class \nodoc\ _TestQueryParamsStructureProperty is UnitTest PonyCheck.for_all[USize]( recover val Generators.usize(1, 10) end, h)( {(n, h) => - let params = recover val + let params = + recover val let p = Array[(String, String)] for i in Range(0, n) do p.push(("k" + i.string(), "v" + i.string())) diff --git a/github_rest_api/request/check_requester.pony b/github_rest_api/request/check_requester.pony index 3e408c3..3a024c2 100644 --- a/github_rest_api/request/check_requester.pony +++ b/github_rest_api/request/check_requester.pony @@ -9,7 +9,14 @@ interface tag CheckResultReceiver their answer via status code rather than a response body. """ be success(value: Bool) + """ + Called when the status check succeeds with a boolean result. + """ + be failure(status: U16, response_body: String, message: String) + """ + Called when the request fails with an unexpected status code. + """ type BoolOrError is (Bool | RequestError) @@ -55,17 +62,23 @@ actor CheckRequester is courier.HTTPClientConnectionActor _connect(url) fun ref _connect(url: String) => - match courier.URL.parse(url) + match \exhaustive\ courier.URL.parse(url) | let parsed: courier.ParsedURL => _request_path = parsed.request_path() - let ctx = match _creds.ssl_ctx - | let c: ssl.SSLContext val => c - | None => SSLContextFactory() - end + let ctx = + match \exhaustive\ _creds.ssl_ctx + | let c: ssl.SSLContext val => c + | None => SSLContextFactory() + end let config = courier.ClientConnectionConfig - _http = courier.HTTPClientConnection.ssl( - _creds.auth, ctx, parsed.host, parsed.port, - this, config) + _http = + courier.HTTPClientConnection.ssl( + _creds.auth, + ctx, + parsed.host, + parsed.port, + this, + config) | let _: courier.URLParseError => _fail("Unable to parse URL: " + url) end @@ -73,7 +86,12 @@ actor CheckRequester is courier.HTTPClientConnectionActor fun ref _http_client_connection(): courier.HTTPClientConnection => _http - fun ref on_connected() => + fun ref on_connected() + => + """ + Builds and sends the HTTP GET request with appropriate headers once the + connection is established. + """ let hdrs = recover trn courier.Headers end hdrs.set("User-Agent", "Pony GitHub Rest API Client") hdrs.set("Accept", "application/vnd.github.v3+json") @@ -82,10 +100,11 @@ actor CheckRequester is courier.HTTPClientConnectionActor (let n, let v) = courier.BearerAuth(t) hdrs.set(n, v) end - let request = courier.HTTPRequest( - courier.GET, - _request_path, - consume hdrs) + let request = + courier.HTTPRequest( + courier.GET, + _request_path, + consume hdrs) _http.send_request(request) fun ref on_response(response: courier.Response val) => @@ -113,13 +132,14 @@ actor CheckRequester is courier.HTTPClientConnectionActor end fun ref on_connection_failure(reason: courier.ConnectionFailureReason) => - let msg = match \exhaustive\ reason - | courier.ConnectionFailedDNS => "DNS resolution failed" - | courier.ConnectionFailedTCP => "Unable to connect" - | courier.ConnectionFailedSSL => "SSL handshake failed" - | courier.ConnectionFailedTimeout => "Connection timed out" - | courier.ConnectionFailedTimerError => "Connect timer failed" - end + let msg = + match \exhaustive\ reason + | courier.ConnectionFailedDNS => "DNS resolution failed" + | courier.ConnectionFailedTCP => "Unable to connect" + | courier.ConnectionFailedSSL => "SSL handshake failed" + | courier.ConnectionFailedTimeout => "Connection timed out" + | courier.ConnectionFailedTimerError => "Connect timer failed" + end _receiver.failure(0, "", consume msg) fun ref on_parse_error(err: courier.ParseError) => diff --git a/github_rest_api/request/credentials.pony b/github_rest_api/request/credentials.pony index 5e929bf..56e33c6 100644 --- a/github_rest_api/request/credentials.pony +++ b/github_rest_api/request/credentials.pony @@ -27,16 +27,16 @@ class val Credentials actor ResultReceiver[A: Any val] """ Generic receiver that converts a JSON response into a model type via a - JsonConverter and fulfills the associated Promise with the result or a + JSONConverter and fulfills the associated Promise with the result or a RequestError. """ let _creds: Credentials let _p: Promise[(A | RequestError)] - let _converter: JsonConverter[A] + let _converter: JSONConverter[A] new create(creds: Credentials, p: Promise[(A | RequestError)], - c: JsonConverter[A]) + c: JSONConverter[A]) => _creds = creds _p = p @@ -46,9 +46,10 @@ actor ResultReceiver[A: Any val] try _p(_converter(json, _creds)?) else - let m = recover val - "Unable to convert json for " + JsonTypeString(json) - end + let m = + recover val + "Unable to convert json for " + JSONTypeString(json) + end _p(RequestError(where message' = m)) end diff --git a/github_rest_api/request/json.pony b/github_rest_api/request/json.pony index a33e6fd..a6b1ab5 100644 --- a/github_rest_api/request/json.pony +++ b/github_rest_api/request/json.pony @@ -1,10 +1,21 @@ use "json" -interface val JsonConverter[A: Any #share] +interface val JSONConverter[A: Any #share] + """ + Converts a JsonNav value into a model type, using the supplied Credentials + for any nested requests. + """ fun apply(json: JsonNav, creds: Credentials): A ? + """ + Parse `json` into an `A`, raising an error when a required field is + missing or has the wrong type. + """ -primitive JsonTypeString - """Convert a JsonNav's value to its JSON string representation for error messages.""" +primitive JSONTypeString + """ + Converts a JsonNav's value to its JSON string representation for error + messages. + """ fun apply(json: JsonNav): String => match \exhaustive\ json.json() | let o: JsonObject => o.print() diff --git a/github_rest_api/request/json_requester.pony b/github_rest_api/request/json_requester.pony index 9d59ad9..58da599 100644 --- a/github_rest_api/request/json_requester.pony +++ b/github_rest_api/request/json_requester.pony @@ -2,15 +2,23 @@ use courier = "courier" use "json" use ssl = "ssl/net" -interface tag JsonRequesterResultReceiver +interface tag JSONRequesterResultReceiver """ Receives the result of a JSON API request: either a parsed JSON response on success, or status/body/message details on failure. """ be success(json: JsonNav) + """ + Called when the request succeeds with a parsed JSON response. + """ + be failure(status: U16, response_body: String, message: String) + """ + Called when the request fails, with the HTTP status code, raw response + body, and an error message. + """ -actor JsonRequester is courier.HTTPClientConnectionActor +actor JSONRequester is courier.HTTPClientConnectionActor """ Issues an HTTP request that expects a JSON response. Supports GET (200), POST (201), and PATCH (200) methods. GET requests follow 301/307 redirects @@ -21,7 +29,7 @@ actor JsonRequester is courier.HTTPClientConnectionActor var _http: courier.HTTPClientConnection = courier.HTTPClientConnection.none() var _collector: courier.ResponseCollector = courier.ResponseCollector let _creds: Credentials - let _receiver: JsonRequesterResultReceiver + let _receiver: JSONRequesterResultReceiver let _method: courier.Method let _expected_status: U16 let _body: (String | None) @@ -31,7 +39,7 @@ actor JsonRequester is courier.HTTPClientConnectionActor new get(creds: Credentials, url: String, - receiver: JsonRequesterResultReceiver) + receiver: JSONRequesterResultReceiver) => """ Issues an HTTP GET request expecting a 200 response with a JSON body. @@ -46,7 +54,7 @@ actor JsonRequester is courier.HTTPClientConnectionActor new post(creds: Credentials, url: String, body: String, - receiver: JsonRequesterResultReceiver) + receiver: JSONRequesterResultReceiver) => """ Issues an HTTP POST request expecting a 201 response with a JSON body. @@ -61,7 +69,7 @@ actor JsonRequester is courier.HTTPClientConnectionActor new patch(creds: Credentials, url: String, body: String, - receiver: JsonRequesterResultReceiver) + receiver: JSONRequesterResultReceiver) => """ Issues an HTTP PATCH request expecting a 200 response with a JSON body. @@ -74,17 +82,23 @@ actor JsonRequester is courier.HTTPClientConnectionActor _connect(url) fun ref _connect(url: String) => - match courier.URL.parse(url) + match \exhaustive\ courier.URL.parse(url) | let parsed: courier.ParsedURL => _request_path = parsed.request_path() - let ctx = match _creds.ssl_ctx - | let c: ssl.SSLContext val => c - | None => SSLContextFactory() - end + let ctx = + match \exhaustive\ _creds.ssl_ctx + | let c: ssl.SSLContext val => c + | None => SSLContextFactory() + end let config = courier.ClientConnectionConfig - _http = courier.HTTPClientConnection.ssl( - _creds.auth, ctx, parsed.host, parsed.port, - this, config) + _http = + courier.HTTPClientConnection.ssl( + _creds.auth, + ctx, + parsed.host, + parsed.port, + this, + config) | let _: courier.URLParseError => _fail("Unable to parse URL: " + url) end @@ -92,7 +106,12 @@ actor JsonRequester is courier.HTTPClientConnectionActor fun ref _http_client_connection(): courier.HTTPClientConnection => _http - fun ref on_connected() => + fun ref on_connected() + => + """ + Builds and sends the HTTP request with appropriate headers once the + connection is established. + """ let hdrs = recover trn courier.Headers end hdrs.set("User-Agent", "Pony GitHub Rest API Client") hdrs.set("Accept", "application/vnd.github.v3+json") @@ -105,17 +124,23 @@ actor JsonRequester is courier.HTTPClientConnectionActor | let b: String => hdrs.set("Content-Length", b.size().string()) end - let request = courier.HTTPRequest( - _method, - _request_path, - consume hdrs, - match _body - | let b: String => b.array() - | None => None - end) + let request = + courier.HTTPRequest( + _method, + _request_path, + consume hdrs, + match \exhaustive\ _body + | let b: String => b.array() + | None => None + end) _http.send_request(request) - fun ref on_response(response: courier.Response val) => + fun ref on_response(response: courier.Response val) + => + """ + Handles the HTTP response. For GET requests, follows 301/307 redirects. + Otherwise, begins collecting the response body. + """ _status = response.status if (_method is courier.GET) and ((_status == 301) or (_status == 307)) @@ -124,7 +149,7 @@ actor JsonRequester is courier.HTTPClientConnectionActor | let loc: String => _redirected = true _http.close() - JsonRequester.get(_creds, loc, _receiver) + JSONRequester.get(_creds, loc, _receiver) return end end @@ -155,13 +180,14 @@ actor JsonRequester is courier.HTTPClientConnectionActor end fun ref on_connection_failure(reason: courier.ConnectionFailureReason) => - let msg = match \exhaustive\ reason - | courier.ConnectionFailedDNS => "DNS resolution failed" - | courier.ConnectionFailedTCP => "Unable to connect" - | courier.ConnectionFailedSSL => "SSL handshake failed" - | courier.ConnectionFailedTimeout => "Connection timed out" - | courier.ConnectionFailedTimerError => "Connect timer failed" - end + let msg = + match \exhaustive\ reason + | courier.ConnectionFailedDNS => "DNS resolution failed" + | courier.ConnectionFailedTCP => "Unable to connect" + | courier.ConnectionFailedSSL => "SSL handshake failed" + | courier.ConnectionFailedTimeout => "Connection timed out" + | courier.ConnectionFailedTimerError => "Connect timer failed" + end _receiver.failure(0, "", consume msg) fun ref on_parse_error(err: courier.ParseError) => diff --git a/github_rest_api/request/no_content_requester.pony b/github_rest_api/request/no_content_requester.pony index 10f457e..5e435cd 100644 --- a/github_rest_api/request/no_content_requester.pony +++ b/github_rest_api/request/no_content_requester.pony @@ -9,7 +9,14 @@ interface tag DeleteResultReceiver a gist. """ be success() + """ + Called when the request succeeds with a 204 No Content response. + """ + be failure(status: U16, response_body: String, message: String) + """ + Called when the request fails with an unexpected status code. + """ type DeletedOrError is (Deleted | RequestError) @@ -74,17 +81,23 @@ actor NoContentRequester is courier.HTTPClientConnectionActor _connect(url) fun ref _connect(url: String) => - match courier.URL.parse(url) + match \exhaustive\ courier.URL.parse(url) | let parsed: courier.ParsedURL => _request_path = parsed.request_path() - let ctx = match _creds.ssl_ctx - | let c: ssl.SSLContext val => c - | None => SSLContextFactory() - end + let ctx = + match \exhaustive\ _creds.ssl_ctx + | let c: ssl.SSLContext val => c + | None => SSLContextFactory() + end let config = courier.ClientConnectionConfig - _http = courier.HTTPClientConnection.ssl( - _creds.auth, ctx, parsed.host, parsed.port, - this, config) + _http = + courier.HTTPClientConnection.ssl( + _creds.auth, + ctx, + parsed.host, + parsed.port, + this, + config) | let _: courier.URLParseError => _fail("Unable to parse URL: " + url) end @@ -92,7 +105,12 @@ actor NoContentRequester is courier.HTTPClientConnectionActor fun ref _http_client_connection(): courier.HTTPClientConnection => _http - fun ref on_connected() => + fun ref on_connected() + => + """ + Builds and sends the HTTP request with appropriate headers once the + connection is established. + """ let hdrs = recover trn courier.Headers end hdrs.set("User-Agent", "Pony GitHub Rest API Client") hdrs.set("Accept", "application/vnd.github.v3+json") @@ -102,10 +120,11 @@ actor NoContentRequester is courier.HTTPClientConnectionActor hdrs.set(n, v) end hdrs.set("Content-Length", "0") - let request = courier.HTTPRequest( - _method, - _request_path, - consume hdrs) + let request = + courier.HTTPRequest( + _method, + _request_path, + consume hdrs) _http.send_request(request) fun ref on_response(response: courier.Response val) => @@ -131,13 +150,14 @@ actor NoContentRequester is courier.HTTPClientConnectionActor end fun ref on_connection_failure(reason: courier.ConnectionFailureReason) => - let msg = match \exhaustive\ reason - | courier.ConnectionFailedDNS => "DNS resolution failed" - | courier.ConnectionFailedTCP => "Unable to connect" - | courier.ConnectionFailedSSL => "SSL handshake failed" - | courier.ConnectionFailedTimeout => "Connection timed out" - | courier.ConnectionFailedTimerError => "Connect timer failed" - end + let msg = + match \exhaustive\ reason + | courier.ConnectionFailedDNS => "DNS resolution failed" + | courier.ConnectionFailedTCP => "Unable to connect" + | courier.ConnectionFailedSSL => "SSL handshake failed" + | courier.ConnectionFailedTimeout => "Connection timed out" + | courier.ConnectionFailedTimerError => "Connect timer failed" + end _receiver.failure(0, "", consume msg) fun ref on_parse_error(err: courier.ParseError) => diff --git a/github_rest_api/request/request.pony b/github_rest_api/request/request.pony new file mode 100644 index 0000000..fa0206d --- /dev/null +++ b/github_rest_api/request/request.pony @@ -0,0 +1,5 @@ +""" +HTTP request infrastructure for the GitHub REST API client. Provides +credentials, SSL context, JSON and no-content requesters, result receivers, +and error types used by the top-level API primitives. +""" diff --git a/github_rest_api/request/request_error.pony b/github_rest_api/request/request_error.pony index ba30292..09ee8e2 100644 --- a/github_rest_api/request/request_error.pony +++ b/github_rest_api/request/request_error.pony @@ -1,4 +1,8 @@ class val RequestError + """ + Represents a failed GitHub API request with its HTTP status code, the raw + response body, and a human-readable error message. + """ let status: U16 let response_body: String let message: String diff --git a/github_rest_api/search.pony b/github_rest_api/search.pony index 03e7774..cf91fc9 100644 --- a/github_rest_api/search.pony +++ b/github_rest_api/search.pony @@ -11,16 +11,20 @@ primitive SearchIssues fun apply(query: String, creds: req.Credentials): Promise[IssueSearchResultsOrError] => + """ + Issue a search request and return a Promise for the first page of results. + """ let p = Promise[IssueSearchResultsOrError] - let sc = PaginatedSearchJsonConverter[Issue](creds, IssueJsonConverter) + let sc = PaginatedSearchJSONConverter[Issue](creds, IssueJSONConverter) let r = SearchResultReceiver[Issue](creds, p, sc) - let url = recover val - "https://api.github.com/search/issues" - + req.QueryParams(recover val [("q", query)] end) - end + let url = + recover val + "https://api.github.com/search/issues" + + req.QueryParams(recover val [("q", query)] end) + end - LinkedJsonRequester(creds, url, r) + LinkedJSONRequester(creds, url, r) p @@ -31,16 +35,15 @@ class val SearchResults[A: Any val] `prev_page()` and `next_page()` to navigate between pages. """ let _creds: req.Credentials - let _converter: PaginatedSearchJsonConverter[A] + let _converter: PaginatedSearchJSONConverter[A] let _prev_link: (String | None) let _next_link: (String | None) - let total_count: I64 let incomplete_results: Bool let items: Array[A] val new val _create(creds: req.Credentials, - converter: req.JsonConverter[A], + converter: req.JSONConverter[A], total_count': I64, incomplete_results': Bool, items': Array[A] val, @@ -48,7 +51,7 @@ class val SearchResults[A: Any val] next_link: (String | None) = None) => _creds = creds - _converter = PaginatedSearchJsonConverter[A](creds, converter) + _converter = PaginatedSearchJSONConverter[A](creds, converter) total_count = total_count' incomplete_results = incomplete_results' items = items' @@ -82,18 +85,18 @@ class val SearchResults[A: Any val] => let p = Promise[(SearchResults[A] | req.RequestError)] let r = SearchResultReceiver[A](_creds, p, _converter) - LinkedJsonRequester(_creds, link, r) + LinkedJSONRequester(_creds, link, r) p -class val PaginatedSearchJsonConverter[A: Any val] +class val PaginatedSearchJSONConverter[A: Any val] """ Converts a JSON search response (with `total_count`, `incomplete_results`, and `items` fields) plus Link header pagination into SearchResults. """ let _creds: req.Credentials - let _converter: req.JsonConverter[A] + let _converter: req.JSONConverter[A] - new val create(creds: req.Credentials, converter: req.JsonConverter[A]) => + new val create(creds: req.Credentials, converter: req.JSONConverter[A]) => _creds = creds _converter = converter @@ -101,6 +104,9 @@ class val PaginatedSearchJsonConverter[A: Any val] link_header: String, creds: req.Credentials): SearchResults[A] ? => + """ + Parse a JSON search response into SearchResults. + """ let total_count = json("total_count").as_i64()? let incomplete = json("incomplete_results").as_bool()? @@ -112,7 +118,8 @@ class val PaginatedSearchJsonConverter[A: Any val] (let prev, let next) = _ExtractPaginationLinks(link_header) - SearchResults[A]._create(_creds, + SearchResults[A]._create( + _creds, _converter, total_count, incomplete, @@ -127,11 +134,11 @@ actor SearchResultReceiver[A: Any val] """ let _creds: req.Credentials let _p: Promise[(SearchResults[A] | req.RequestError)] - let _converter: PaginatedSearchJsonConverter[A] + let _converter: PaginatedSearchJSONConverter[A] new create(creds: req.Credentials, p: Promise[(SearchResults[A] | req.RequestError)], - c: PaginatedSearchJsonConverter[A]) + c: PaginatedSearchJSONConverter[A]) => _creds = creds _p = p @@ -141,9 +148,10 @@ actor SearchResultReceiver[A: Any val] try _p(_converter(json, link_header, _creds)?) else - let m = recover val - "Unable to convert json for " + req.JsonTypeString(json) - end + let m = + recover val + "Unable to convert json for " + req.JSONTypeString(json) + end _p(req.RequestError(where message' = m)) end diff --git a/github_rest_api/user.pony b/github_rest_api/user.pony index ba98ec5..2854665 100644 --- a/github_rest_api/user.pony +++ b/github_rest_api/user.pony @@ -67,11 +67,14 @@ class val User user_type = user_type' site_admin = site_admin' -primitive UserJsonConverter is req.JsonConverter[User] +primitive UserJSONConverter is req.JSONConverter[User] """ Converts a JSON object into a User. """ fun apply(json: JsonNav, creds: req.Credentials): User ? => + """ + Parse a JSON object into a User. + """ let login = json("login").as_string()? let id = json("id").as_i64()? let node_id = json("node_id").as_string()? @@ -91,7 +94,8 @@ primitive UserJsonConverter is req.JsonConverter[User] let user_type = json("type").as_string()? let site_admin = json("site_admin").as_bool()? - User(creds, + User( + creds, login, id, node_id,