dry-web 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 1c2ac79f0779539356bd7a516d6a35b72628770b
4
- data.tar.gz: b674f6ce4607fb2e8131f0b215b056aea3bbf301
3
+ metadata.gz: 87f2f5f98072989367f2d0a59ccc9fe8cc4762c0
4
+ data.tar.gz: 50752d39dea5ded3839fba27c48eacc46db5035a
5
5
  SHA512:
6
- metadata.gz: 3cae9a50a5b3679065712c7679abc5371a956590d9e8ba33dcd7e24a18e311c4087dc8431531db648f736a99343a2ca3311052148ae05a7df77ce3a2780d7535
7
- data.tar.gz: 74be24c3d7003f2a661bbc706f80992fb775b538610e1cc6b37d564b0549a4678b0f68a923868c2431355aca3fd56dc08d3fc33ed4892af72622ad09d0c80ef8
6
+ metadata.gz: 04ecc1a070afefdcd7b15776fab6696e837e982df611aa51ed0580651d8c60abfe5cf3a7e85def62408b3619f2bd010feea1ac25f50ee3e23408975bc100d58c
7
+ data.tar.gz: fe7f4569e116734f26ba675ceb8cfa09b2b18bcfc6d0b3180e9220668ef073a9c40031747ecb39e362988a67d0c4d7440488a9f4986cae599c4c21fee2ed4655
@@ -1,3 +1,15 @@
1
+ # v0.3.0 / 2016-06-22
2
+
3
+ ### Added
4
+
5
+ - Added an `Umbrella` subclass of `Dry::Web::Container`, intended to be a single, top-level wrapper around multiple sub-apps in a dry-web project (timriley)
6
+ - Added `Dry::Web::Settings`, designed to work as an app's single, top-level settings object (timriley)
7
+ - Added `env` config to `Dry::Web::Container`, moved across from dry-component (timriley)
8
+
9
+ ### Changed
10
+
11
+ - Renamed `Dry::Web::Cli` to `Dry::Web::Console`, to make room for a real CLI in the future, starting with dry-web-roda (timriley)
12
+
1
13
  # v0.2.0 / 2016-06-12
2
14
 
3
15
  ### Changed
data/Gemfile CHANGED
@@ -2,6 +2,8 @@ source 'https://rubygems.org'
2
2
 
3
3
  gemspec
4
4
 
5
+ gem "dry-component", github: "dry-rb/dry-component", branch: "master"
6
+
5
7
  group :test do
6
8
  gem 'byebug', platform: :mri
7
9
  gem 'codeclimate-test-reporter'
@@ -18,7 +18,7 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_runtime_dependency "dry-component", "~> 0"
21
+ spec.add_runtime_dependency "dry-component"
22
22
 
23
23
  spec.add_development_dependency "bundler", "~> 1.7"
24
24
  spec.add_development_dependency "rake", "~> 11.0"
@@ -1,6 +1,6 @@
1
1
  module Dry
2
2
  module Web
3
- class Cli
3
+ class Console
4
4
  REPL = begin
5
5
  require 'pry'
6
6
  Pry
@@ -0,0 +1,53 @@
1
+ require "yaml"
2
+
3
+ module Dry
4
+ module Web
5
+ class Settings
6
+ SettingValueError = Class.new(StandardError)
7
+
8
+ def self.schema
9
+ @schema ||= {}
10
+ end
11
+
12
+ def self.setting(name, type = nil)
13
+ settings(name => type)
14
+ end
15
+
16
+ def self.settings(new_schema)
17
+ check_schema_duplication(new_schema)
18
+ @schema = schema.merge(new_schema)
19
+
20
+ self
21
+ end
22
+
23
+ def self.check_schema_duplication(new_schema)
24
+ shared_keys = new_schema.keys & schema.keys
25
+
26
+ raise ArgumentError, "Setting :#{shared_keys.first} has already been defined" if shared_keys.any?
27
+ end
28
+ private_class_method :check_schema_duplication
29
+
30
+ def self.load(root, env)
31
+ yaml_path = root.join("config/settings.yml")
32
+ yaml_data = File.exist?(yaml_path) ? YAML.load_file(yaml_path)[env.to_s] : {}
33
+ schema = self.schema
34
+
35
+ Class.new do
36
+ extend Dry::Configurable
37
+
38
+ schema.each do |key, type|
39
+ value = ENV.fetch(key.to_s.upcase) { yaml_data[key.to_s.downcase] }
40
+
41
+ begin
42
+ value = type[value] if type
43
+ rescue => e
44
+ raise SettingValueError, "error typecasting +#{key}+: #{e}"
45
+ end
46
+
47
+ setting key, value
48
+ end
49
+ end.config
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,33 @@
1
+ require "dry/web/container"
2
+
3
+ module Dry
4
+ module Web
5
+ class Umbrella < Dry::Web::Container
6
+ setting :settings_loader
7
+ setting :settings
8
+
9
+ def self.configure(env = config.env, &block)
10
+ super() do |config|
11
+ yield(config) if block
12
+
13
+ if config.settings_loader && config.settings.nil?
14
+ config.settings = load_settings(config.settings_loader, root, env)
15
+ end
16
+ end
17
+
18
+ self
19
+ end
20
+
21
+ def self.load_settings(loader, root, env)
22
+ begin
23
+ loader.load(root, env)
24
+ rescue => e
25
+ puts "Could not load your settings: #{e}"
26
+ puts
27
+ raise e
28
+ end
29
+ end
30
+ private_class_method :load_settings
31
+ end
32
+ end
33
+ end
@@ -1,5 +1,5 @@
1
1
  module Dry
2
2
  module Web
3
- VERSION = '0.2.0'.freeze
3
+ VERSION = '0.3.0'.freeze
4
4
  end
5
5
  end
@@ -0,0 +1,4 @@
1
+ test:
2
+ api_key: "yaml123"
3
+ precompile_assets: "1"
4
+ undeclared: "not declared in settings"
@@ -1,3 +1,5 @@
1
+ ENV["RACK_ENV"] = "test"
2
+
1
3
  if RUBY_ENGINE == "ruby"
2
4
  require "codeclimate-test-reporter"
3
5
  CodeClimate::TestReporter.start
@@ -0,0 +1,80 @@
1
+ require "dry/web/settings"
2
+
3
+ RSpec.describe Dry::Web::Settings do
4
+ describe ".setting" do
5
+ it "raises an error if a duplicate setting is specified" do
6
+ expect {
7
+ Class.new(Dry::Web::Settings) do
8
+ setting :foo
9
+ setting :foo
10
+ end
11
+ }.to raise_error(ArgumentError)
12
+ end
13
+ end
14
+
15
+ describe ".load" do
16
+ subject(:settings) {
17
+ Class.new(Dry::Web::Settings) do
18
+ setting :api_key
19
+ setting :precompile_assets
20
+ setting :env_only_setting
21
+ end.load(SPEC_ROOT.join("fixtures/test"), :test)
22
+ }
23
+
24
+ it "loads settings from ENV first (as upper-cased variables)" do
25
+ ENV["ENV_ONLY_SETTING"] = "hello"
26
+ expect(settings.env_only_setting).to eq "hello"
27
+ end
28
+
29
+ it "loads settings from a YAML file (as lower-cased keys) if unavailable from ENV" do
30
+ expect(settings.api_key).to eq "yaml123"
31
+ end
32
+
33
+ it "ignores undeclared settings in the YAML file" do
34
+ expect(settings).not_to respond_to(:undeclared)
35
+ end
36
+
37
+ context "settings with types" do
38
+ before do
39
+ Test::CoercingBool = Class.new do
40
+ def self.[](val)
41
+ %w[1 true].include?(val.to_s)
42
+ end
43
+ end
44
+
45
+ Test::ConstraintNotMatched = Class.new(ArgumentError)
46
+
47
+ Test::LongString = Class.new do
48
+ def self.[](val)
49
+ raise Test::ConstraintNotMatched, "string must be 12 characters or longer" if val.length < 12
50
+ end
51
+ end
52
+ end
53
+
54
+ context "coercing types" do
55
+ subject(:settings) {
56
+ Class.new(Dry::Web::Settings) do
57
+ setting :precompile_assets, Test::CoercingBool
58
+ end.load(SPEC_ROOT.join("fixtures/test"), :test)
59
+ }
60
+
61
+ it "supports coercion input data" do
62
+ expect(settings.precompile_assets).to eq true
63
+ end
64
+ end
65
+
66
+ context "constraining types" do
67
+ subject(:settings) {
68
+ Class.new(Dry::Web::Settings) do
69
+ setting :api_key, Test::LongString
70
+ end.load(SPEC_ROOT.join("fixtures/test"), :test)
71
+ }
72
+
73
+ it "raises helpful exceptions if input data does not match constraints" do
74
+ expect { settings }.to raise_error(Dry::Web::Settings::SettingValueError)
75
+ expect { settings }.to raise_error(/error typecasting \+api_key\+/)
76
+ end
77
+ end
78
+ end
79
+ end
80
+ end
@@ -0,0 +1,56 @@
1
+ require "dry/web/settings"
2
+ require "dry/web/umbrella"
3
+
4
+ RSpec.describe Dry::Web::Umbrella do
5
+ subject(:umbrella) {
6
+ Class.new(Dry::Web::Umbrella) do
7
+ configure do |config|
8
+ config.root = SPEC_ROOT.join("fixtures/test")
9
+ end
10
+ end
11
+ }
12
+
13
+ describe "config" do
14
+ describe "#settings" do
15
+ subject(:settings) { umbrella.config.settings }
16
+
17
+ context "no settings specified" do
18
+ it "is an empty object" do
19
+ expect(:settings).not_to be_nil
20
+ end
21
+
22
+ it "does not offer any settings" do
23
+ expect(:settings).not_to respond_to(:some_setting)
24
+ end
25
+ end
26
+
27
+ context "settings loader specified" do
28
+ let(:settings_loader) { class_double("Dry::Web::Settings") }
29
+
30
+ it "loads the settings using the specified settings_loader" do
31
+ allow(settings_loader).to receive(:load).with(umbrella.config.root, :test) {
32
+ double("settings", foo: "bar")
33
+ }
34
+
35
+ umbrella.configure do |config|
36
+ config.settings_loader = settings_loader
37
+ end
38
+
39
+ expect(settings.foo).to eq "bar"
40
+ end
41
+ end
42
+
43
+ context "settings object specified" do
44
+ before do
45
+ umbrella.configure do |config|
46
+ config.settings = double("custom settings", bar: "baz")
47
+ end
48
+ end
49
+
50
+ it "leaves the settings object in place" do
51
+ expect(settings.bar).to eq "baz"
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: dry-web
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Piotr Solnica
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-12 00:00:00.000000000 Z
11
+ date: 2016-06-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: dry-component
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
19
  version: '0'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
27
  - !ruby/object:Gem::Dependency
@@ -99,11 +99,16 @@ files:
99
99
  - Rakefile
100
100
  - dry-web.gemspec
101
101
  - lib/dry-web.rb
102
- - lib/dry/web/cli.rb
102
+ - lib/dry/web/console.rb
103
103
  - lib/dry/web/container.rb
104
+ - lib/dry/web/settings.rb
105
+ - lib/dry/web/umbrella.rb
104
106
  - lib/dry/web/version.rb
107
+ - spec/fixtures/test/config/settings.yml
105
108
  - spec/spec_helper.rb
106
109
  - spec/unit/container_spec.rb
110
+ - spec/unit/settings_spec.rb
111
+ - spec/unit/umbrella_spec.rb
107
112
  homepage: https://github.com/dry-rb/dry-web
108
113
  licenses:
109
114
  - MIT
@@ -129,5 +134,8 @@ signing_key:
129
134
  specification_version: 4
130
135
  summary: Lightweight web application stack on top of dry-component
131
136
  test_files:
137
+ - spec/fixtures/test/config/settings.yml
132
138
  - spec/spec_helper.rb
133
139
  - spec/unit/container_spec.rb
140
+ - spec/unit/settings_spec.rb
141
+ - spec/unit/umbrella_spec.rb