{"id":20305987,"url":"https://github.com/prmr/dscribe","last_synced_at":"2025-04-11T15:01:52.623Z","repository":{"id":41869612,"uuid":"263996451","full_name":"prmr/DScribe","owner":"prmr","description":"Unit test generator with documentation support","archived":false,"fork":false,"pushed_at":"2022-04-25T16:57:00.000Z","size":2180,"stargazers_count":9,"open_issues_count":4,"forks_count":2,"subscribers_count":5,"default_branch":"master","last_synced_at":"2025-03-25T11:04:03.993Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Java","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/prmr.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-05-14T18:39:07.000Z","updated_at":"2024-06-07T12:52:26.000Z","dependencies_parsed_at":"2022-08-11T19:50:11.871Z","dependency_job_id":null,"html_url":"https://github.com/prmr/DScribe","commit_stats":null,"previous_names":[],"tags_count":2,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prmr%2FDScribe","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prmr%2FDScribe/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prmr%2FDScribe/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/prmr%2FDScribe/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/prmr","download_url":"https://codeload.github.com/prmr/DScribe/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248428527,"owners_count":21101774,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-14T17:11:08.056Z","updated_at":"2025-04-11T15:01:52.551Z","avatar_url":"https://github.com/prmr.png","language":"Java","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# DScribe\nDScribe is a technique to generate both unit tests and documentation from a set of templates and invocations.\n\n## License and Attribution\n\nThe content of this repository is licensed unter the terms of the [Apache license, Version 2.0](LICENSE). To indicate attribution, please link to this repository and cite the following article:\n\nMathieu Nassif, Alexa Hernandez, Ashvitha Sridharan, and Martin P. Robillard. \"Generating Unit Tests for Documentation,\" To appear in IEEE Transactions on Software Engineering, doi: [10.1109/TSE.2021.3087087](10.1109/TSE.2021.3087087).\n\n## How DScribe Works\nDScribe allows developers to create templates that jointly capture the structure to test and document a recurring concern. Developers can then invoke the templates to generate consistent and checkable unit tests and documentation.\n\n### Writing Templates \nDScribe templates are defined in Java. They associate two components: a code skeleton and a documentation fragment. The code skeleton is created as an abstract syntax tree with a set of nodes marked as placeholders (denoted by surrounding \"$\" signs). It captures the structure to test the concern. The documentation fragmentation describes the concern under test using free-form text and may refer to the code skeleton's placeholders. For example:\n```\n/**\t\t\t\t\t\t\t\t\t\t \n * Throws $exType$ when $state$\t\t\t  \t\n */\t\t\t\t\t\t\t\t\t\n@Template(\"AssertThrows\")\n@Types($state$=EXPR, $exType$=EXCEPTION, $factory$=EXPR, $params$=EXPR_LIST)\n@Test\npublic void $method$_When$state$_Throw$exType$()\n{\n\tassertThrows($exType$, () -\u003e $class$.$method$($params$)); \n}\n```\nSince DScribe uses method-level Java annotations to invoke templates (see [invoking templates](#invoking-templates)), for each template, you also need to define an annotation. The annotation must have the same name as the template as well as one parameter for each template placeholder. For example, the annotation for the `AssertThrows` template should look like: \n```\n@Repeatable(AssertThrowsList.class)\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ ElementType.TYPE, ElementType.METHOD })\npublic @interface AssertThrows\n{\n\tpublic String state();\n\tpublic Class\u003c?\u003e exType();\n\tpublic String factory();\n\tpublic String[] params() default {};\n\tpublic String uut() default \"\";\n}\n\n@Retention(RetentionPolicy.RUNTIME)\n@Target({ ElementType.TYPE, ElementType.METHOD })\npublic @interface AssertThrowsList\n{\n\tAssertThrows[] value();\n}\n```\n\nDScribe templates are typically aggregated in a template class called ``Template.java``. You can also decide to organize your templates across multiple template classes. The imports statements and package declaration defined in your template class(es) are copied over to the generated test classes. For example, suppose your ``Template.java`` class looks like:\n```\npackage $package$;\nimport static org.junit.jupiter.api.Assertions.*;\n\npublic class Template {\n\t// Template definitions\n\t\t.\n\t\t.\n\t\t.\n}\n```\nThen the generated test classes will have a package name that is the same as the focal class' package name. The ``import static org.junit.jupiter.api.Assertions.*`` import statement will also be added to the test classes. \n\n### Predefined Templates\nTo help developers get started using DScribe, we provide a set of [six predefined templates](https://github.com/prmr/DScribe/blob/master/dscribe/templates/Template.java) that capture well-known universal specification such as specfications about exceptions, clones contracts, and equals contracts. We also provide the corresponding [annotation definitions](https://github.com/prmr/DScribe/blob/annotations/dscribe/DScribeAnnotations.java) for each of the predefined templates.\n\t\n### Invoking Templates\nTo invoke a template, you annotate the focal method with the annotation corresponding to the template. For example, to use the `AssertThrows` template to test and document the method `int divide(int x, int y)`, simply annotate the method with the `AssertThrows` annotation and pass the template's placeholder values as input to the annotation. \n```\n@AssertThrows(state=\"DivisorIsZero\", exType=java.lang.IllegalArugmentException, params = {\"5\", \"0\"})\npublic int divide(int x, int y) {\n\tif (y == 0) throw new IllegalArgumentException();\n\treturn x/y;\n}\n```\nYou do not need to pass values for the `$method$` and `$class$` placeholders. They are predefined placeholders, their values are derived directly from the focal method and its declaring class.\n\n## Installing DScribe\nThere are different ways to run DScribe\u0026mdash;as an Eclipse project, as a jar file, or using the more user-friendly DScribe Eclipse plug-in. \n\n**Eclipse Project:** You can import this repository as an Eclipse project, and run it with a recent Java version (\u003e= 11).\n\n**Compiling sources:** All source files are in the `src/main/java` folder, and dependencies are distributed in the `libs` folder.\n\n**Eclipse Plug-in:** To learn how to install and use the DScribe Eclipse plug-in, checkout the [plug-in's README](https://github.com/prmr/DScribe-plugin). \n\n## Configuring DScribe\nTo use DScribe, add the following files to your project:\n```\n├── dscribe \t\t\t\t\t\n|   └── config.properties     \u003c- Defines DScribe configuration properties\n|   └── templates             \u003c- The DScribe template repository\n|        └── Template.java    \u003c- Java class defining DScribe templates \n|        └── ... \n```\nThe `config.properties`can define the following properties: \n* `templateRepoPath`: relative path to the DScribe template repository, `dscribe/templates` by default. \n* `binFolder`: the name of the project's binary folder on the classpath, `bin` by default.\n* `srcFolder`: the name of the project's source folder on the classpath, \t`src` by default.\n* `testFolder`: the name of the project's test folder, `test` by default.\n* `testClassNameConvention`: the test class naming convention to use to identify the test class associated with a given production class. The two options are `prefix` (e.g., given a production class `Calculator`look for a test class named `CalculatorTest`) and `post` (e.g., `TestCalculator`).  The default is `post`. \n\nLook [here](https://github.com/prmr/DScribe/blob/master/dscribe/config.properties) for an example `config.properties` file! \n\n## Running DScribe\n### Using the DScribe Eclipse Plug-in \nThe DScribe Eclipse plug-in's [README](https://github.com/prmr/DScribe-plugin) explains how you can use it to run DScribe.\n\n### Using an Eclipse Project or Jar File \nThe entry point of DScribe is the `main` method in `ca.mcgill.cs.swevo.dscribe.DScribe`. Use command line arguments to specify which operation you want to perform, among the following:\n\n- `generateTests`: This operation generates unit tests for all template invocations (e.g., method-level Java annotations) in the inputted focal class(es). When a unit test is generated, it is added to the test class associated with the focal method's declaring type. The template invocation is moved from the focal method to the resulting test method.\n\n  To use this operation, provide a space-separated list of the fully qualified names of the classes for which you want to generate unit tests. For example,\n\n  ```\n  java -cp libs/*.jar:bin:your/project ca.mcgill.cs.swevo.dscribe.DScribe generateTests com.mypackage.MyClass1 com.mypackage.MyClass2\n  ```\n\n- `generateDocs`: This operation generates documentation based on the template invocations in the inputted focal classes as well as in their associated test classes. \n\n  To use this operation, provide a space-separated list of the fully qualified names of the classes for which you want to generate documentation. For example,\n\n  ```\n  java -cp libs/*.jar:bin:your/project ca.mcgill.cs.swevo.dscribe.DScribe generateDocs com.mypackage.MyClass1\n  ```\n\n## Dependencies\n\nDScribe depends on the following Java libraries:\n\n1. *Picocli* is a one-file library to create CLI applications easily. We redistribute the source code of this library in our source folder.\n2. *JavaParser* is a library to parse Java source files into ASTs. The compiled class files are included in the `libs` folder.\n\nAll dependencies are licensed under the Apache License 2.0 (the same as this tool). A copy of the license is included with this software.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprmr%2Fdscribe","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fprmr%2Fdscribe","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fprmr%2Fdscribe/lists"}