detour 0.0.1 → 0.0.2

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.
Files changed (147) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -1
  3. data/.travis.yml +6 -2
  4. data/Gemfile +5 -0
  5. data/README.md +41 -132
  6. data/Rake.md +108 -0
  7. data/Rakefile +21 -1
  8. data/app/assets/fonts/glyphicons-halflings-regular.eot +0 -0
  9. data/app/assets/fonts/glyphicons-halflings-regular.svg +229 -0
  10. data/app/assets/fonts/glyphicons-halflings-regular.ttf +0 -0
  11. data/app/assets/fonts/glyphicons-halflings-regular.woff +0 -0
  12. data/app/assets/images/detour/.gitkeep +0 -0
  13. data/app/assets/javascripts/detour/application.js +16 -0
  14. data/app/assets/javascripts/detour/bootstrap.js +2006 -0
  15. data/app/assets/javascripts/detour/delete_feature.js +13 -0
  16. data/app/assets/javascripts/detour/delete_flag.js +13 -0
  17. data/app/assets/javascripts/detour/modals.js +3 -0
  18. data/app/assets/javascripts/detour/tooltips.js +3 -0
  19. data/app/assets/stylesheets/detour/application.css +14 -0
  20. data/app/assets/stylesheets/detour/bootstrap.css +7112 -0
  21. data/app/assets/stylesheets/detour/main.css +49 -0
  22. data/app/controllers/detour/application_controller.rb +12 -0
  23. data/app/controllers/detour/features_controller.rb +19 -0
  24. data/app/controllers/detour/flaggable_flags_controller.rb +90 -0
  25. data/app/controllers/detour/flags_controller.rb +18 -0
  26. data/app/helpers/detour/application_helper.rb +32 -0
  27. data/app/helpers/detour/flaggable_flags_helper.rb +5 -0
  28. data/app/helpers/detour/flags_helper.rb +7 -0
  29. data/app/models/detour/concerns/countable_flag.rb +19 -0
  30. data/app/models/detour/concerns/flag_actions.rb +141 -0
  31. data/app/models/detour/concerns/matchers.rb +73 -0
  32. data/app/models/detour/feature.rb +81 -0
  33. data/{lib → app/models}/detour/flag.rb +8 -2
  34. data/app/models/detour/flag_in_flag.rb +12 -0
  35. data/app/models/detour/group_flag.rb +13 -0
  36. data/{lib → app/models}/detour/opt_out_flag.rb +4 -2
  37. data/app/models/detour/percentage_flag.rb +9 -0
  38. data/app/views/detour/application/index.html.erb +0 -0
  39. data/app/views/detour/features/_errors.html.erb +11 -0
  40. data/app/views/detour/features/_success.html.erb +1 -0
  41. data/app/views/detour/features/error.js.erb +5 -0
  42. data/app/views/detour/features/success.js.erb +1 -0
  43. data/app/views/detour/flaggable_flags/_errors.html.erb +11 -0
  44. data/app/views/detour/flaggable_flags/_flaggable_flag.html.erb +11 -0
  45. data/app/views/detour/flaggable_flags/error.js.erb +5 -0
  46. data/app/views/detour/flaggable_flags/index.html.erb +34 -0
  47. data/app/views/detour/flaggable_flags/success.js.erb +1 -0
  48. data/app/views/detour/flags/_feature_form.html.erb +38 -0
  49. data/app/views/detour/flags/index.html.erb +76 -0
  50. data/app/views/detour/shared/_nav.html.erb +28 -0
  51. data/app/views/detour/shared/_spacer_cells.html.erb +3 -0
  52. data/app/views/layouts/detour/application.html.erb +29 -0
  53. data/config/routes.rb +16 -0
  54. data/detour.gemspec +15 -14
  55. data/lib/detour/acts_as_flaggable.rb +42 -3
  56. data/lib/detour/configuration.rb +35 -0
  57. data/lib/detour/engine.rb +5 -0
  58. data/lib/detour/flag_form.rb +87 -0
  59. data/lib/detour/version.rb +1 -1
  60. data/lib/detour.rb +10 -14
  61. data/lib/generators/templates/migration.rb +2 -0
  62. data/lib/tasks/detour.rake +16 -16
  63. data/script/rails +8 -0
  64. data/spec/controllers/detour/application_controller_spec.rb +15 -0
  65. data/spec/controllers/detour/features_controller_spec.rb +51 -0
  66. data/spec/controllers/detour/flaggable_flags_controller_spec.rb +100 -0
  67. data/spec/controllers/detour/flags_controller_spec.rb +77 -0
  68. data/spec/dummy/README.rdoc +261 -0
  69. data/spec/dummy/Rakefile +7 -0
  70. data/spec/dummy/app/assets/javascripts/application.js +15 -0
  71. data/spec/dummy/app/assets/stylesheets/application.css +13 -0
  72. data/spec/dummy/app/controllers/application_controller.rb +7 -0
  73. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  74. data/spec/dummy/app/mailers/.gitkeep +0 -0
  75. data/spec/dummy/app/models/.gitkeep +0 -0
  76. data/spec/dummy/app/models/user.rb +5 -0
  77. data/spec/dummy/app/models/widget.rb +5 -0
  78. data/spec/dummy/app/views/application/index.html.erb +22 -0
  79. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  80. data/spec/dummy/config/application.rb +65 -0
  81. data/spec/dummy/config/boot.rb +10 -0
  82. data/spec/dummy/config/database.yml +19 -0
  83. data/spec/dummy/config/environment.rb +5 -0
  84. data/spec/dummy/config/environments/development.rb +37 -0
  85. data/spec/dummy/config/environments/production.rb +67 -0
  86. data/spec/dummy/config/environments/test.rb +37 -0
  87. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  88. data/spec/dummy/config/initializers/detour.rb +36 -0
  89. data/spec/dummy/config/initializers/inflections.rb +15 -0
  90. data/spec/dummy/config/initializers/mime_types.rb +5 -0
  91. data/spec/dummy/config/initializers/secret_token.rb +7 -0
  92. data/spec/dummy/config/initializers/session_store.rb +8 -0
  93. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  94. data/spec/dummy/config/locales/en.yml +5 -0
  95. data/spec/dummy/config/routes.rb +4 -0
  96. data/spec/dummy/config.ru +4 -0
  97. data/spec/dummy/db/migrate/20131218015844_create_users.rb +10 -0
  98. data/spec/dummy/db/migrate/20131218023124_create_widgets.rb +9 -0
  99. data/spec/dummy/db/migrate/20131218055352_add_user_id_to_widgets.rb +6 -0
  100. data/spec/dummy/db/migrate/20131221052201_setup_detour.rb +32 -0
  101. data/spec/dummy/db/schema.rb +59 -0
  102. data/spec/dummy/db/seeds.rb +10 -0
  103. data/spec/dummy/lib/assets/.gitkeep +0 -0
  104. data/spec/dummy/log/.gitkeep +0 -0
  105. data/spec/dummy/public/404.html +26 -0
  106. data/spec/dummy/public/422.html +26 -0
  107. data/spec/dummy/public/500.html +25 -0
  108. data/spec/dummy/public/favicon.ico +0 -0
  109. data/spec/dummy/script/rails +6 -0
  110. data/spec/factories/feature.rb +5 -0
  111. data/spec/factories/flag_in_flag.rb +6 -0
  112. data/spec/factories/group_flag.rb +7 -0
  113. data/spec/factories/opt_out_flag.rb +6 -0
  114. data/spec/factories/percentage_flag.rb +7 -0
  115. data/spec/factories/user.rb +6 -0
  116. data/spec/factories/widget.rb +5 -0
  117. data/spec/features/features_spec.rb +70 -0
  118. data/spec/features/flag_in_flags_spec.rb +118 -0
  119. data/spec/features/group_flags_spec.rb +49 -0
  120. data/spec/features/home_page_spec.rb +11 -0
  121. data/spec/features/opt_out_flags_spec.rb +105 -0
  122. data/spec/features/percentage_flags_spec.rb +63 -0
  123. data/spec/integration/group_rollout_spec.rb +1 -1
  124. data/spec/lib/detour/acts_as_flaggable_spec.rb +45 -0
  125. data/spec/lib/detour/configuration_spec.rb +23 -0
  126. data/spec/lib/detour/flag_form_spec.rb +84 -0
  127. data/spec/lib/{active_record/rollout → detour}/flaggable_spec.rb +19 -19
  128. data/spec/lib/tasks/{detour_rake_spec.rb → detour_spec.rb} +54 -54
  129. data/spec/{lib/active_record/rollout → models/detour}/feature_spec.rb +93 -67
  130. data/spec/models/detour/flag_in_flag_spec.rb +38 -0
  131. data/spec/{lib/active_record/rollout → models/detour}/flag_spec.rb +1 -1
  132. data/spec/models/detour/opt_out_flag_spec.rb +38 -0
  133. data/spec/{lib/active_record/rollout → models/detour}/percentage_flag_spec.rb +1 -1
  134. data/spec/spec_helper.rb +41 -21
  135. data/spec/support/shared_contexts/rake.rb +4 -14
  136. metadata +278 -95
  137. data/lib/detour/feature.rb +0 -312
  138. data/lib/detour/flaggable_flag.rb +0 -10
  139. data/lib/detour/group_flag.rb +0 -8
  140. data/lib/detour/percentage_flag.rb +0 -11
  141. data/spec/lib/active_record/rollout/acts_as_flaggable_spec.rb +0 -31
  142. data/spec/lib/active_record/rollout/flaggable_flag_spec.rb +0 -9
  143. data/spec/lib/active_record/rollout/opt_out_flag_spec.rb +0 -9
  144. data/spec/support/schema.rb +0 -13
  145. /data/lib/generators/{active_record_rollout_generator.rb → detour_generator.rb} +0 -0
  146. /data/lib/generators/templates/{active_record_rollout.rb → detour.rb} +0 -0
  147. /data/spec/{lib/active_record/rollout → models/detour}/group_flag_spec.rb +0 -0
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: fa9eb669cbe85bcf6e060065aa53924ec688e7be
4
+ data.tar.gz: ede70af5253bf7438872a8f9059bf05159b68c31
5
+ SHA512:
6
+ metadata.gz: 79eaf748749d194e084fb6e42bd5bdca11dc86b5543051fb517c78cab35bd9338264187060453964320d7c0a736bac9277d6100d34be244dbc4843213bc234d5
7
+ data.tar.gz: d47913a017eb2cb3de39e58d41e0c62b409113ff2657e74717bbfc123059e60009f5b67bc7c8e45f6ab595f2e6901519bcac4fff440f68656865dc87143574ea
data/.gitignore CHANGED
@@ -1,5 +1,6 @@
1
1
  *.gem
2
2
  *.rbc
3
+ *.log
3
4
  .bundle
4
5
  .config
5
6
  .yardoc
@@ -12,7 +13,7 @@ lib/bundler/man
12
13
  pkg
13
14
  rdoc
14
15
  spec/reports
15
- spec/spec.sqlite3
16
+ *.sqlite3
16
17
  test/tmp
17
18
  test/version_tmp
18
19
  tmp
data/.travis.yml CHANGED
@@ -1,6 +1,10 @@
1
1
  language: ruby
2
2
  rvm:
3
- - 1.9.2
4
3
  - 1.9.3
5
4
  - 2.0.0
6
- script: bundle exec rspec
5
+ - 2.1.0
6
+ before_install: gem install bundler --version '>= 1.5.1'
7
+ script:
8
+ - RAILS_ENV=test bundle exec rake db:create
9
+ - RAILS_ENV=test bundle exec rake db:migrate
10
+ - bundle exec rspec
data/Gemfile CHANGED
@@ -2,3 +2,8 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in detour.gemspec
4
4
  gemspec
5
+
6
+ gem "jquery-rails"
7
+ gem "indefinite_article", ">= 0.2.0"
8
+
9
+ gem "fakefs", require: false
data/README.md CHANGED
@@ -16,24 +16,12 @@ Rollouts for `ActiveRecord` models. It is a spiritual fork of [ArRollout](https:
16
16
 
17
17
  - [Installation](#installation)
18
18
  - [Usage](#usage)
19
+ - [Configuration](#configuration)
19
20
  - [Marking a model as flaggable](#marking-a-model-as-flaggable)
20
21
  - [Determining if a record is flagged into a feature](#determining-if-a-record-is-flagged-into-a-feature)
21
- - [Feature operations](#feature-operations)
22
- - [Creating features](#creating-features)
23
- - [Destroying features](#destroying-features)
24
- - [Flagging a record into a feature](#flagging-a-record-into-a-feature)
25
- - [Removing a flag-in for a record for a feature](#removing-a-flag-in-for-a-record-for-a-feature)
26
- - [Opt a record out of a feature](#opt-a-record-out-of-a-feature)
27
- - [Un-opt out a record from a feature](#un-opt-out-a-record-from-a-feature)
28
- - [Flag a programmatic group into a feature](#flag-a-programmatic-group-into-a-feature)
29
- - [Remove a flag-in for a programmatic group for a feature](#remove-a-flag-in-for-a-programmatic-group-for-a-feature)
30
- - [Flag a percentage of records into a feature](#flag-a-percentage-of-records-into-a-feature)
31
- - [Remove a flag-in for a percentage of records for a feature](#remove-a-flag-in-for-a-percentage-of-records-for-a-feature)
32
- - [Defining a default class](#defining-a-default-class)
33
22
  - [Defining programmatic groups](#defining-programmatic-groups)
34
23
  - [Contributing](#contributing)
35
24
 
36
-
37
25
  ## Installation
38
26
 
39
27
  Add this line to your application's Gemfile:
@@ -44,9 +32,13 @@ And then execute:
44
32
 
45
33
  $ bundle
46
34
 
47
- Or install it yourself as:
35
+ In your rails app:
36
+
37
+ $ bundle exec rails generate detour
38
+
39
+ Run the Detour migrations:
48
40
 
49
- $ gem install detour
41
+ $ bundle exec rake db:migrate
50
42
 
51
43
  ## Usage
52
44
 
@@ -54,8 +46,42 @@ Or install it yourself as:
54
46
  should have features accessible to it based on individual flags, flags for a
55
47
  percentage of records, or flags for a programmable group of records.
56
48
 
49
+ ### Configuration
50
+
51
+ Edit `config/initializers/detour.rb`:
52
+
53
+ ```ruby
54
+ Detour.configure do |config|
55
+ # Detour needs to know at boot which models will
56
+ # have flags defined for them:
57
+ config.flaggable_types = %w[User Widget]
58
+
59
+ # Detour needs to know what directories to search
60
+ # through in order to find places where you're
61
+ # checking for flags in your code. Provide it an
62
+ # array of glob strings:
63
+ config.grep_dirs = %w[app/**/*.{rb,erb}]
64
+
65
+ # Provide a default class to manage rollouts for, if
66
+ # desired. This means you can omit the class name from
67
+ # rake tasks:
68
+ config.default_flaggable_class_name = "User"
69
+ end
70
+ ```
71
+
72
+ Mount the app in `config/routes.rb`:
73
+
74
+ ```ruby
75
+ Rails.application.routes.draw do
76
+ mount Detour::Engine => "/detour"
77
+ end
78
+ ```
79
+
57
80
  ### Marking a model as flaggable
58
81
 
82
+ In addition to listing classes that are flaggable in your initializer, add
83
+ `acts_as_flaggable` to the class definitions themselves:
84
+
59
85
  ```ruby
60
86
  class User < ActiveRecord::Base
61
87
  acts_as_flaggable
@@ -113,123 +139,6 @@ end; else
113
139
  end
114
140
  ```
115
141
 
116
- ### Feature operations
117
-
118
- Features and flags are intended to be controlled by a rake tasks. To create
119
- them programmatically, consult the documentation.
120
-
121
- #### Creating features
122
-
123
- ```sh
124
- $ bundle exec rake detour:create[new_ui]
125
- ```
126
-
127
- #### Destroying features
128
-
129
- ```sh
130
- $ bundle exec rake detour:destroy[new_ui]
131
- ```
132
-
133
- #### Flagging a record into a feature
134
-
135
- This task requires passing the feature name, the record's class, and the
136
- record's ID.
137
-
138
- ```sh
139
- $ bundle exec rake detour:activate[new_ui,User,2]
140
- ```
141
-
142
- #### Removing a flag-in for a record for a feature
143
-
144
- This task requires passing the feature name, the record's class, and the
145
- record's ID.
146
-
147
- ```sh
148
- $ bundle exec rake detour:deactivate[new_ui,User,2]
149
- ```
150
-
151
- #### Opt a record out of a feature
152
-
153
- This will ensure that `record.has_feature?(:feature)` will always be false for
154
- the given feature, regardless of other individual flag, percentage, or group
155
- rollouts that would otherwise target this record.
156
-
157
- This task requires passing the feature name, the record's class, and the
158
- record's ID.
159
-
160
- ```sh
161
- $ bundle exec rake detour:opt_out[new_ui,User,2]
162
- ```
163
-
164
- #### Un-opt out a record from a feature
165
-
166
- This task requires passing the feature name, the record's class, and the
167
- record's ID.
168
-
169
- ```sh
170
- $ bundle exec rake detour:un_opt_out[new_ui,User,2]
171
- ```
172
-
173
- #### Flag a programmatic group into a feature
174
-
175
- This task requires passing the feature name, the record class for the group,
176
- and the name of the group.
177
-
178
- ```sh
179
- $ bundle exec rake detour:activate_group[new_ui,User,admins]
180
- ```
181
-
182
- #### Remove a flag-in for a programmatic group for a feature
183
-
184
- This task requires passing the feature name, the record class for the group,
185
- and the name of the group.
186
-
187
- ```sh
188
- $ bundle exec rake detour:deactivate_group[new_ui,User,admins]
189
- ```
190
-
191
- #### Flag a percentage of records into a feature
192
-
193
- This relies on the following formula to determine if a record is flagged in to
194
- a feature based on percentage:
195
-
196
- ```ruby
197
- record.id % 10 < percentage / 10
198
- ```
199
-
200
- This task requires passing the feature name, the record class for the group,
201
- and the percentage of records to be flagged in.
202
-
203
- ```sh
204
- $ bundle exec rake detour:activate_percentage[new_ui,User,20]
205
- ```
206
-
207
- #### Remove a flag-in for a percentage of records for a feature
208
-
209
- This task requires passing the feature name, and the record class for the group.
210
-
211
- ```sh
212
- $ bundle exec rake detour:deactivate_percentage[new_ui,User]
213
- ```
214
-
215
- ### Defining a default class
216
-
217
- In order to provide passing a class name into rake tasks, a default class can
218
- be set:
219
-
220
- ```ruby
221
- Detour.configure do |config|
222
- config.default_flaggable_class_name = "User"
223
- end
224
- ```
225
-
226
- Then, in your rake tasks:
227
-
228
- ```sh
229
- # Will activate feature "foo" for all instances of User that match the admins group.
230
- $ bundle exec rake detour:activate_group[foo,admins]
231
- ```
232
-
233
142
  ### Defining programmatic groups
234
143
 
235
144
  A specific group of records matching a given block can be flagged into a
data/Rake.md ADDED
@@ -0,0 +1,108 @@
1
+ # Detour Rake Tasks
2
+
3
+ ## Contents
4
+
5
+ - [Creating features](#creating-features)
6
+ - [Destroying features](#destroying-features)
7
+ - [Flagging a record into a feature](#flagging-a-record-into-a-feature)
8
+ - [Removing a flag-in for a record for a feature](#removing-a-flag-in-for-a-record-for-a-feature)
9
+ - [Opt a record out of a feature](#opt-a-record-out-of-a-feature)
10
+ - [Un-opt out a record from a feature](#un-opt-out-a-record-from-a-feature)
11
+ - [Flag a programmatic group into a feature](#flag-a-programmatic-group-into-a-feature)
12
+ - [Remove a flag-in for a programmatic group for a feature](#remove-a-flag-in-for-a-programmatic-group-for-a-feature)
13
+ - [Flag a percentage of records into a feature](#flag-a-percentage-of-records-into-a-feature)
14
+ - [Remove a flag-in for a percentage of records for a feature](#remove-a-flag-in-for-a-percentage-of-records-for-a-feature)
15
+
16
+ ## Creating features
17
+
18
+ ```sh
19
+ $ bundle exec rake detour:create[new_ui]
20
+ ```
21
+
22
+ ## Destroying features
23
+
24
+ ```sh
25
+ $ bundle exec rake detour:destroy[new_ui]
26
+ ```
27
+
28
+ ## Flagging a record into a feature
29
+
30
+ This task requires passing the feature name, the record's class, and the
31
+ record's ID.
32
+
33
+ ```sh
34
+ $ bundle exec rake detour:activate[new_ui,User,2]
35
+ ```
36
+
37
+ ## Removing a flag-in for a record for a feature
38
+
39
+ This task requires passing the feature name, the record's class, and the
40
+ record's ID.
41
+
42
+ ```sh
43
+ $ bundle exec rake detour:deactivate[new_ui,User,2]
44
+ ```
45
+
46
+ ## Opt a record out of a feature
47
+
48
+ This will ensure that `record.has_feature?(:feature)` will always be false for
49
+ the given feature, regardless of other individual flag, percentage, or group
50
+ rollouts that would otherwise target this record.
51
+
52
+ This task requires passing the feature name, the record's class, and the
53
+ record's ID.
54
+
55
+ ```sh
56
+ $ bundle exec rake detour:opt_out[new_ui,User,2]
57
+ ```
58
+
59
+ ## Un-opt out a record from a feature
60
+
61
+ This task requires passing the feature name, the record's class, and the
62
+ record's ID.
63
+
64
+ ```sh
65
+ $ bundle exec rake detour:un_opt_out[new_ui,User,2]
66
+ ```
67
+
68
+ ## Flag a programmatic group into a feature
69
+
70
+ This task requires passing the feature name, the record class for the group,
71
+ and the name of the group.
72
+
73
+ ```sh
74
+ $ bundle exec rake detour:activate_group[new_ui,User,admins]
75
+ ```
76
+
77
+ ## Remove a flag-in for a programmatic group for a feature
78
+
79
+ This task requires passing the feature name, the record class for the group,
80
+ and the name of the group.
81
+
82
+ ```sh
83
+ $ bundle exec rake detour:deactivate_group[new_ui,User,admins]
84
+ ```
85
+
86
+ ## Flag a percentage of records into a feature
87
+
88
+ This relies on the following formula to determine if a record is flagged in to
89
+ a feature based on percentage:
90
+
91
+ ```ruby
92
+ record.id % 10 < percentage / 10
93
+ ```
94
+
95
+ This task requires passing the feature name, the record class for the group,
96
+ and the percentage of records to be flagged in.
97
+
98
+ ```sh
99
+ $ bundle exec rake detour:activate_percentage[new_ui,User,20]
100
+ ```
101
+
102
+ ## Remove a flag-in for a percentage of records for a feature
103
+
104
+ This task requires passing the feature name, and the record class for the group.
105
+
106
+ ```sh
107
+ $ bundle exec rake detour:deactivate_percentage[new_ui,User]
108
+ ```
data/Rakefile CHANGED
@@ -1 +1,21 @@
1
- require "bundler/gem_tasks"
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require "bundler/setup"
4
+ rescue LoadError
5
+ puts "You must `gem install bundler` and `bundle install` to run rake tasks"
6
+ end
7
+
8
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
9
+ load "rails/tasks/engine.rake"
10
+
11
+ Bundler::GemHelper.install_tasks
12
+
13
+ Dir[File.join(File.dirname(__FILE__), "tasks/**/*.rake")].each {|f| load f }
14
+
15
+ require "rspec/core"
16
+ require "rspec/core/rake_task"
17
+
18
+ desc "Run all specs in spec directory (excluding plugin specs)"
19
+ RSpec::Core::RakeTask.new(:spec => "app:db:test:prepare")
20
+
21
+ task :default => :spec