Add configurable with functions

Add more tests for call functions and fixed
This commit is contained in:
Sambo Chea 2021-03-24 14:10:25 +07:00
parent a51d5fe00b
commit 33b6355bcf
7 changed files with 67 additions and 40 deletions

View File

@ -1,3 +1,15 @@
import 'package:configurable/dotenv_configuration_provider.dart';
import 'package:configurable/simple_configuration_provider.dart';
void main() { 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();
} }

9
lib/configurable.dart Normal file
View File

@ -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);

View File

@ -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; library dotenv;
import 'dart:io'; import 'dart:io';
import 'package:meta/meta.dart'; import 'package:meta/meta.dart';
part 'parser.dart'; // load functions from parser
part 'dotenv_parser.dart';
// create in-memory variables store
var _env = Map<String, String>.from(Platform.environment); var _env = Map<String, String>.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<String, String> get env => _env; Map<String, String> 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); Map clean() => _env = Map.from(Platform.environment);
/// True if all supplied variables have nonempty value; false otherwise. // check the variables that defined in .env or platform env
/// Differs from [containsKey](dart:core) by excluding null values.
/// Note [load] should be called first.
bool isEveryDefined(Iterable<String> vars) => bool isEveryDefined(Iterable<String> vars) =>
vars.every((k) => _env[k] != null && (_env[k]?.isNotEmpty ?? false)); vars.every((k) => _env[k] != null && (_env[k]?.isNotEmpty ?? false));
/// Read environment variables from [filename] and add them to [env]. // load file .env from project root
/// Logs to [stderr] if [filename] does not exist. void load([String filename = '.env', DotenvParser psr = const DotenvParser()]) {
void load([String filename = '.env', Parser psr = const Parser()]) {
var file = File.fromUri(Uri.file(filename)); var file = File.fromUri(Uri.file(filename));
var lines = _verify(file); var lines = _verify(file);
_env.addAll(psr.parse(lines)); _env.addAll(psr.parse(lines));
} }
// verify file .env
List<String> _verify(File file) { List<String> _verify(File file) {
if (file.existsSync()) return file.readAsLinesSync(); if (file.existsSync()) return file.readAsLinesSync();
stderr.writeln('[dotenv] Load failed: file not found: $file'); stderr.writeln('[dotenv] Load failed: file not found: $file');
return []; return [];
} }

View File

@ -1,8 +1,6 @@
part of dotenv; part of dotenv;
/// Creates key-value pairs from strings formatted as environment class DotenvParser {
/// variable definitions.
class Parser {
static const _singleQuot = "'"; static const _singleQuot = "'";
static const _keyword = 'export'; static const _keyword = 'export';
@ -10,11 +8,9 @@ class Parser {
static final _surroundQuotes = RegExp(r'''^(['"])(.*)\1$'''); static final _surroundQuotes = RegExp(r'''^(['"])(.*)\1$''');
static final _bashVar = RegExp(r'(?:\\)?(\$)(?:{)?([a-zA-Z_][\w]*)+(?:})?'); static final _bashVar = RegExp(r'(?:\\)?(\$)(?:{)?([a-zA-Z_][\w]*)+(?:})?');
/// [Parser] methods are pure functions. // constructor for parser
const Parser(); const DotenvParser();
/// Creates a [Map](dart:core) suitable for merging into [Platform.environment](dart:io).
/// Duplicate keys are silently discarded.
Map<String, String> parse(Iterable<String> lines) { Map<String, String> parse(Iterable<String> lines) {
var out = <String, String>{}; var out = <String, String>{};
lines.forEach((line) { lines.forEach((line) {
@ -79,7 +75,6 @@ class Parser {
bool _isValid(String s) => s.isNotEmpty && s.contains('='); 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<String, String> map, String key) => bool _has(Map<String, String> map, String key) =>
map.containsKey(key) && map[key] != null; map.containsKey(key) && map[key] != null;

View File

@ -1,7 +1,11 @@
import 'package:configurable/configuration_provider.dart'; 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 { class DotenvConfigurationProvider implements ConfigurationProvider {
DotenvConfigurationProvider() {
load();
}
@override @override
bool containsKey(String key) { bool containsKey(String key) {
return env.containsKey(key); return env.containsKey(key);

View File

@ -23,4 +23,6 @@ class SystemConfig {
static String? getOrNull(String key, {String? defaultValue}) { static String? getOrNull(String key, {String? defaultValue}) {
return getProvider().getOrNull(key, defaultValue: defaultValue); return getProvider().getOrNull(key, defaultValue: defaultValue);
} }
static bool containsKey(String key) => getProvider().containsKey(key);
} }

View File

@ -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:configurable/system_config.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
@ -10,5 +12,27 @@ void main() {
expect(value, equals(result)); expect(value, equals(result));
expect(value, equals(SystemConfig.getOrNull(key))); 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)));
});
} }