dry-web 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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