{"id":20713865,"url":"https://github.com/diffplug/durian-globals","last_synced_at":"2026-03-02T14:37:56.587Z","repository":{"id":57718800,"uuid":"224536067","full_name":"diffplug/durian-globals","owner":"diffplug","description":"Globals are useful.  Durian makes them testable too.","archived":false,"fork":false,"pushed_at":"2020-06-06T00:38:40.000Z","size":248,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-04-23T08:08:14.152Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","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/diffplug.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-11-27T23:50:15.000Z","updated_at":"2022-02-04T09:59:53.000Z","dependencies_parsed_at":"2022-09-26T21:40:28.916Z","dependency_job_id":null,"html_url":"https://github.com/diffplug/durian-globals","commit_stats":null,"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diffplug%2Fdurian-globals","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diffplug%2Fdurian-globals/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diffplug%2Fdurian-globals/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/diffplug%2Fdurian-globals/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/diffplug","download_url":"https://codeload.github.com/diffplug/durian-globals/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250395288,"owners_count":21423400,"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-17T02:27:49.491Z","updated_at":"2026-03-02T14:37:51.539Z","avatar_url":"https://github.com/diffplug.png","language":"Java","readme":"# \u003cimg align=\"left\" src=\"logo.png\"\u003e DurianGlobals: Easy-to-test singletons\n\n\u003c!---freshmark shields\noutput = [\n    link(shield('Maven central', 'mavencentral', 'com.diffplug.durian-globals:durian-globals', 'blue'), 'https://search.maven.org/search?q=g:com.diffplug.durian-globals'),\n    link(shield('Apache 2.0', 'license', 'apache-2.0', 'blue'), 'https://tldrlegal.com/license/apache-license-2.0-(apache-2.0)'),\n    '',\n    link(shield('Changelog', 'changelog', versionLast, 'brightgreen'), 'CHANGELOG.md'),\n    link(shield('Javadoc', 'javadoc', 'yes', 'brightgreen'), 'https://javadoc.jitpack.io/com/github/diffplug/durian-globals/durian-globals-agg/release~{{versionLast}}/javadoc/'),\n    link(shield('Live chat', 'gitter', 'chat', 'brightgreen'), 'https://gitter.im/diffplug/durian'),\n    link(image('JitCI', 'https://jitci.com/gh/diffplug/durian-globals/svg'), 'https://jitci.com/gh/diffplug/durian-globals')\n    ].join('\\n');\n--\u003e\n[![Maven central](https://img.shields.io/badge/mavencentral-com.diffplug.durian--globals%3Adurian--globals-blue.svg)](https://search.maven.org/search?q=g:com.diffplug.durian-globals)\n[![Apache 2.0](https://img.shields.io/badge/license-apache--2.0-blue.svg)](https://tldrlegal.com/license/apache-license-2.0-(apache-2.0))\n\n[![Changelog](https://img.shields.io/badge/changelog-1.0.0-brightgreen.svg)](CHANGELOG.md)\n[![Javadoc](https://img.shields.io/badge/javadoc-yes-brightgreen.svg)](https://javadoc.jitpack.io/com/github/diffplug/durian-globals/durian-globals-agg/release~1.0.0/javadoc/)\n[![Live chat](https://img.shields.io/badge/gitter-chat-brightgreen.svg)](https://gitter.im/diffplug/durian)\n[![JitCI](https://jitci.com/gh/diffplug/durian-globals/svg)](https://jitci.com/gh/diffplug/durian-globals)\n\u003c!---freshmark /shields --\u003e\n\n\u003c!---freshmark javadoc\noutput = prefixDelimiterReplace(input, 'https://javadoc.jitpack.io/com/github/diffplug/durian-globals/durian-globals-agg/release~', '/', versionLast)\noutput = prefixDelimiterReplace(output, \"'com.diffplug.durian-globals:durian-globals:\", \"'\", versionLast)\noutput = prefixDelimiterReplace(output, \"'com.diffplug.durian-globals:durian-globals.dev:\", \"'\", versionLast)\n--\u003e\n\n## Usage\n\nProvides an easy way to initialize a singleton exactly once:\n\n```java\npublic class Singleton {\n  public static Singleton instance() {\n    return Globals.getOrSetTo(Singleton.class, Singleton::new);\n  }\n\n  protected Singleton() {}\n  ...\n}\n```\n\nIn a testing environment, you can wipe the globals to get a clean state or to replace the standard implementation with a testing one.\n\n```java\npublic class SingletonTest {\n  static class SingletonDev extends Singleton {\n    ...\n  }\n\n  @Test\n  public void someTest() {\n    try (AutoCloseable wipeGlobals = GlobalsDev.wipe()) {\n      SingletonDev dev = new SingletonDev();\n      GlobalsDev.install(Singleton.class, dev);\n      ...\n    }\n  }\n}\n```\n\nThe \"trick\" is that `GlobalsDev` is shipped in a different artifact than the rest, so you can be sure that your `Globals` can only be changed in tests, and never in production code:\n\n```gradle\ndependencies {\n  implementation     'com.diffplug.durian-globals:durian-globals:1.0.0'\n  testImplementation 'com.diffplug.durian-globals:durian-globals.dev:1.0.0'\n}\n```\n\n## Built-ins\n\nThere are some globals that people frequently want control over during testing.\n\n### Time\n\nYou can use [`public static long Time.now()`](https://javadoc.jitpack.io/com/github/diffplug/durian-globals/durian-globals-agg/release~1.0.0/javadoc/com/diffplug/common/globals/Time.html) as a replacement for `System.currentTimeMillis()`.  And in a test, you can replace it with [`TimeDev`](https://javadoc.jitpack.io/com/github/diffplug/durian-globals/durian-globals-agg/release~1.0.0/javadoc/com/diffplug/common/globals/TimeDev.html).\n\n```java\n@Test\npublic void someTimeDependentTest() {\n  try (AutoCloseable wipeGlobals = GlobalsDev.wipe()) {\n    TimeDev time = TimeDev.install();\n    time.setUTC(LocalDate.parse(\"2019-03-30\"));\n    ... // exercise code that uses `Time.now()`\n  }\n}\n```\n\n\u003c!---freshmark /javadoc --\u003e\n\n## Requirements\n\nDurianGlobals requires nothing but Java 8+.\n\n## In the wild\n\n- Integration testing the [spotless-changelog](https://github.com/diffplug/spotless-changelog) gradle plugin\n  - [build setup](https://github.com/diffplug/spotless-changelog/blob/c6c66eb12e5ce8a23d42fcb34ef3753382ee4cb4/build.gradle#L52-L54)\n  - [integration code](https://github.com/diffplug/spotless-changelog/blob/11fb5f5cd13921f8ecf8151092fdbad44b6f3004/spotless-changelog-plugin-gradle/src/test/java/com/diffplug/spotless/changelog/gradle/ChangelogPluginTest.java#L33-L34)\n\n## Acknowledgements\n\n* Built by [gradle](http://gradle.org/).\n* Tested by [junit](http://junit.org/).\n* Maintained by [DiffPlug](http://www.diffplug.com/).\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdiffplug%2Fdurian-globals","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdiffplug%2Fdurian-globals","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdiffplug%2Fdurian-globals/lists"}