softlaunch 0.5.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,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