climate_control 0.0.1

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.
@@ -0,0 +1,17 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
@@ -0,0 +1,9 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.9.2
4
+ - 1.9.3
5
+ before_install:
6
+ - gem update --system
7
+ branches:
8
+ only:
9
+ - master
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in climate_control.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2012 Joshua Clayton and thoughtbot, inc.
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/NEWS ADDED
@@ -0,0 +1,2 @@
1
+ 0.0.1 (November 28, 2012)
2
+ Initial release
@@ -0,0 +1,89 @@
1
+ # Climate Control
2
+
3
+ Easily manage your environment.
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'climate_control'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install climate_control
18
+
19
+ ## Usage
20
+
21
+ `ClimateControl` can be used to temporarily assign environment variables
22
+ within a block:
23
+
24
+ ```ruby
25
+ ClimateControl::Modifier.new CONFIRMATION_INSTRUCTIONS_BCC: 'confirmation_bcc@example.com' do
26
+ sign_up_as 'john@example.com'
27
+ confirm_account_for_email 'john@example.com'
28
+ current_email.should bcc_to('confirmation_bcc@example.com')
29
+ end
30
+ ```
31
+
32
+ To use with RSpec, you could define this in your spec:
33
+
34
+ ```ruby
35
+ def with_modified_env(options, &block)
36
+ ClimateControl::Modifier.new(options, &block)
37
+ end
38
+ ```
39
+
40
+ This would allow for more straightforward way to modify the environment:
41
+
42
+ ```ruby
43
+ require 'spec_helper'
44
+
45
+ describe Thing, 'name' do
46
+ it 'appends ADDITIONAL_NAME' do
47
+ with_modified_env ADDITIONAL_NAME: 'bar' do
48
+ expect(Thing.new.name).to eq('John Doe Bar')
49
+ end
50
+ end
51
+
52
+ def with_modified_env(options, &block)
53
+ ClimateControl::Modifier.new(options, &block)
54
+ end
55
+ end
56
+ ```
57
+
58
+ To modify the environment for an entire set of tests in RSpec, use an `around`
59
+ block:
60
+
61
+ ```ruby
62
+ describe Thing, 'name' do
63
+ # ... tests
64
+
65
+ around do |example|
66
+ ClimateControl::Modifier.new FOO: 'bar' do
67
+ example.run
68
+ end
69
+ end
70
+ end
71
+ ```
72
+
73
+ Environment variables assigned within the block will be preserved;
74
+ essentially, the code should behave exactly the same with and without the
75
+ block, except for the overrides. Transparency is crucial because the code
76
+ executed within the block is not for `ClimateControl` to manage or modify. See
77
+ the tests for more detail about the specific behaviors.
78
+
79
+ ## Contributing
80
+
81
+ 1. Fork it
82
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
83
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
84
+ 4. Push to the branch (`git push origin my-new-feature`)
85
+ 5. Create new Pull Request
86
+
87
+ ## License
88
+
89
+ climate_control is copyright 2012 Joshua Clayton and thoughtbot, inc. It is free software and may be redistributed under the terms specified in the LICENSE.txt file.
@@ -0,0 +1,6 @@
1
+ require 'bundler/gem_tasks'
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:rspec)
5
+
6
+ task default: :rspec
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'climate_control/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = 'climate_control'
8
+ gem.version = ClimateControl::VERSION
9
+ gem.authors = ['Joshua Clayton']
10
+ gem.email = ['joshua.clayton@gmail.com']
11
+ gem.description = %q{Modify your ENV}
12
+ gem.summary = %q{Modify your ENV easily with ClimateControl}
13
+ gem.homepage = 'https://github.com/thoughtbot/climate_control'
14
+
15
+ gem.files = `git ls-files`.split($/)
16
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
17
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
+ gem.require_paths = ['lib']
19
+
20
+ gem.add_dependency 'activesupport', '>= 3.0'
21
+ gem.add_development_dependency 'rspec', '~> 2.11'
22
+ gem.add_development_dependency 'rake', '~> 0.9.2'
23
+ gem.add_development_dependency 'simplecov', '~> 0.7.1'
24
+ end
@@ -0,0 +1,5 @@
1
+ require 'climate_control/modifier'
2
+ require 'climate_control/version'
3
+
4
+ module ClimateControl
5
+ end
@@ -0,0 +1,86 @@
1
+ require 'active_support/core_ext/hash/keys'
2
+
3
+ module ClimateControl
4
+ class Modifier
5
+ def initialize(environment_overrides = {}, &block)
6
+ @environment_overrides = environment_overrides.dup.stringify_keys!
7
+ @block = block
8
+
9
+ process
10
+ end
11
+
12
+ private
13
+
14
+ def process
15
+ begin
16
+ prepare_environment_for_block
17
+ run_block
18
+ ensure
19
+ cache_environment_after_block
20
+ delete_keys_that_do_not_belong
21
+ revert_changed_keys
22
+ end
23
+ end
24
+
25
+ def prepare_environment_for_block
26
+ @original_env = clone_environment
27
+ copy_overrides_to_environment
28
+ @env_with_overrides_before_block = clone_environment
29
+ end
30
+
31
+ def run_block
32
+ @block.call
33
+ end
34
+
35
+ def copy_overrides_to_environment
36
+ @environment_overrides.each do |key, value|
37
+ ENV[key] = value
38
+ end
39
+ end
40
+
41
+ def keys_to_remove
42
+ @environment_overrides.keys
43
+ end
44
+
45
+ def keys_changed_by_block
46
+ @keys_changed_by_block ||= OverlappingKeysWithChangedValues.new(@env_with_overrides_before_block, @env_after_block).keys
47
+ end
48
+
49
+ def cache_environment_after_block
50
+ @env_after_block = clone_environment
51
+ end
52
+
53
+ def delete_keys_that_do_not_belong
54
+ (keys_to_remove - keys_changed_by_block).each {|key| ENV.delete(key) }
55
+ end
56
+
57
+ def revert_changed_keys
58
+ (@original_env.keys - keys_changed_by_block).each do |key|
59
+ ENV[key] = @original_env[key]
60
+ end
61
+ end
62
+
63
+ def clone_environment
64
+ ENV.to_hash
65
+ end
66
+
67
+ class OverlappingKeysWithChangedValues
68
+ def initialize(hash_1, hash_2)
69
+ @hash_1 = hash_1
70
+ @hash_2 = hash_2
71
+ end
72
+
73
+ def keys
74
+ overlapping_keys.select do |overlapping_key|
75
+ @hash_1[overlapping_key] != @hash_2[overlapping_key]
76
+ end
77
+ end
78
+
79
+ private
80
+
81
+ def overlapping_keys
82
+ @hash_2.keys & @hash_1.keys
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,3 @@
1
+ module ClimateControl
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,75 @@
1
+ require 'spec_helper'
2
+
3
+ describe ClimateControl::Modifier do
4
+ it 'modifies the environment' do
5
+ with_modified_env VARIABLE_1: 'bar', VARIABLE_2: 'qux' do
6
+ expect(ENV['VARIABLE_1']).to eq 'bar'
7
+ expect(ENV['VARIABLE_2']).to eq 'qux'
8
+ end
9
+
10
+ expect(ENV['VARIABLE_1']).to be_nil
11
+ expect(ENV['VARIABLE_2']).to be_nil
12
+ end
13
+
14
+ it 'allows for environment variables to be assigned within the block' do
15
+ with_modified_env VARIABLE_1: 'modified' do
16
+ ENV['ASSIGNED_IN_BLOCK'] = 'assigned'
17
+ end
18
+
19
+ expect(ENV['ASSIGNED_IN_BLOCK']).to eq 'assigned'
20
+ end
21
+
22
+ it 'reassigns previously set environment variables' do
23
+ ENV['VARIABLE_ASSIGNED_BEFORE_MODIFYING_ENV'] = 'original'
24
+ expect(ENV['VARIABLE_ASSIGNED_BEFORE_MODIFYING_ENV']).to eq 'original'
25
+
26
+ with_modified_env VARIABLE_ASSIGNED_BEFORE_MODIFYING_ENV: 'overridden' do
27
+ expect(ENV['VARIABLE_ASSIGNED_BEFORE_MODIFYING_ENV']).to eq 'overridden'
28
+ end
29
+
30
+ expect(ENV['VARIABLE_ASSIGNED_BEFORE_MODIFYING_ENV']).to eq 'original'
31
+ end
32
+
33
+ it 'persists the change when overriding the variable in the block' do
34
+ with_modified_env VARIABLE_MODIFIED_AND_THEN_ASSIGNED: 'modified' do
35
+ ENV['VARIABLE_MODIFIED_AND_THEN_ASSIGNED'] = 'assigned value'
36
+ end
37
+
38
+ expect(ENV['VARIABLE_MODIFIED_AND_THEN_ASSIGNED']).to eq 'assigned value'
39
+ end
40
+
41
+ it 'resets environment variables even if the block raises' do
42
+ expect {
43
+ with_modified_env FOO: 'bar' do
44
+ raise 'broken'
45
+ end
46
+ }.to raise_error
47
+
48
+ expect(ENV['FOO']).to be_nil
49
+ end
50
+
51
+ it 'preserves environment variables set within the block' do
52
+ ENV['CHANGED'] = 'old value'
53
+
54
+ with_modified_env IRRELEVANT: 'ignored value' do
55
+ ENV['CHANGED'] = 'new value'
56
+ end
57
+
58
+ expect(ENV['CHANGED']).to eq 'new value'
59
+ end
60
+
61
+ def with_modified_env(options, &block)
62
+ ClimateControl::Modifier.new(options, &block)
63
+ end
64
+
65
+ around do |example|
66
+ old_env = ENV.to_hash
67
+
68
+ example.run
69
+
70
+ ENV.clear
71
+ old_env.each do |key, value|
72
+ ENV[key] = value
73
+ end
74
+ end
75
+ end
@@ -0,0 +1,11 @@
1
+ require 'simplecov'
2
+ SimpleCov.start
3
+
4
+ $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib')
5
+ $LOAD_PATH << File.join(File.dirname(__FILE__))
6
+
7
+ require 'rubygems'
8
+ require 'rspec'
9
+ require 'climate_control'
10
+
11
+ Dir['spec/support/**/*.rb'].each { |f| require File.expand_path(f) }
metadata ADDED
@@ -0,0 +1,125 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: climate_control
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Joshua Clayton
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2012-11-28 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: activesupport
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '3.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '3.0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: rspec
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: '2.11'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: '2.11'
46
+ - !ruby/object:Gem::Dependency
47
+ name: rake
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 0.9.2
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 0.9.2
62
+ - !ruby/object:Gem::Dependency
63
+ name: simplecov
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 0.7.1
70
+ type: :development
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 0.7.1
78
+ description: Modify your ENV
79
+ email:
80
+ - joshua.clayton@gmail.com
81
+ executables: []
82
+ extensions: []
83
+ extra_rdoc_files: []
84
+ files:
85
+ - .gitignore
86
+ - .travisci.yml
87
+ - Gemfile
88
+ - LICENSE.txt
89
+ - NEWS
90
+ - README.md
91
+ - Rakefile
92
+ - climate_control.gemspec
93
+ - lib/climate_control.rb
94
+ - lib/climate_control/modifier.rb
95
+ - lib/climate_control/version.rb
96
+ - spec/lib/climate_control/modifier_spec.rb
97
+ - spec/spec_helper.rb
98
+ homepage: https://github.com/thoughtbot/climate_control
99
+ licenses: []
100
+ post_install_message:
101
+ rdoc_options: []
102
+ require_paths:
103
+ - lib
104
+ required_ruby_version: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ required_rubygems_version: !ruby/object:Gem::Requirement
111
+ none: false
112
+ requirements:
113
+ - - ! '>='
114
+ - !ruby/object:Gem::Version
115
+ version: '0'
116
+ requirements: []
117
+ rubyforge_project:
118
+ rubygems_version: 1.8.23
119
+ signing_key:
120
+ specification_version: 3
121
+ summary: Modify your ENV easily with ClimateControl
122
+ test_files:
123
+ - spec/lib/climate_control/modifier_spec.rb
124
+ - spec/spec_helper.rb
125
+ has_rdoc: