Skip to content

Commit 1bd8bbd

Browse files
committed
Merge pull request #2 from e2/class_builder
Implement Nenv::Builder for creating static classes
2 parents bfe6358 + d1b164b commit 1bd8bbd

File tree

8 files changed

+94
-15
lines changed

8 files changed

+94
-15
lines changed

Diff for: Gemfile

+1
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,5 @@ gem 'coveralls', require: false
88
group :development do
99
gem 'guard-rspec', '~> 4.5', require: false
1010
gem 'guard-rubocop', require: false
11+
gem 'pry'
1112
end

Diff for: README.md

+15-3
Original file line numberDiff line numberDiff line change
@@ -186,17 +186,29 @@ Nenv.path += Pathname.pwd + "foo"
186186
187187
```
188188
189-
### Your own class
189+
### Your own class (recommended version for simpler unit tests)
190+
191+
```ruby
192+
MyEnv = Nenv::Builder.build do
193+
create_method(:foo?)
194+
end
195+
196+
MyEnv.new('my').foo? # same as ENV['MY_FOO'][/^(?:false|no|n|0)/i,1].nil?
197+
198+
```
199+
200+
201+
### Your own class (dynamic version - not recommended because harder to test)
190202
191203
```ruby
192204
class MyEnv < Nenv::Environment
193205
def initialize
194-
super("my_env")
206+
super("my")
195207
create_method(:foo?)
196208
end
197209
end
198210
199-
MyEnv.new.foo? # same as ENV['MY_ENV_FOO'][/^(?:false|no|n|0)/i,1].nil?
211+
MyEnv.new.foo? # same as ENV['MY_FOO'][/^(?:false|no|n|0)/i,1].nil?
200212
201213
```
202214

Diff for: lib/nenv.rb

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
require 'nenv/version'
22

33
require 'nenv/autoenvironment'
4+
require 'nenv/builder'
45

56
def Nenv(namespace = nil)
67
Nenv::AutoEnvironment.new(namespace)

Diff for: lib/nenv/builder.rb

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
require 'nenv/environment'
2+
3+
module Nenv
4+
module Builder
5+
def self.build(&block)
6+
Class.new(Nenv::Environment, &block)
7+
end
8+
end
9+
end

Diff for: lib/nenv/environment.rb

+21-10
Original file line numberDiff line numberDiff line change
@@ -22,26 +22,37 @@ def initialize(namespace = nil)
2222
@namespace = (namespace ? namespace.upcase : nil)
2323
end
2424

25+
def self.create_method(meth, &block)
26+
_create_env_method(self, meth, &block)
27+
end
28+
2529
def create_method(meth, &block)
26-
fail(AlreadyExistsError, meth) if respond_to?(meth)
30+
self.class._create_env_method(class << self; self; end, meth, &block)
31+
end
32+
33+
private
34+
35+
def _sanitize(meth)
36+
meth.to_s[/^([^=?]*)[=?]?$/, 1].upcase
37+
end
2738

28-
(class << self; self; end).send(:define_method, meth) do |*args|
29-
raw_value = args.first
39+
def self._create_env_method(instance, meth, &block)
40+
_fail_if_exists(instance, meth)
41+
42+
instance.send(:define_method, meth) do |*args|
3043
env_name = [@namespace, _sanitize(meth)].compact.join('_')
3144

32-
callback = block
3345
if args.size == 1
34-
ENV[env_name] = Dumper.new.dump(raw_value, &callback)
46+
raw_value = args.first
47+
ENV[env_name] = Dumper.new.dump(raw_value, &block)
3548
else
36-
Loader.new(meth).load(ENV[env_name], &callback)
49+
Loader.new(meth).load(ENV[env_name], &block)
3750
end
3851
end
3952
end
4053

41-
private
42-
43-
def _sanitize(meth)
44-
meth.to_s[/^([^=?]*)[=?]?$/, 1].upcase
54+
def self._fail_if_exists(instance, meth)
55+
fail(AlreadyExistsError, meth) if instance.instance_methods.include?(meth)
4556
end
4657
end
4758
end

Diff for: spec/lib/nenv/builder_spec.rb

+27
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
require 'nenv/builder'
2+
3+
RSpec.describe Nenv::Builder do
4+
describe '#build' do
5+
before do
6+
allow(ENV).to receive(:[]).with('FOO')
7+
end
8+
9+
it 'returns a class with the given methods' do
10+
FooEnv = Nenv::Builder.build do
11+
create_method(:foo?)
12+
end
13+
FooEnv.new.foo?
14+
end
15+
16+
context 'with duplicate methods' do
17+
it 'fails' do
18+
expect do
19+
FooEnv = Nenv::Builder.build do
20+
create_method(:foo?)
21+
create_method(:foo?)
22+
end
23+
end.to raise_error(Nenv::Environment::AlreadyExistsError)
24+
end
25+
end
26+
end
27+
end

Diff for: spec/lib/nenv_spec.rb

+14-1
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
end
1717
end
1818

19-
describe 'Nenv() module' do
19+
describe 'Nenv module' do
2020
it 'reads from env' do
2121
expect(ENV).to receive(:[]).with('CI').and_return('true')
2222
Nenv.ci?
@@ -50,4 +50,17 @@
5050
end
5151
end
5252
end
53+
54+
# Test added here to properly test if builder is required
55+
describe 'Nenv builder' do
56+
before do
57+
allow(ENV).to receive(:[]).with('FOO').and_return('false')
58+
end
59+
it 'is required and works' do
60+
FooEnv = Nenv::Builder.build do
61+
create_method(:foo?)
62+
end
63+
FooEnv.new.foo?
64+
end
65+
end
5366
end

Diff for: spec/spec_helper.rb

+6-1
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
mocks.verify_partial_doubles = true
1111
end
1212

13-
config.filter_run :focus
13+
config.filter_run focus: ENV['CI'] != 'true'
1414
config.run_all_when_everything_filtered = true
1515

1616
config.disable_monkey_patching!
@@ -33,6 +33,11 @@
3333
allow(ENV).to receive(:[]=) do |key, value|
3434
fail "stub me: ENV[#{key.inspect}] = #{value.inspect}"
3535
end
36+
37+
allow(ENV).to receive(:[]).with('PRYRC').and_call_original
38+
allow(ENV).to receive(:[]).with('DISABLE_PRY').and_call_original
39+
allow(ENV).to receive(:[]).with('ANSICON').and_call_original
40+
allow(ENV).to receive(:[]).with('TERM').and_call_original
3641
end
3742

3843
config.after do

0 commit comments

Comments
 (0)