Skip to content

Commit 6c7ae3a

Browse files
author
Ricardo Quiñones
committed
Adds specs and finalizes library code to ensure that .env.example declared variables are set
1 parent 2e9e42a commit 6c7ae3a

File tree

6 files changed

+172
-8
lines changed

6 files changed

+172
-8
lines changed

Diff for: .ruby-version

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2.2.2

Diff for: dotenv_safe.gemspec

+4
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Gem::Specification.new do |spec|
1616
}
1717
spec.homepage = "https://github/wework/dotenv_safe"
1818
spec.license = "MIT"
19+
spec.required_ruby_version = '>= 2.2.2'
1920

2021
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
2122
# to allow pushing to a single host or delete this section to allow pushing to any host.
@@ -33,8 +34,11 @@ Gem::Specification.new do |spec|
3334
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
3435
spec.require_paths = ["lib"]
3536

37+
spec.add_dependency "dotenv-rails", '~> 2.1.1'
38+
3639
spec.add_development_dependency "bundler", "~> 1.13"
3740
spec.add_development_dependency "rake", "~> 10.0"
3841
spec.add_development_dependency "rspec", "~> 3.0"
42+
spec.add_development_dependency "rails", "~> 4.0"
3943
spec.add_development_dependency "pry"
4044
end

Diff for: lib/dotenv_safe.rb

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
require "dotenv_safe/version"
1+
require 'dotenv_safe/version'
22
require 'dotenv_safe/railtie' if defined?(Rails)
33

44
module DotenvSafe

Diff for: lib/dotenv_safe/railtie.rb

+53-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,62 @@
1+
require 'dotenv'
2+
13
module DotenvSafe
2-
class Railtie < Rails::Railtie
4+
class MissingEnvVarError < StandardError; end
5+
6+
class Railtie < ::Rails::Railtie
37
config.before_configuration do
8+
# Make sure to force load environment variables for dotenv in development
9+
if Rails.env.development?
10+
Dotenv::Railtie.load
11+
end
12+
413
check_env_vars
514
end
615

716
def check_env_vars
8-
raise StandardError.new('I am an error')
17+
missing_env_vars = aggregate_missing_env_vars
18+
19+
if missing_env_vars.any?
20+
raise MissingEnvVarError.new([
21+
'Missing the following environment variables: ',
22+
missing_env_vars.to_sentence
23+
].join(''))
24+
end
25+
end
26+
27+
private
28+
29+
# Returns an array of missing environment variables
30+
#
31+
# @return [Array<String>]
32+
def aggregate_missing_env_vars
33+
example_env_vars.inject([]) do |array, key_and_value|
34+
key = key_and_value[0]
35+
36+
begin
37+
ENV.fetch(key)
38+
array
39+
rescue KeyError
40+
array << key
41+
end
42+
end
43+
end
44+
45+
# Returns a hash of environment variables defined in `.env.example`
46+
#
47+
# @return [Hash]
48+
def example_env_vars
49+
Dotenv::Parser.call(read)
50+
rescue Errno::ENOENT, Dotenv::FormatError
51+
{}
52+
end
53+
54+
def read
55+
File.open(root.join('.env.example'), "rb:bom|utf-8", &:read)
56+
end
57+
58+
def root
59+
Rails.root || Pathname.new(ENV["RAILS_ROOT"] || Dir.pwd)
960
end
1061
end
1162
end

Diff for: spec/dotenv_safe_spec.rb

+109-4
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,116 @@
11
require "spec_helper"
22

33
describe DotenvSafe do
4-
it "has a version number" do
5-
expect(DotenvSafe::VERSION).not_to be nil
4+
let(:rail_tie) { DotenvSafe::Railtie.send(:new) }
5+
6+
describe '#check_env_vars' do
7+
let(:valid_env_file_contents) do
8+
[
9+
"FOO=bar\n",
10+
"BAR=\n",
11+
].join('')
12+
end
13+
14+
let(:invalid_env_file_contents) do
15+
[
16+
"FOO=\n",
17+
"BAR=foo\n",
18+
"NOT_SET_1=foo\n",
19+
"NOT_SET_2=\n",
20+
].join('')
21+
end
22+
23+
before do
24+
allow(ENV).to receive(:fetch)
25+
allow(ENV).to receive(:fetch).with('FOO').and_return('bar')
26+
allow(ENV).to receive(:fetch).with('BAR').and_return('foo')
27+
allow(ENV).to receive(:fetch).with('NOT_SET_1').and_raise(KeyError)
28+
allow(ENV).to receive(:fetch).with('NOT_SET_2').and_raise(KeyError)
29+
end
30+
31+
context 'with all required environment variables set' do
32+
it 'should not raise an error when all the variables are present' do
33+
allow(rail_tie).to receive(:read).and_return(valid_env_file_contents)
34+
expect { rail_tie.check_env_vars }.to_not raise_error
35+
end
36+
end
37+
38+
context 'with some required environment variables not set' do
39+
it 'should raise an error when missing required environment variables' do
40+
allow(rail_tie).to receive(:read).and_return(invalid_env_file_contents)
41+
expect {
42+
rail_tie.check_env_vars
43+
}.to raise_error(DotenvSafe::MissingEnvVarError)
44+
end
45+
end
646
end
747

8-
it "does something useful" do
9-
expect(false).to eq(true)
48+
describe '#example_env_vars' do
49+
context 'with no .env.example file' do
50+
it 'returns an empty array if no file found' do
51+
expect(rail_tie.send(:example_env_vars)).to eq({})
52+
end
53+
end
54+
55+
context 'with .env.example file' do
56+
context 'with no valid environment variables' do
57+
let(:invalid_env_file_contents) do
58+
[
59+
"foo\n",
60+
"bar\n",
61+
"stuff\n",
62+
].join('')
63+
end
64+
65+
before do
66+
allow(rail_tie).to receive(:read).and_return(invalid_env_file_contents)
67+
end
68+
69+
it 'returns an empty hash' do
70+
expect(rail_tie.send(:example_env_vars)).to eq({})
71+
end
72+
end
73+
74+
context 'with valid environment variables' do
75+
context 'without comments' do
76+
let(:valid_env_file_contents) do
77+
[
78+
"FOO_VAR=bar\n",
79+
"BAR_VAR=foo\n",
80+
].join('')
81+
end
82+
83+
before do
84+
allow(rail_tie).to receive(:read).and_return(valid_env_file_contents)
85+
end
86+
87+
it 'returns some example env vars' do
88+
expect(rail_tie.send(:example_env_vars)).to eq({
89+
'FOO_VAR' => 'bar',
90+
'BAR_VAR' => 'foo',
91+
})
92+
end
93+
end
94+
95+
context 'with comments' do
96+
let(:valid_env_file_contents) do
97+
[
98+
"FOO_VAR=bar\n",
99+
"# BAR_VAR=foo\n",
100+
].join('')
101+
end
102+
103+
before do
104+
allow(rail_tie).to receive(:read).and_return(valid_env_file_contents)
105+
end
106+
107+
it 'returns non-commented out example env vars' do
108+
expect(rail_tie.send(:example_env_vars)).to eq({
109+
'FOO_VAR' => 'bar',
110+
})
111+
end
112+
end
113+
end
114+
end
10115
end
11116
end

Diff for: spec/spec_helper.rb

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
$LOAD_PATH.unshift File.expand_path("../../lib", __FILE__)
2-
require "dotenv_safe"
2+
require 'pry'
3+
require 'dotenv_safe'
4+
require 'rails'
5+
require 'dotenv_safe/railtie' # explicit require for testing

0 commit comments

Comments
 (0)