From 33b6355bcf80ed6093e0f43235d32d4d85229ab3 Mon Sep 17 00:00:00 2001 From: Sambo Chea Date: Wed, 24 Mar 2021 14:10:25 +0700 Subject: [PATCH] Add configurable with functions Add more tests for call functions and fixed --- example/example.dart | 14 ++++++- lib/configurable.dart | 9 +++++ lib/dotenv/dotenv.dart | 39 +++++-------------- .../{parser.dart => dotenv_parser.dart} | 11 ++---- lib/dotenv_configuration_provider.dart | 6 ++- lib/system_config.dart | 2 + test/config_test.dart | 26 ++++++++++++- 7 files changed, 67 insertions(+), 40 deletions(-) create mode 100644 lib/configurable.dart rename lib/dotenv/{parser.dart => dotenv_parser.dart} (85%) diff --git a/example/example.dart b/example/example.dart index 31ed13f..24a92d2 100644 --- a/example/example.dart +++ b/example/example.dart @@ -1,3 +1,15 @@ +import 'package:configurable/dotenv_configuration_provider.dart'; +import 'package:configurable/simple_configuration_provider.dart'; + void main() { - print('Example'); + var key = 'app.name'; + var value = 'CUBETIQ Solution'; + + // in-memory provider (built-in) + var simpleProvider = SimpleConfigurationProvider(); + + // dotenv provider (from file .env) + var dotenvProvider = DotenvConfigurationProvider(); + + } \ No newline at end of file diff --git a/lib/configurable.dart b/lib/configurable.dart new file mode 100644 index 0000000..994641a --- /dev/null +++ b/lib/configurable.dart @@ -0,0 +1,9 @@ +library configurable; + +import 'package:configurable/system_config.dart'; + +String? getConfigOrNull(String key, {String? defaultValue}) => + SystemConfig.getOrNull(key, defaultValue: defaultValue); +String getConfig(String key, {String? defaultValue}) => + SystemConfig.get(key, defaultValue: defaultValue); +bool hasConfigkey(String key) => SystemConfig.containsKey(key); diff --git a/lib/dotenv/dotenv.dart b/lib/dotenv/dotenv.dart index a84f42c..4de9857 100644 --- a/lib/dotenv/dotenv.dart +++ b/lib/dotenv/dotenv.dart @@ -1,54 +1,35 @@ -/// Loads environment variables from a `.env` file. -/// -/// ## usage -/// -/// Once you call [load], the top-level [env] map is available. -/// You may wish to prefix the import. -/// -/// import 'package:dotenv/dotenv.dart' show load, env; -/// -/// void main() { -/// load(); -/// var x = env['foo']; -/// // ... -/// } -/// -/// Verify required variables are present: -/// -/// const _requiredEnvVars = const ['host', 'port']; -/// bool get hasEnv => isEveryDefined(_requiredEnvVars); library dotenv; import 'dart:io'; import 'package:meta/meta.dart'; -part 'parser.dart'; +// load functions from parser +part 'dotenv_parser.dart'; +// create in-memory variables store var _env = Map.from(Platform.environment); -/// A copy of [Platform.environment](dart:io) including variables loaded at runtime from a file. +// move from platforms env with default vars Map get env => _env; -/// Overwrite [env] with a new writable copy of [Platform.environment](dart:io). +// clean the env and set default from platform environment Map clean() => _env = Map.from(Platform.environment); -/// True if all supplied variables have nonempty value; false otherwise. -/// Differs from [containsKey](dart:core) by excluding null values. -/// Note [load] should be called first. +// check the variables that defined in .env or platform env bool isEveryDefined(Iterable vars) => vars.every((k) => _env[k] != null && (_env[k]?.isNotEmpty ?? false)); -/// Read environment variables from [filename] and add them to [env]. -/// Logs to [stderr] if [filename] does not exist. -void load([String filename = '.env', Parser psr = const Parser()]) { +// load file .env from project root +void load([String filename = '.env', DotenvParser psr = const DotenvParser()]) { var file = File.fromUri(Uri.file(filename)); var lines = _verify(file); _env.addAll(psr.parse(lines)); } +// verify file .env List _verify(File file) { if (file.existsSync()) return file.readAsLinesSync(); stderr.writeln('[dotenv] Load failed: file not found: $file'); return []; -} \ No newline at end of file +} diff --git a/lib/dotenv/parser.dart b/lib/dotenv/dotenv_parser.dart similarity index 85% rename from lib/dotenv/parser.dart rename to lib/dotenv/dotenv_parser.dart index 2b6dec2..a8bd2e1 100644 --- a/lib/dotenv/parser.dart +++ b/lib/dotenv/dotenv_parser.dart @@ -1,8 +1,6 @@ part of dotenv; -/// Creates key-value pairs from strings formatted as environment -/// variable definitions. -class Parser { +class DotenvParser { static const _singleQuot = "'"; static const _keyword = 'export'; @@ -10,11 +8,9 @@ class Parser { static final _surroundQuotes = RegExp(r'''^(['"])(.*)\1$'''); static final _bashVar = RegExp(r'(?:\\)?(\$)(?:{)?([a-zA-Z_][\w]*)+(?:})?'); - /// [Parser] methods are pure functions. - const Parser(); + // constructor for parser + const DotenvParser(); - /// Creates a [Map](dart:core) suitable for merging into [Platform.environment](dart:io). - /// Duplicate keys are silently discarded. Map parse(Iterable lines) { var out = {}; lines.forEach((line) { @@ -79,7 +75,6 @@ class Parser { bool _isValid(String s) => s.isNotEmpty && s.contains('='); - /// [null] is a valid value in a Dart map, but the env var representation is empty string, not the string 'null' bool _has(Map map, String key) => map.containsKey(key) && map[key] != null; diff --git a/lib/dotenv_configuration_provider.dart b/lib/dotenv_configuration_provider.dart index 6e65370..40f6d24 100644 --- a/lib/dotenv_configuration_provider.dart +++ b/lib/dotenv_configuration_provider.dart @@ -1,7 +1,11 @@ import 'package:configurable/configuration_provider.dart'; -import 'package:configurable/dotenv/dotenv.dart' show env; +import 'package:configurable/dotenv/dotenv.dart' show env, load; class DotenvConfigurationProvider implements ConfigurationProvider { + DotenvConfigurationProvider() { + load(); + } + @override bool containsKey(String key) { return env.containsKey(key); diff --git a/lib/system_config.dart b/lib/system_config.dart index 186fa0d..f9b2a23 100644 --- a/lib/system_config.dart +++ b/lib/system_config.dart @@ -23,4 +23,6 @@ class SystemConfig { static String? getOrNull(String key, {String? defaultValue}) { return getProvider().getOrNull(key, defaultValue: defaultValue); } + + static bool containsKey(String key) => getProvider().containsKey(key); } diff --git a/test/config_test.dart b/test/config_test.dart index 0ca2ca0..e420b67 100644 --- a/test/config_test.dart +++ b/test/config_test.dart @@ -1,3 +1,5 @@ +import 'package:configurable/configurable.dart' show getConfigOrNull; +import 'package:configurable/dotenv_configuration_provider.dart'; import 'package:configurable/system_config.dart'; import 'package:test/test.dart'; @@ -10,5 +12,27 @@ void main() { expect(value, equals(result)); expect(value, equals(SystemConfig.getOrNull(key))); }); - + + test('get system config by key with dotenv provider', () { + var key = 'app.name'; + var value = 'CUBETIQ Solution'; + + // set dotenv provider + SystemConfig.setProvider(DotenvConfigurationProvider()); + + var result = SystemConfig.getOrNull(key); + + expect(value, equals(result)); + expect(value, equals(SystemConfig.getOrNull(key))); + }); + + test('get config by key with function', () { + var key = 'app.name'; + var value = 'CUBETIQ Solution'; + + var result = getConfigOrNull(key, defaultValue: value); + + expect(value, equals(result)); + expect(value, equals(getConfigOrNull(key))); + }); }