softlaunch 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/.rspec ADDED
@@ -0,0 +1 @@
1
+ --color
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in softlaunch.gemspec
4
+ gemspec
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 Lee Atchison
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,233 @@
1
+ # Soft Launch
2
+
3
+ Soft Launch is a mechanism that allows you to add new features to a web application, but limit which of your users has access to them. This allows you to give access to a new feature to a limited set of users,
4
+ while at the same time letting them try out the new feature in a full production environment.
5
+
6
+ You use Soft Launch by defining "features". A feature is a piece of functionality that you want to roll out to a specific subset of individuals. An example feature may be a newly designed
7
+ account settings page, for example.
8
+
9
+ You define features in your config/softlaunch.yml file. This file specifies the name of a feature and whether or not the feature should be enabled for a particular rails environment or not.
10
+ Here is an example configuration file for launching a newly redesigned accout settings page:
11
+
12
+ ```ruby
13
+ development:
14
+ acctsettings:
15
+ name: New Account Settings Page
16
+ status: enabled
17
+
18
+ test:
19
+ acctsettings:
20
+ name: New Account Settings Page
21
+ status: enabled
22
+
23
+ production:
24
+ acctsettings:
25
+ name: New Account Settings Page
26
+ status: disabled
27
+ ```
28
+
29
+ Now, in your controllers, models, views, helpers, etc., you can query whether a given feature is enabled for a specific page request or not by using code similar to this?
30
+
31
+ ```ruby
32
+ if launched? :acctsettings
33
+ ...code for the new page...
34
+ else
35
+ ...code for the old page...
36
+ end
37
+ ```
38
+
39
+ Using Soft Launch, you can enable/disable features by rails environment (shown above). For a disabled feature, you can enable it for a given subset of users.
40
+ You can also allow a user to enable the feature by setting a cookie by going to a special URL in your application to enable/disable a feature.
41
+
42
+ Note: Soft Launch should not be used to enable unstable or untested features. It's purpose isn't to replace the normal testing process. It's purpose is to provide limited exposure to a set
43
+ of features before making them more globally available to everyone using your application.
44
+
45
+ # Installation
46
+
47
+ Soft Launch requires Rails 3.0 or greater.
48
+ Add this to your Gemfile and run the bundle command:
49
+
50
+ ```ruby
51
+ gem "softlaunch"
52
+ ```
53
+
54
+ Now, run this command:
55
+
56
+ ```ruby
57
+ rails generate soft_launch:setup
58
+ ```
59
+
60
+ This will create an initializer file and add an entry to your route.rb file.
61
+
62
+ # Getting Started
63
+
64
+ Let's say you added a feature to display a new newsfeed on your home page. You want to develop and test that feature in a controlled environment, as normal.
65
+ However, you'll want to roll this out to only a few people in production to judge feedback first, before rolling it out to everyone, so you enable
66
+ Soft Launch.
67
+
68
+ Follow the installation instructions above, then you'll find a config/softlaunch.yml file in your application, it will contain something like this:
69
+
70
+ ```yml
71
+ development:
72
+ myfeature:
73
+ name: My New Feature
74
+ status: enabled
75
+
76
+ test:
77
+ myfeature:
78
+ name: My New Feature
79
+ status: enabled
80
+
81
+ production:
82
+ myfeature:
83
+ name: My New Feature
84
+ status: disabled
85
+ ```
86
+
87
+ By default, this feature will be setup to be enabled in development and test, but not production. Let's change the name and identifier of this feature to
88
+ something more meaningful to us:
89
+
90
+ ```yml
91
+ development:
92
+ newsfeed:
93
+ name: Display home page newsfeed
94
+ status: enabled
95
+
96
+ test:
97
+ newsfeed:
98
+ name: Display home page newsfeed
99
+ status: enabled
100
+
101
+ production:
102
+ newsfeed:
103
+ name: Display home page newsfeed
104
+ status: disabled
105
+ ```
106
+
107
+ Now, let's go to our view template for our home page:
108
+
109
+ ```erb
110
+ file: app/views/home/index.html.erb
111
+ ...
112
+ <%if launched? :newsfeed%>
113
+ <h2>Welcome to my New Newsfeed!</h2>
114
+ <@newsfeed.each do |article%>
115
+ ...
116
+ <%end%>
117
+ <%else%>
118
+ Put whatever I had on the page before the newsfeed was added here.
119
+ <%end%>
120
+ ...
121
+ ```
122
+
123
+ Since your newsfeed will likely need data from our controller, add it as well:
124
+
125
+ ```ruby
126
+ file: app/controllers/home_controllber.rb
127
+ ...
128
+ def index
129
+ ... do other stuff here ...
130
+ if launched? :newsfeed
131
+ @newsfeed=NewsFeed.most_recent_news
132
+ end
133
+ end
134
+ ...
135
+ ```
136
+
137
+ Now, when you show this page in development and test mode, you'll see the newsfeed. But when it is displayed in production, the original
138
+ content is displayed.
139
+
140
+ ## Enabling it for a Specific Person's Browser
141
+ Let's say you want to see what it looks like now in production.
142
+ Update your config file to show the following:
143
+
144
+ ```yml
145
+ development:
146
+ newsfeed:
147
+ name: Display home page newsfeed
148
+ status: enabled
149
+
150
+ test:
151
+ newsfeed:
152
+ name: Display home page newsfeed
153
+ status: enabled
154
+
155
+ production:
156
+ newsfeed:
157
+ name: Display home page newsfeed
158
+ status: user
159
+ usercode: C04D9454C8EB449C8B4E6A72157B4AA4
160
+ ```
161
+
162
+ The 'usercode' is a random, unique code assigned to this newsfeed. We used a UUID for this example (sans dashes), but you can
163
+ use any value you like. You want the value to be "hard to guess", as it will be used in the URL that enables your new feature
164
+ for a specific user and their browser.
165
+
166
+ Now, in production, go to your home page, you'll see the "old" content. You can enable the new content just for you by going to this
167
+ URL:
168
+
169
+ http://<myapplication>/softlaunch/C04D9454C8EB449C8B4E6A72157B4AA4
170
+
171
+ On this page, you'll see whether this feature is enabled for your browser or not, and will be given the option to enable/disable this feature.
172
+ Enable the feature, and go back to your home page.
173
+
174
+ You will now see that your home page has the new newsfeed.
175
+
176
+ Go to a different browser or a different computer and load the home page. You'll see the old content is still visible to you.
177
+
178
+ A cookie has been set in your browser, which is what is used to enable the feature. It is only enabled for you and only with the
179
+ current browser.
180
+
181
+ You can now give that URL to other people (beta testers, for instance) and let them use the feature. If they have problems with
182
+ it or don't like it, they can always turn it off. Note that you should tell them not to share the URL with other people, as
183
+ anyone with the URL will know how to enable the feature (which is why the unique identifier should be hard to guess).
184
+
185
+ At any point in time, you can enable this feature for everybody by changing your config file (and redeploying), changing the
186
+ production section of the config file to show this:
187
+
188
+ ```yml
189
+ production:
190
+ newsfeed:
191
+ name: Display home page newsfeed
192
+ status: enabled
193
+ ```
194
+
195
+ Or, if you want to disable the feature to everyone (because it wasn't well received or you want to work on it some more),
196
+ you can change it to this:
197
+
198
+ ```yml
199
+ production:
200
+ newsfeed:
201
+ name: Display home page newsfeed
202
+ status: disabled
203
+ ```
204
+
205
+ When it is disabled, even people with the cookie set will not be able to see the feature.
206
+
207
+ Once you have finished permanently launching the feature (or permanently deciding not to launch it), you can go and refactor
208
+ your code to remove the "if launched?" statements and the unused code, then remove the feature from the softlaunch.yml
209
+ file.
210
+
211
+ # Questions or Problems?
212
+
213
+ Please note that this is not yet released, and is still a work in progress.
214
+
215
+ Suggestions for this gem can be sent to me.
216
+
217
+ # Testing Soft Launch
218
+
219
+ Simply run "rake test". The gem uses rspec for all of it's test suites.
220
+
221
+ # Using Can Can?
222
+
223
+ If you are using Can Can, and have the following line in your application_controller.rb file:
224
+
225
+ ```ruby
226
+ check_authorization
227
+ ```
228
+
229
+ You should update it to exclude the soft launch controller:
230
+
231
+ ```ruby
232
+ check_authorization :unless => :soft_launch_controller?
233
+ ```
@@ -0,0 +1,7 @@
1
+ require "bundler/gem_tasks"
2
+ require 'rspec/core/rake_task'
3
+
4
+ RSpec::Core::RakeTask.new(:spec)
5
+
6
+ task default: :spec
7
+ task test: :spec
@@ -0,0 +1,26 @@
1
+ class SoftLaunch
2
+ class SoftLaunchController < ApplicationController
3
+
4
+ def show
5
+ @softlaunch=SoftLaunch.find_by_usercode params[:id]
6
+ render :layout => SoftLaunch.engine_layout
7
+ end
8
+
9
+ def update
10
+ @softlaunch=SoftLaunch.find_by_usercode params[:id]
11
+ if params[:sl_enable].to_i!=0
12
+ @softlaunch.enable=true
13
+ flash[:info]="Enabled feature #{@softlaunch.name}"
14
+ else
15
+ @softlaunch.enable=false
16
+ flash[:info]="Disabled feature #{@softlaunch.name}"
17
+ end
18
+ redirect_to soft_launch_path id: @softlaunch.usercode
19
+ end
20
+
21
+ def soft_launch_controller?
22
+ true
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,31 @@
1
+ <h1>Soft Launch: <%=@softlaunch.name%></h1>
2
+ <table class="softlaunchstatus">
3
+ <tr>
4
+ <td class="label">Public Status: </td>
5
+ <td class="value"><%=@softlaunch.status_string%></td>
6
+ </tr>
7
+ <tr>
8
+ <td class="label">This Browser Status: </td>
9
+ <%if @softlaunch.launched?%>
10
+ <td class="value">
11
+ Enabled
12
+ </td>
13
+ <td class="value">
14
+ <%=form_for @softlaunch.usercode,:method=>:put do |f|%>
15
+ <%=hidden_field_tag :sl_enable,0%>
16
+ <%=f.submit "Disable"%>
17
+ <%end%>
18
+ </td>
19
+ <%else%>
20
+ <td class="value">
21
+ Disabled
22
+ </td>
23
+ <td class="value">
24
+ <%=form_for @softlaunch.usercode,:method=>:put do |f|%>
25
+ <%=hidden_field_tag :sl_enable,1%>
26
+ <%=f.submit "Enable"%>
27
+ <%end%>
28
+ </td>
29
+ <%end%>
30
+ </tr>
31
+ </table>
@@ -0,0 +1,3 @@
1
+ SoftLaunch::Engine.routes.draw do
2
+ resources :soft_launch, only: [:show,:update],path: ""
3
+ end
@@ -0,0 +1,10 @@
1
+ class SoftLaunch
2
+ class SetupGenerator < Rails::Generators::Base
3
+ source_root File.expand_path('../templates', __FILE__)
4
+ def create_initializer
5
+ copy_file "softlaunch_init.rb", "config/initializers/softlaunch_init.rb"
6
+ copy_file "softlaunch.yml", "config/softlaunch.yml"
7
+ route "mount SoftLaunch::Engine => \"/softlaunch\""
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,14 @@
1
+ development:
2
+ myfeature:
3
+ name: My New Feature
4
+ status: enabled
5
+
6
+ test:
7
+ myfeature:
8
+ name: My New Feature
9
+ status: enabled
10
+
11
+ production:
12
+ myfeature:
13
+ name: My New Feature
14
+ status: disabled
@@ -0,0 +1,23 @@
1
+ #
2
+ #
3
+ # SoftLaunch Configuration
4
+ #
5
+ #
6
+
7
+ #
8
+ # Specify the location of the configuraiton file.
9
+ # Default: RAILS_ROOT/config/softlaunch.yml
10
+ #
11
+ SoftLaunch.config_file=Rails.root.join "config/softlaunch.yml"
12
+
13
+ #
14
+ # Specify a layout file to use for the softlaunch feature page.
15
+ # NOTE: If you specify a layout file for the engine, then in this layout file, all
16
+ # URL helpers must be prefixed with "main_app". So, for instance, you can't use
17
+ # "root_path", you must use "main_app.root_path". If you do not do this, you will
18
+ # get errors when rendering a page from the engine. Specify 'nil' will not use any
19
+ # template file.
20
+ # This is due to how engines handle namespaced applications.
21
+ #
22
+ SoftLaunch.engine_layout=nil # Do not use any layout file.
23
+ # SoftLaunch.engine_layout="application" # Use the global application layout file.
@@ -0,0 +1,9 @@
1
+ require "softlaunch/version"
2
+ require "softlaunch/errors"
3
+ require "softlaunch/config"
4
+ require "softlaunch/finders"
5
+ require "softlaunch/cookies"
6
+ require "softlaunch/accessors"
7
+ require "softlaunch/initialize"
8
+ require "softlaunch/include_appctlr"
9
+ require "softlaunch/engine"
@@ -0,0 +1,33 @@
1
+ require 'yaml'
2
+ class SoftLaunch
3
+
4
+ def launched?
5
+ return true if @status==:enabled
6
+ return false if @status==:disabled
7
+ return false if !user_specific?
8
+ return cookie_enabled?
9
+ end
10
+
11
+ def enabled?
12
+ @status==:enabled
13
+ end
14
+
15
+ def disabled?
16
+ @status==:disabled
17
+ end
18
+
19
+ def user_specific?
20
+ @status==:user
21
+ end
22
+
23
+ def status_string
24
+ case @status
25
+ when :disabled then "Disabled"
26
+ when :enabled then "Enabled"
27
+ when :user then "Per User"
28
+ else
29
+ "???#{@status}???"
30
+ end
31
+ end
32
+
33
+ end
@@ -0,0 +1,33 @@
1
+ class SoftLaunch
2
+
3
+ class << self
4
+ attr_accessor :cookies, :engine_layout
5
+
6
+ def reset
7
+ @config_file=nil
8
+ @config=nil
9
+ end
10
+
11
+ def config_file= config_file # Where is the config file located?
12
+ raise FileAlreadyInUse if @config
13
+ @config_file=config_file
14
+ end
15
+ def config_file
16
+ @config_file||=Rails.root.join "config/softlaunch.yml"
17
+ end
18
+
19
+ def config
20
+ return @config if @config
21
+ raw_config = File.read(config_file)
22
+ if raw_config.nil?
23
+ puts "No configuration file provided"
24
+ logger.error "No configuration file provided"
25
+ raise InvalidConfiguration
26
+ end
27
+ @config = YAML::load(raw_config)[ENV["RAILS_ENV"]||"development"]
28
+ @config
29
+ end
30
+
31
+ end
32
+
33
+ end
@@ -0,0 +1,24 @@
1
+ class SoftLaunch
2
+
3
+ def enable= status
4
+ if status
5
+ SoftLaunch.cookies[cookie_name]=true
6
+ else
7
+ SoftLaunch.cookies.delete cookie_name
8
+ end
9
+ end
10
+
11
+ private
12
+
13
+ def cookie_enabled?
14
+ raise SoftLaunch::CookiesNotConfigured if SoftLaunch.cookies.nil?
15
+ # User Status...(force true and false, even if 1, 0, nil, etc.)
16
+ return true if SoftLaunch.cookies[cookie_name]
17
+ return false
18
+ end
19
+
20
+ def cookie_name
21
+ "soft_launch_#{id}".to_sym
22
+ end
23
+
24
+ end
@@ -0,0 +1,20 @@
1
+ class SoftLaunch
2
+
3
+ if defined? Rails
4
+
5
+ class Engine < Rails::Engine
6
+ engine_name "soft_launch"
7
+ isolate_namespace SoftLaunch
8
+ initializer 'soft_launch.controller' do |app|
9
+ ActiveSupport.on_load(:action_controller) do
10
+ include SoftLaunchApplicationController
11
+ helper_method :launched?
12
+ helper_method :softlaunch
13
+ before_filter :setup_soft_launch
14
+ end
15
+ end
16
+ end
17
+
18
+ end
19
+
20
+ end
@@ -0,0 +1,12 @@
1
+ class SoftLaunch
2
+
3
+ class << self
4
+
5
+ class FileAlreadyInUse<Exception;end
6
+ class InvalidFeature<Exception;end
7
+ class InvalidConfiguration<Exception;end
8
+ class CookiesNotConfigured<Exception;end
9
+
10
+ end
11
+
12
+ end
@@ -0,0 +1,27 @@
1
+ class SoftLaunch
2
+
3
+ class << self
4
+
5
+ def all
6
+ ret=[]
7
+ config.each do |id,data|
8
+ ret<<SoftLaunch.new(id)
9
+ end
10
+ ret
11
+ end
12
+ def find feature
13
+ config.each do |id,data|
14
+ return SoftLaunch.new id if id.to_s==feature.to_s
15
+ end
16
+ return nil
17
+ end
18
+ def find_by_usercode usercode
19
+ config.each do |id,data|
20
+ return SoftLaunch.new id if data["usercode"] and data["usercode"].to_s == usercode.to_s
21
+ end
22
+ return nil
23
+ end
24
+
25
+ end
26
+
27
+ end
@@ -0,0 +1,17 @@
1
+ module SoftLaunchApplicationController
2
+
3
+ def launched? ident
4
+ sl=SoftLaunch.find ident
5
+ return false if sl.nil?
6
+ sl.launched?
7
+ end
8
+
9
+ def softlaunch ident
10
+ launched? ident
11
+ end
12
+
13
+ def setup_soft_launch
14
+ SoftLaunch.cookies=cookies
15
+ end
16
+
17
+ end
@@ -0,0 +1,14 @@
1
+ require 'yaml'
2
+ class SoftLaunch
3
+ attr_reader :id,:name,:usercode
4
+
5
+ def initialize feature_id
6
+ info=SoftLaunch.config[feature_id.to_s]
7
+ raise SoftLaunch::InvalidFeature if info.nil?
8
+ @id=feature_id
9
+ @name=info["name"]
10
+ @status=info["status"].to_sym
11
+ @usercode=info["usercode"]
12
+ end
13
+
14
+ end
@@ -0,0 +1,3 @@
1
+ module Softlaunch
2
+ VERSION = "0.5.1"
3
+ end
@@ -0,0 +1,23 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "softlaunch/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "softlaunch"
7
+ s.version = Softlaunch::VERSION
8
+ s.authors = ["Lee Atchison"]
9
+ s.email = ["lee@leeatchison.com"]
10
+ s.homepage = ""
11
+ s.summary = %q{Stage the launch of new features to smaller groups of people first.}
12
+ s.description = %q{Stage the launch of new features to smaller groups of people first.}
13
+
14
+ s.rubyforge_project = "softlaunch"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ s.add_development_dependency "rspec"
23
+ end
@@ -0,0 +1,11 @@
1
+ test:
2
+ feature1:
3
+ name: My New Feature 1
4
+ status: enabled
5
+ feature2:
6
+ name: My New Feature 2
7
+ status: disabled
8
+ feature3:
9
+ name: My New Feature 3
10
+ status: user
11
+ usercode: thisisasampleusercode
@@ -0,0 +1,22 @@
1
+ require 'spec_helper'
2
+
3
+ describe "Soft Launch Asker" do
4
+ before :each do
5
+ SoftLaunch.reset
6
+ SoftLaunch.config_file=Rails.root.join "spec/config_templates/basic.yml"
7
+ end
8
+ it "should report launched if feature is enabled" do
9
+ launched?(:feature1).should be_true
10
+ end
11
+ it "should report not launched if feature is disabled" do
12
+ launched?(:feature2).should be_false
13
+ end
14
+ it "should report launched if feature is user and there is a proper cookie" do
15
+ SoftLaunch.cookies={:soft_launch_feature3=>true}
16
+ launched?(:feature3).should be_true
17
+ end
18
+ it "should report not launched if feature is user and there is no proper cookie" do
19
+ SoftLaunch.cookies={}
20
+ launched?(:feature1).should be_false
21
+ end
22
+ end
@@ -0,0 +1,83 @@
1
+ require 'spec_helper'
2
+
3
+ describe SoftLaunch do
4
+ before :each do
5
+ SoftLaunch.reset
6
+ SoftLaunch.config_file="spec/config_templates/basic.yml"
7
+ end
8
+ it "reads configuration from a specified configuration file" do
9
+ SoftLaunch.config_file.should eq "spec/config_templates/basic.yml"
10
+ end
11
+ it "allows setting features as enabled" do
12
+ sl=SoftLaunch.find "feature1"
13
+ sl.name.should eq "My New Feature 1"
14
+ sl.enabled?.should be_true
15
+ sl.disabled?.should be_false
16
+ sl.user_specific?.should be_false
17
+ end
18
+ it "allows setting features as disabled" do
19
+ sl=SoftLaunch.find "feature2"
20
+ sl.name.should eq "My New Feature 2"
21
+ sl.enabled?.should be_false
22
+ sl.disabled?.should be_true
23
+ sl.user_specific?.should be_false
24
+ end
25
+ it "allows setting features as user enablable" do
26
+ sl=SoftLaunch.find "feature3"
27
+ sl.name.should eq "My New Feature 3"
28
+ sl.enabled?.should be_false
29
+ sl.disabled?.should be_false
30
+ sl.user_specific?.should be_true
31
+ end
32
+ it "should report launched if feature is enabled" do
33
+ sl=SoftLaunch.find "feature1"
34
+ sl.launched?.should be_true
35
+ end
36
+ it "should report not launched if feature is disabled" do
37
+ sl=SoftLaunch.find "feature2"
38
+ sl.launched?.should be_false
39
+ end
40
+ it "should report launched if feature is user and there is a proper cookie" do
41
+ SoftLaunch.cookies={:soft_launch_feature3=>true}
42
+ sl=SoftLaunch.find "feature3"
43
+ sl.launched?.should be_true
44
+ end
45
+ it "should report not launched if feature is user and there is no proper cookie" do
46
+ SoftLaunch.cookies={}
47
+ sl=SoftLaunch.find "feature3"
48
+ sl.launched?.should be_false
49
+ end
50
+ it "should be able to get a list of all features" do
51
+ list=SoftLaunch.all
52
+ list.size.should eq 3
53
+ list[0].name.should eq "My New Feature 1"
54
+ list[1].name.should eq "My New Feature 2"
55
+ list[2].name.should eq "My New Feature 3"
56
+ end
57
+ it "should be able to look up a feature by feature name" do
58
+ feature=SoftLaunch.find "feature2"
59
+ feature.name.should eq "My New Feature 2"
60
+ end
61
+ it "should be able to look up a feature by user code" do
62
+ feature=SoftLaunch.find_by_usercode "thisisasampleusercode"
63
+ feature.name.should eq "My New Feature 3"
64
+ end
65
+
66
+ it "should be able to set a cookie to enable a feature" do
67
+ cookies={}
68
+ cookies[:soft_launch_feature3].should be_nil
69
+ SoftLaunch.cookies=cookies
70
+ sl=SoftLaunch.find "feature3"
71
+ sl.enable=true
72
+ cookies[:soft_launch_feature3].should be_true
73
+ end
74
+ it "should be able to clear a cookie to disable a feature" do
75
+ cookies={:soft_launch_feature3=>true}
76
+ cookies[:soft_launch_feature3].should be_true
77
+ SoftLaunch.cookies=cookies
78
+ sl=SoftLaunch.find "feature3"
79
+ sl.enable=false
80
+ cookies[:soft_launch_feature3].should be_nil
81
+ end
82
+
83
+ end
@@ -0,0 +1,2 @@
1
+ require 'softlaunch'
2
+ ENV["RAILS_ENV"]||="test"
metadata ADDED
@@ -0,0 +1,87 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: softlaunch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.5.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Lee Atchison
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-11-23 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: &70316284707900 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: *70316284707900
25
+ description: Stage the launch of new features to smaller groups of people first.
26
+ email:
27
+ - lee@leeatchison.com
28
+ executables: []
29
+ extensions: []
30
+ extra_rdoc_files: []
31
+ files:
32
+ - .gitignore
33
+ - .rspec
34
+ - Gemfile
35
+ - LICENSE
36
+ - README.md
37
+ - Rakefile
38
+ - app/controllers/soft_launch/soft_launch_controller.rb
39
+ - app/views/soft_launch/soft_launch/show.html.erb
40
+ - config/routes.rb
41
+ - lib/generators/soft_launch/setup/setup_generator.rb
42
+ - lib/generators/soft_launch/setup/templates/softlaunch.yml
43
+ - lib/generators/soft_launch/setup/templates/softlaunch_init.rb
44
+ - lib/softlaunch.rb
45
+ - lib/softlaunch/accessors.rb
46
+ - lib/softlaunch/config.rb
47
+ - lib/softlaunch/cookies.rb
48
+ - lib/softlaunch/engine.rb
49
+ - lib/softlaunch/errors.rb
50
+ - lib/softlaunch/finders.rb
51
+ - lib/softlaunch/include_appctlr.rb
52
+ - lib/softlaunch/initialize.rb
53
+ - lib/softlaunch/version.rb
54
+ - softlaunch.gemspec
55
+ - spec/config_templates/basic.yml
56
+ - spec/softlaunch_asker.rb
57
+ - spec/softlaunch_spec.rb
58
+ - spec/spec_helper.rb
59
+ homepage: ''
60
+ licenses: []
61
+ post_install_message:
62
+ rdoc_options: []
63
+ require_paths:
64
+ - lib
65
+ required_ruby_version: !ruby/object:Gem::Requirement
66
+ none: false
67
+ requirements:
68
+ - - ! '>='
69
+ - !ruby/object:Gem::Version
70
+ version: '0'
71
+ required_rubygems_version: !ruby/object:Gem::Requirement
72
+ none: false
73
+ requirements:
74
+ - - ! '>='
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ requirements: []
78
+ rubyforge_project: softlaunch
79
+ rubygems_version: 1.8.10
80
+ signing_key:
81
+ specification_version: 3
82
+ summary: Stage the launch of new features to smaller groups of people first.
83
+ test_files:
84
+ - spec/config_templates/basic.yml
85
+ - spec/softlaunch_asker.rb
86
+ - spec/softlaunch_spec.rb
87
+ - spec/spec_helper.rb