├── .gitignore
├── .travis.yml
├── Gemfile
├── LICENSE
├── README.md
├── Rakefile
├── app
└── controllers
│ └── chili
│ └── application_controller.rb
├── chili.gemspec
├── lib
├── chili.rb
├── chili
│ ├── activatable.rb
│ ├── base.rb
│ ├── bundler.rb
│ ├── engine.rb
│ ├── engine_extensions.rb
│ ├── feature.rb
│ ├── overrides.rb
│ └── version.rb
├── generators
│ └── chili
│ │ ├── feature
│ │ ├── USAGE
│ │ └── feature_generator.rb
│ │ └── generator_proxy.rb
└── tasks
│ └── chili.rake
└── spec
├── README.md
├── chili
└── activatable_spec.rb
├── dummy
├── app
│ ├── app
│ │ └── controllers
│ │ │ └── application_controller.rb
│ ├── config
│ │ ├── application.rb
│ │ ├── boot.rb
│ │ ├── database.yml
│ │ ├── environment.rb
│ │ └── environments
│ │ │ └── test.rb
│ └── script
│ │ └── rails
└── blank_feature
│ ├── README.rdoc
│ ├── app
│ ├── assets
│ │ ├── images
│ │ │ └── blank_feature
│ │ │ │ └── .gitkeep
│ │ ├── javascripts
│ │ │ └── blank_feature
│ │ │ │ └── application.js
│ │ └── stylesheets
│ │ │ └── blank_feature
│ │ │ └── application.css
│ ├── controllers
│ │ └── blank_feature
│ │ │ └── application_controller.rb
│ └── overrides
│ │ └── layouts
│ │ └── application
│ │ ├── assets.html.erb.deface
│ │ └── example.html.erb.deface
│ ├── blank_feature.gemspec
│ ├── config
│ └── routes.rb
│ └── lib
│ ├── blank_feature.rb
│ ├── blank_feature
│ ├── engine.rb
│ └── version.rb
│ ├── generators
│ └── blank_feature_generator.rb
│ └── tasks
│ └── blank_feature_tasks.rake
├── example_app
├── README.rdoc
├── Rakefile
├── app
│ ├── assets
│ │ ├── javascripts
│ │ │ └── application.js
│ │ └── stylesheets
│ │ │ ├── application.css
│ │ │ ├── posts.css
│ │ │ ├── scaffold.css
│ │ │ └── users.css
│ ├── controllers
│ │ ├── application_controller.rb
│ │ ├── posts_controller.rb
│ │ ├── sessions_controller.rb
│ │ └── users_controller.rb
│ ├── helpers
│ │ ├── application_helper.rb
│ │ ├── posts_helper.rb
│ │ └── users_helper.rb
│ ├── mailers
│ │ └── .gitkeep
│ ├── models
│ │ ├── .gitkeep
│ │ ├── post.rb
│ │ └── user.rb
│ ├── overrides
│ │ └── posts
│ │ │ └── index
│ │ │ └── spree.html.erb.deface
│ └── views
│ │ ├── layouts
│ │ └── application.html.erb
│ │ ├── posts
│ │ ├── _form.html.erb
│ │ ├── _post.html.erb
│ │ ├── edit.html.erb
│ │ ├── index.html.erb
│ │ ├── new.html.erb
│ │ └── show.html.erb
│ │ ├── sessions
│ │ └── new.html.erb
│ │ └── users
│ │ ├── _form.html.erb
│ │ ├── edit.html.erb
│ │ ├── index.html.erb
│ │ ├── new.html.erb
│ │ └── show.html.erb
├── config.ru
├── config
│ ├── application.rb
│ ├── boot.rb
│ ├── database.yml
│ ├── environment.rb
│ ├── environments
│ │ ├── development.rb
│ │ ├── production.rb
│ │ └── test.rb
│ ├── initializers
│ │ ├── backtrace_silencers.rb
│ │ ├── filter_parameter_logging.rb
│ │ ├── inflections.rb
│ │ ├── mime_types.rb
│ │ ├── secret_token.rb
│ │ ├── session_store.rb
│ │ └── wrap_parameters.rb
│ ├── locales
│ │ └── en.yml
│ └── routes.rb
├── db
│ ├── migrate
│ │ ├── 20120513023816_create_posts.rb
│ │ ├── 20120513023840_create_users.rb
│ │ └── 20120513032032_create_social_feature_likes.rb
│ └── schema.rb
├── lib
│ ├── assets
│ │ └── .gitkeep
│ └── chili
│ │ ├── invites_feature
│ │ ├── .gitignore
│ │ ├── app
│ │ │ ├── assets
│ │ │ │ ├── images
│ │ │ │ │ └── invites_feature
│ │ │ │ │ │ └── .gitkeep
│ │ │ │ ├── javascripts
│ │ │ │ │ └── invites_feature
│ │ │ │ │ │ └── application.js
│ │ │ │ └── stylesheets
│ │ │ │ │ └── invites_feature
│ │ │ │ │ └── application.css
│ │ │ ├── controllers
│ │ │ │ └── invites_feature
│ │ │ │ │ └── application_controller.rb
│ │ │ └── overrides
│ │ │ │ └── posts
│ │ │ │ └── index
│ │ │ │ └── disclaimer.html.erb.deface
│ │ ├── config
│ │ │ └── routes.rb
│ │ └── lib
│ │ │ ├── generators
│ │ │ └── invites_feature_generator.rb
│ │ │ ├── invites_feature.rb
│ │ │ └── invites_feature
│ │ │ └── engine.rb
│ │ └── social_feature
│ │ ├── app
│ │ ├── assets
│ │ │ ├── images
│ │ │ │ └── social_feature
│ │ │ │ │ └── .gitkeep
│ │ │ ├── javascripts
│ │ │ │ └── social_feature
│ │ │ │ │ └── application.js
│ │ │ └── stylesheets
│ │ │ │ └── social_feature
│ │ │ │ └── application.css.scss
│ │ ├── controllers
│ │ │ └── social_feature
│ │ │ │ ├── application_controller.rb
│ │ │ │ └── likes_controller.rb
│ │ ├── models
│ │ │ └── social_feature
│ │ │ │ ├── like.rb
│ │ │ │ ├── post.rb
│ │ │ │ └── user.rb
│ │ ├── overrides
│ │ │ ├── layouts
│ │ │ │ └── application
│ │ │ │ │ └── likes_link.html.erb.deface
│ │ │ └── posts
│ │ │ │ ├── _post
│ │ │ │ └── like_actions.html.erb.deface
│ │ │ │ └── index
│ │ │ │ ├── disclaimer.html.erb.deface
│ │ │ │ └── table_headers.html.erb.deface
│ │ └── views
│ │ │ └── social_feature
│ │ │ └── likes
│ │ │ └── index.html.erb
│ │ ├── config
│ │ └── routes.rb
│ │ ├── db
│ │ └── migrate
│ │ │ └── 20120513031021_create_social_feature_likes.rb
│ │ └── lib
│ │ ├── generators
│ │ └── social_feature_generator.rb
│ │ ├── social_feature.rb
│ │ └── social_feature
│ │ └── engine.rb
├── log
│ └── .gitkeep
├── public
│ ├── 404.html
│ ├── 422.html
│ ├── 500.html
│ └── favicon.ico
├── script
│ └── rails
└── spec
│ └── support
│ └── user_macros.rb
├── features
└── social_feature_spec.rb
├── generators
└── chili
│ ├── feature_generator_spec.rb
│ └── generator_proxy_spec.rb
├── spec_helper.rb
└── support
└── dummy_app.rb
/.gitignore:
--------------------------------------------------------------------------------
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 | spec/example_app/db/*.sqlite3
16 | spec/example_app/log/*.log
17 | spec/example_app/tmp/
18 | spec/example_app/.sass-cache
19 | spec/dummy/app/Gemfile
20 | spec/dummy/app/log/
21 | spec/dummy/app/lib/
22 | tmp
23 | .DS_Store
24 | .pt
25 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: ruby
2 | script: "rake app:db:setup && rake app:db:test:prepare && rake"
3 | rvm:
4 | - 1.9.3
5 | - 2.0.0
6 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source 'https://rubygems.org'
2 |
3 | # Specify your gem's dependencies in chili.gemspec
4 | gemspec
5 | gem 'rake'
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (c) 2012 Jens Balvig
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.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # 🌶️ Chili
2 |
3 | Have you ever wanted to test out a new feature on only a subset of users?
4 | Did that implementation end up being lots of if/else statements embedded in the main code?
5 | If so, Chili can help.
6 |
7 | Chili is built on top of Rails Engines and Deface and allows you to conditionally add new/modify existing views,
8 | while leaving the main code untouched.
9 |
10 | ## Tutorial & Examples
11 |
12 | - [Walkthrough of creating and releasing a new feature with Chili](https://balvig.github.io/chili/)
13 |
14 | ## Requirements
15 |
16 | - Rails 4.1+
17 | - Ruby 1.9.2+
18 |
19 | ## Installation
20 |
21 | First add Chili to your app's Gemfile:
22 |
23 | ```ruby
24 | gem 'chili'
25 | ```
26 |
27 | and run `bundle`.
28 |
29 | ## Usage
30 |
31 | Chili features are like mini apps that are created inside your main app's lib/chili directory using using the "chili" generator.
32 |
33 | ### Creating a new chili feature
34 |
35 | As an example, assuming you want to add a beta feature named "social" that shows a new like-button
36 | to a subset of users, first within your main app run:
37 |
38 | ```bash
39 | $ rails g chili:feature social
40 | ```
41 |
42 | This will:
43 |
44 | 1. Create the directory `lib/chili/social_feature` containing the basic structure for the feature
45 | 2. Add a reference to the feature to the main app gemfile
46 |
47 | Since the feature is mounted as a gem you'll have to restart the app.
48 |
49 | ### Define who can see the feature
50 |
51 | Use the active_if block to control whether new the feature is active for each user.
52 | The context of the active_if block is the application controller so you can use any methods available to that.
53 |
54 | ```ruby
55 | # {feature}/lib/social_feature.rb
56 | module SocialFeature
57 | extend Chili::Base
58 | active_if { logged_in? && current_user.admin? } # Feature is only visible to logged in admin users
59 | end
60 | ```
61 |
62 | ### Modifying view templates in main app
63 |
64 | Chili uses Deface to dynamically modify existing view templates (see [Deface docs](https://github.com/spree/deface#using-the-deface-dsl-deface-files) for details)
65 | To generate an override to the feature, run the deface generator specifying the name of the feature and path to the template you want to modify.
66 | For example, assuming the main app has the partial `app/views/posts/_post.html.erb` run:
67 |
68 | ```bash
69 | $ rails g social_feature deface:override posts/_post like_button
70 | ```
71 |
72 | This will create a dummy override at `{feature}/app/overrides/posts/_post/like_button.html.erb.deface` that you can edit:
73 |
74 | ```erb
75 | <% # {feature}/app/overrides/posts/_post/like_button.html.erb.deface %>
76 |
77 |
<%= link_to 'Like!', social_feature.likes_path(like: {post_id: post}), method: :post %> |
78 | ```
79 |
80 | ### Adding new resources
81 |
82 | You can run the usual Rails generators for each feature by prepending
83 | the generator with the name of the feature:
84 |
85 | ```bash
86 | $ rails g social_feature scaffold Like
87 | ```
88 |
89 | The new resource will be namespaced to `SocialFeature::Like` and automounted as an [isolated engine](http://railscasts.com/episodes/277-mountable-engines?view=asciicast) in the main app at `/chili/social_feature/likes`,
90 | but will only be accessible when active_if is true.
91 |
92 | ### Migrations
93 |
94 | To copy and run feature db migrations use the following command:
95 |
96 | ```bash
97 | $ rake social_feature:db:migrate
98 | ```
99 |
100 | ### Modifying existing models
101 |
102 | Create a model with the same name as the one you want to modify by running: `rails g social_feature model User --migration=false` and edit it to inherit from the original:
103 |
104 | ```ruby
105 | # {feature}/app/models/social_feature/user.rb
106 | module SocialFeature
107 | class User < ::User
108 | has_many :likes
109 | end
110 | end
111 | ```
112 |
113 | Access in your overrides/feature views through the namespaced model:
114 |
115 | ```erb
116 | <%= SocialFeature::User.first.likes %>
117 | <%= current_user.becomes(SocialFeature::User).likes %>
118 | ```
119 |
120 | ### Stylesheets/javascripts
121 |
122 | Files added to the feature's `app/assets/social_feature/javascripts|stylesheets` directory are automatically injected into the layout using a pre-generated override:
123 |
124 | ```erb
125 | <% # {feature}/app/overrides/layouts/application/assets.html.erb.deface %>
126 |
127 | <%= stylesheet_link_tag 'social_feature/application' %>
128 | <%= javascript_include_tag 'social_feature/application' %>
129 | ```
130 |
131 | If you don't need any css/js in your feature, you can remove this file.
132 |
133 | ## Gotchas
134 |
135 | - Chili will not be able to automount if you use a catch-all route in your main app (ie `match '*a', to: 'errors#routing'`), you will have to remove the catch-all or manually add the engine to the main app's routes file.
136 | - Just like normal engines, Chili requires you to prepend path helpers with `main_app` (ie `main_app.root_path` etc) in view templates that are shared with the main app (such as the main app's application layout file).
137 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env rake
2 |
3 | begin
4 | require 'bundler/setup'
5 | rescue LoadError
6 | puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
7 | end
8 |
9 | APP_RAKEFILE = File.expand_path("../spec/example_app/Rakefile", __FILE__)
10 | load 'rails/tasks/engine.rake'
11 |
12 | require 'rspec/core/rake_task'
13 |
14 | RSpec::Core::RakeTask.new(:spec)
15 | task :default => :spec
16 |
17 | Bundler::GemHelper.install_tasks
18 |
--------------------------------------------------------------------------------
/app/controllers/chili/application_controller.rb:
--------------------------------------------------------------------------------
1 | module Chili
2 | class ApplicationController < ::ApplicationController
3 | before_filter :activate_feature
4 |
5 | private
6 |
7 | def activate_feature
8 | raise ActionController::RoutingError, 'Feature Disabled' unless self.class.parent.active?(self)
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/chili.gemspec:
--------------------------------------------------------------------------------
1 | # -*- encoding: utf-8 -*-
2 | require File.expand_path('../lib/chili/version', __FILE__)
3 |
4 | Gem::Specification.new do |gem|
5 | gem.authors = ["Jens Balvig"]
6 | gem.email = ["jens@balvig.com"]
7 | gem.description = %q{The spicy feature toggle framework}
8 | gem.summary = %q{The spicy feature toggle framework}
9 | gem.homepage = "http://balvig.github.com/chili/"
10 |
11 | gem.files = `git ls-files`.split($\)
12 | gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
13 | gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
14 | gem.name = "chili"
15 | gem.require_paths = ["lib"]
16 | gem.version = Chili::VERSION
17 |
18 | gem.add_dependency "rails", ">= 4.1"
19 | gem.add_dependency "deface", "~> 1.0.0"
20 |
21 | gem.add_development_dependency 'rspec', '~> 2.14.0'
22 | gem.add_development_dependency 'rspec-rails', '~> 2.14.0'
23 | gem.add_development_dependency 'jquery-rails'
24 | gem.add_development_dependency 'capybara', '~> 2.0'
25 | gem.add_development_dependency 'xpath'
26 | gem.add_development_dependency 'sqlite3'
27 | gem.add_development_dependency 'pry'
28 | end
29 |
--------------------------------------------------------------------------------
/lib/chili.rb:
--------------------------------------------------------------------------------
1 | require "deface"
2 | require "chili/base"
3 | require "chili/bundler"
4 | require "chili/engine"
5 | require "chili/feature"
6 | require "chili/overrides"
7 | require "chili/version"
8 | require "generators/chili/generator_proxy"
9 |
10 | module Chili
11 | FEATURE_FOLDER = 'lib/chili'
12 | end
13 |
--------------------------------------------------------------------------------
/lib/chili/activatable.rb:
--------------------------------------------------------------------------------
1 | module Chili
2 | module Activatable
3 | def self.extended(base)
4 | base.send(:unloadable) if base.respond_to?(:unloadable)
5 | end
6 |
7 | def active_if(&block)
8 | @active_if = block
9 | end
10 |
11 | def active?(controller)
12 | controller.instance_eval(&@active_if)
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/lib/chili/base.rb:
--------------------------------------------------------------------------------
1 | require "chili/activatable"
2 | require "chili/engine_extensions"
3 |
4 | module Chili
5 | module Base
6 | def self.extended(base)
7 | base.extend(Activatable)
8 | base::Engine.extend(EngineExtensions)
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/lib/chili/bundler.rb:
--------------------------------------------------------------------------------
1 | Bundler.require(:chili)
2 |
--------------------------------------------------------------------------------
/lib/chili/engine.rb:
--------------------------------------------------------------------------------
1 | module Chili
2 | class Engine < ::Rails::Engine
3 |
4 | initializer "chili.add_autoload_paths", before: :set_autoload_paths do |app|
5 | app.config.autoload_paths += Dir["#{app.config.root}/#{FEATURE_FOLDER}/*/lib"]
6 | end
7 |
8 | initializer 'chili.deface' do |app|
9 | app.config.deface.namespaced = true
10 | end
11 |
12 | initializer 'chili.controller' do |app|
13 | ActiveSupport.on_load(:action_controller) do
14 | include Chili::Overrides
15 | end
16 | end
17 | end
18 | end
19 |
--------------------------------------------------------------------------------
/lib/chili/engine_extensions.rb:
--------------------------------------------------------------------------------
1 | module Chili
2 | module EngineExtensions
3 | def self.extended(base)
4 | base.rake_tasks do
5 | next if self.is_a?(Rails::Application)
6 | next unless has_migrations?
7 |
8 | namespace railtie_name do
9 | namespace :db do
10 | desc "Copy and migrate migrations from #{railtie_name}"
11 | task :migrate do
12 | Rake::Task["#{railtie_name}:install:migrations"].invoke
13 | Rake::Task["db:migrate"].invoke
14 | end
15 | end
16 | end
17 | end
18 | end
19 |
20 | def automount!(path = nil)
21 | engine = self
22 | path ||= 'chili/' + engine.parent.to_s.underscore
23 | Rails.application.routes.draw do
24 | mount engine => path
25 | end
26 | end
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/lib/chili/feature.rb:
--------------------------------------------------------------------------------
1 | module Chili
2 | class Feature
3 | def initialize(short_name)
4 | @short_name = short_name
5 | end
6 |
7 | def name
8 | @short_name.to_s.underscore.gsub('_feature','') + '_feature'
9 | end
10 |
11 | def path
12 | "#{FEATURE_FOLDER}/#{name}"
13 | end
14 | end
15 | end
16 |
--------------------------------------------------------------------------------
/lib/chili/overrides.rb:
--------------------------------------------------------------------------------
1 | module Chili
2 | module Overrides
3 | def self.included(base)
4 | base.send(:include, InstanceMethods)
5 | base.before_filter :activate_overrides
6 | end
7 |
8 | module InstanceMethods
9 | def activate_overrides
10 | Deface::Override.all.values.map(&:values).flatten.each do |override|
11 | engine = override.railtie_class.constantize.parent
12 | override.args[:disabled] = !engine.active?(self) if engine.respond_to?(:active?)
13 | end
14 | end
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/lib/chili/version.rb:
--------------------------------------------------------------------------------
1 | module Chili
2 | VERSION = "4.0.1"
3 | end
4 |
--------------------------------------------------------------------------------
/lib/generators/chili/feature/USAGE:
--------------------------------------------------------------------------------
1 | Description:
2 | Generate a new chili feature
3 |
4 | Example:
5 | rails generate chili:feature social
6 |
7 | This will create:
8 | basic chili feature structure in vendor/chili/social_feature
9 |
--------------------------------------------------------------------------------
/lib/generators/chili/feature/feature_generator.rb:
--------------------------------------------------------------------------------
1 | module Chili
2 | module Generators
3 | class FeatureGenerator < Rails::Generators::NamedBase
4 |
5 | def run_plugin_generator
6 | ARGV[0] = feature.path
7 | ARGV[1] = '--mountable'
8 | ARGV[2] = '--skip-test-unit'
9 | ARGV[3] = '--skip-bundle'
10 |
11 | require 'rails/generators'
12 | require 'rails/generators/rails/plugin/plugin_generator'
13 | Rails::Generators::PluginGenerator.start
14 | end
15 |
16 | def reset_destination_root
17 | self.destination_root = ''
18 | end
19 |
20 | def edit_gemspec
21 | require File.expand_path('../../../../chili/version', __FILE__)
22 | gemspec = "#{feature.name}.gemspec"
23 | gsub_file gemspec, 'TODO: Your name', `git config user.NAME`.chomp
24 | gsub_file gemspec, 'TODO: Your email', `git config user.email`.chomp
25 | gsub_file gemspec, /TODO(:\s)?/, ''
26 | inject_into_file gemspec, " s.add_dependency 'chili', '~> #{Chili::VERSION.sub(/\.\d+$/,'')}'\n\n", before: ' s.add_development_dependency "sqlite3"'
27 | end
28 |
29 | def add_gem_to_main_gemfile
30 | gemfile = "../../../Gemfile"
31 | group = "group :chili do\n"
32 | append_to_file gemfile, group
33 | append_to_file gemfile, " gem '#{feature.name}', path: '#{feature.path}'\nend", after: group
34 | gsub_file gemfile, 'end gem', ' gem' #nasty cleanup
35 | end
36 |
37 | def remove_unused_files
38 | remove_dir "app/helpers/#{feature.name}"
39 | remove_dir 'app/views/layouts'
40 | remove_dir 'script'
41 | remove_file 'Gemfile'
42 | remove_file 'Rakefile'
43 | remove_file 'MIT-LICENSE'
44 | end
45 |
46 | def remove_jquery_stuff
47 | gsub_file "app/assets/javascripts/#{feature.name}/application.js", "//= require jquery_ujs\n", ''
48 | gsub_file "app/assets/javascripts/#{feature.name}/application.js", "//= require jquery\n", ''
49 | end
50 |
51 | def chilify_application_controller
52 | gsub_file "app/controllers/#{feature.name}/application_controller.rb", "ActionController::Base", 'Chili::ApplicationController'
53 | end
54 |
55 | def clean_up_gitignore
56 | gsub_file ".gitignore", /test\/dummy.*\n/, ''
57 | end
58 |
59 | def automount_engine
60 | prepend_to_file 'config/routes.rb', "#{feature.name.camelcase}::Engine.automount!\n"
61 | end
62 |
63 | def include_chili_libs
64 | prepend_to_file "lib/#{feature.name}.rb", "require \"chili\"\n"
65 | end
66 |
67 | def include_base_and_active_if
68 | inject_into_file "lib/#{feature.name}.rb", after: "module #{feature.name.camelcase}\n" do <<-RUBY
69 | extend Chili::Base
70 | active_if { true } # edit this to activate/deactivate feature at runtime
71 | RUBY
72 | end
73 | end
74 |
75 | def add_dummy_override
76 | example_file_path = "app/overrides/layouts/application/example.html.erb.deface"
77 | create_file example_file_path do <<-RUBY
78 |
79 |
80 | #{feature.name} active - edit/remove this file:
81 | #{feature.path}/#{example_file_path}
82 | <%= link_to 'deface docs', 'https://github.com/spree/deface', target: '_blank' %>
83 |
84 | RUBY
85 | end
86 | end
87 |
88 | def add_assets_override
89 | create_file 'app/overrides/layouts/application/assets.html.erb.deface' do <<-RUBY
90 |
91 | <%= stylesheet_link_tag '#{feature.name}/application' %>
92 | <%= javascript_include_tag '#{feature.name}/application' %>
93 | RUBY
94 | end
95 | end
96 |
97 | def add_generator_proxy
98 | create_file "lib/generators/#{feature.name}_generator.rb" do <<-RUBY
99 | class #{feature.name.camelcase}Generator < Rails::Generators::Base
100 | include Chili::GeneratorProxy
101 | end
102 | RUBY
103 | end
104 | end
105 |
106 | protected
107 |
108 | def feature
109 | @feature ||= Chili::Feature.new(ARGV[0])
110 | end
111 | end
112 | end
113 | end
114 |
--------------------------------------------------------------------------------
/lib/generators/chili/generator_proxy.rb:
--------------------------------------------------------------------------------
1 | module Chili
2 | module GeneratorProxy
3 | def self.included(base)
4 | base.class_eval do
5 | argument :generator, type: :string
6 | argument :generator_options, type: :array, default: [], banner: "GENERATOR_OPTIONS"
7 |
8 | def self.desc
9 | "Generates resources (scaffold, model, migration etc) for #{generator_name}"
10 | end
11 |
12 | def delegate
13 | engine = self.class.generator_name.classify.constantize
14 | Rails::Generators.namespace = engine
15 | Rails::Generators.invoke ARGV.shift, ARGV, destination_root: Feature.new(engine).path, behavior: behavior
16 | end
17 | end
18 | end
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/lib/tasks/chili.rake:
--------------------------------------------------------------------------------
1 | { spec: 'RSpec::Core::RakeTask', test: 'Rake::TestTask' }.each do |test_lib, rake_task|
2 | if Rake::Task.task_defined?(test_lib)
3 |
4 | Rake::Task[test_lib].clear
5 | chili_specs = "#{Chili::FEATURE_FOLDER}/**/#{test_lib}/**/*_#{test_lib}.rb"
6 |
7 | task = rake_task.constantize.new(test_lib => 'test:prepare')
8 | task.pattern = [task.pattern, chili_specs]
9 |
10 | namespace test_lib do
11 | desc "Run tests for all Chili features"
12 | rake_task.constantize.new(:chili) do |t|
13 | t.pattern = chili_specs
14 | end
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/spec/README.md:
--------------------------------------------------------------------------------
1 | # Running tests
2 |
3 | ```bash
4 | $ rake app:db:setup
5 | $ rake app:db:test:prepare
6 | $ rake
7 | ```
8 |
9 | ## Folders
10 |
11 | ```bash
12 | spec/dummy/app # dummy app for generating chili features inside
13 | spec/dummy/blank_feature # blank feature template used to compare output of generators
14 | spec/example_app # rails app containing 2 chili features for integration testing
15 | spec/generators # generator tests
16 | spec/chili # chili unit tests
17 | spec/requests # integration tests
18 | ```
19 |
--------------------------------------------------------------------------------
/spec/chili/activatable_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | module Engine
4 | extend Chili::Activatable
5 | end
6 |
7 | class DummyController
8 | def logged_in? ; true end
9 | def admin? ; false end
10 | end
11 |
12 | describe Chili::Activatable do
13 | describe '#active_if & #active?' do
14 | it "evaluates the active_if block within the context of the instance" do
15 | Engine.active_if { logged_in? }
16 | Engine.active?(DummyController.new).should be_true
17 | Engine.active_if { logged_in? && admin? }
18 | Engine.active?(DummyController.new).should be_false
19 | end
20 | end
21 | end
22 |
--------------------------------------------------------------------------------
/spec/dummy/app/app/controllers/application_controller.rb:
--------------------------------------------------------------------------------
1 | class ApplicationController < ActionController::Base
2 | protect_from_forgery
3 | end
4 |
--------------------------------------------------------------------------------
/spec/dummy/app/config/application.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path('../boot', __FILE__)
2 |
3 | require 'rails/all'
4 |
5 | # Require the gems listed in Gemfile, including any gems
6 | # you've limited to :test, :development, or :production.
7 | Bundler.require(:default, Rails.env)
8 | require "chili"
9 | Dir.glob(File.expand_path('../../lib/chili/*', __FILE__)).each do |dir|
10 | require File.basename(dir)
11 | end
12 |
13 | module Dummy
14 | class Application < Rails::Application
15 | # Settings in config/environments/* take precedence over those specified here.
16 | # Application configuration should go into files in config/initializers
17 | # -- all .rb files in that directory are automatically loaded.
18 |
19 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
20 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
21 | # config.time_zone = 'Central Time (US & Canada)'
22 |
23 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
24 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
25 | # config.i18n.default_locale = :de
26 | end
27 | end
28 |
--------------------------------------------------------------------------------
/spec/dummy/app/config/boot.rb:
--------------------------------------------------------------------------------
1 | # Set up gems listed in the Gemfile.
2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../../Gemfile', __FILE__)
3 |
4 | require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
5 | $:.unshift File.expand_path('../../../../../lib', __FILE__)
6 | $:.unshift File.expand_path('../../lib/chili/blank_feature/lib', __FILE__)
7 |
--------------------------------------------------------------------------------
/spec/dummy/app/config/database.yml:
--------------------------------------------------------------------------------
1 | # SQLite version 3.x
2 | # gem install sqlite3
3 | #
4 | # Ensure the SQLite 3 gem is defined in your Gemfile
5 | # gem 'sqlite3'
6 | development:
7 | adapter: sqlite3
8 | database: db/development.sqlite3
9 | pool: 5
10 | timeout: 5000
11 |
12 | # Warning: The database defined as "test" will be erased and
13 | # re-generated from your development database when you run "rake".
14 | # Do not set this db to the same as development or production.
15 | test:
16 | adapter: sqlite3
17 | database: db/test.sqlite3
18 | pool: 5
19 | timeout: 5000
20 |
21 | production:
22 | adapter: sqlite3
23 | database: db/production.sqlite3
24 | pool: 5
25 | timeout: 5000
26 |
--------------------------------------------------------------------------------
/spec/dummy/app/config/environment.rb:
--------------------------------------------------------------------------------
1 | # Load the Rails application.
2 | require File.expand_path('../application', __FILE__)
3 |
4 | # Initialize the Rails application.
5 | Dummy::Application.initialize!
6 |
--------------------------------------------------------------------------------
/spec/dummy/app/config/environments/test.rb:
--------------------------------------------------------------------------------
1 | Dummy::Application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb.
3 |
4 | # The test environment is used exclusively to run your application's
5 | # test suite. You never need to work with it otherwise. Remember that
6 | # your test database is "scratch space" for the test suite and is wiped
7 | # and recreated between test runs. Don't rely on the data there!
8 | config.cache_classes = true
9 |
10 | # Do not eager load code on boot. This avoids loading your whole application
11 | # just for the purpose of running a single test. If you are using a tool that
12 | # preloads Rails for running tests, you may have to set it to true.
13 | config.eager_load = false
14 |
15 | # Configure static asset server for tests with Cache-Control for performance.
16 | config.serve_static_assets = true
17 | config.static_cache_control = "public, max-age=3600"
18 |
19 | # Show full error reports and disable caching.
20 | config.consider_all_requests_local = true
21 | config.action_controller.perform_caching = false
22 |
23 | # Raise exceptions instead of rendering exception templates.
24 | config.action_dispatch.show_exceptions = false
25 |
26 | # Disable request forgery protection in test environment.
27 | config.action_controller.allow_forgery_protection = false
28 |
29 | # Tell Action Mailer not to deliver emails to the real world.
30 | # The :test delivery method accumulates sent emails in the
31 | # ActionMailer::Base.deliveries array.
32 | config.action_mailer.delivery_method = :test
33 |
34 | # Print deprecation notices to the stderr.
35 | config.active_support.deprecation = :stderr
36 | end
37 |
--------------------------------------------------------------------------------
/spec/dummy/app/script/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3 |
4 | APP_PATH = File.expand_path('../../config/application', __FILE__)
5 | require File.expand_path('../../config/boot', __FILE__)
6 | require 'rails/commands'
7 |
--------------------------------------------------------------------------------
/spec/dummy/blank_feature/README.rdoc:
--------------------------------------------------------------------------------
1 | = BlankFeature
2 |
3 | This project rocks and uses MIT-LICENSE.
--------------------------------------------------------------------------------
/spec/dummy/blank_feature/app/assets/images/blank_feature/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/balvig/chili/3a5e24b1d8b4e731cb1a589a9ae276799549b126/spec/dummy/blank_feature/app/assets/images/blank_feature/.gitkeep
--------------------------------------------------------------------------------
/spec/dummy/blank_feature/app/assets/javascripts/blank_feature/application.js:
--------------------------------------------------------------------------------
1 | // This is a manifest file that'll be compiled into application.js, which will include all the files
2 | // listed below.
3 | //
4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5 | // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6 | //
7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8 | // compiled file.
9 | //
10 | // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details
11 | // about supported directives.
12 | //
13 | //= require_tree .
14 |
--------------------------------------------------------------------------------
/spec/dummy/blank_feature/app/assets/stylesheets/blank_feature/application.css:
--------------------------------------------------------------------------------
1 | /*
2 | * This is a manifest file that'll be compiled into application.css, which will include all the files
3 | * listed below.
4 | *
5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6 | * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7 | *
8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the
9 | * compiled file so the styles you add here take precedence over styles defined in any styles
10 | * defined in the other CSS/SCSS files in this directory. It is generally better to create a new
11 | * file per style scope.
12 | *
13 | *= require_tree .
14 | *= require_self
15 | */
16 |
--------------------------------------------------------------------------------
/spec/dummy/blank_feature/app/controllers/blank_feature/application_controller.rb:
--------------------------------------------------------------------------------
1 | module BlankFeature
2 | class ApplicationController < Chili::ApplicationController
3 | end
4 | end
5 |
--------------------------------------------------------------------------------
/spec/dummy/blank_feature/app/overrides/layouts/application/assets.html.erb.deface:
--------------------------------------------------------------------------------
1 |
2 | <%= stylesheet_link_tag 'blank_feature/application' %>
3 | <%= javascript_include_tag 'blank_feature/application' %>
4 |
--------------------------------------------------------------------------------
/spec/dummy/blank_feature/app/overrides/layouts/application/example.html.erb.deface:
--------------------------------------------------------------------------------
1 |
2 |
3 | blank_feature active - edit/remove this file:
4 | lib/chili/blank_feature/app/overrides/layouts/application/example.html.erb.deface
5 | <%= link_to 'deface docs', 'https://github.com/spree/deface', target: '_blank' %>
6 |
7 |
--------------------------------------------------------------------------------
/spec/dummy/blank_feature/blank_feature.gemspec:
--------------------------------------------------------------------------------
1 | $:.push File.expand_path("../lib", __FILE__)
2 |
3 | # Maintain your gem's version:
4 | require "blank_feature/version"
5 |
6 | # Describe your gem and declare its dependencies:
7 | Gem::Specification.new do |s|
8 | s.name = "blank_feature"
9 | s.version = BlankFeature::VERSION
10 | s.authors = ["GIT_AUTHOR"]
11 | s.email = ["GIT_EMAIL"]
12 | s.homepage = ""
13 | s.summary = "Summary of BlankFeature."
14 | s.description = "Description of BlankFeature."
15 | s.license = "MIT"
16 |
17 | s.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.rdoc"]
18 |
19 | s.add_dependency "rails", "~> 4.1.6"
20 |
21 | s.add_dependency 'chili', '~> 4.0'
22 |
23 | s.add_development_dependency "sqlite3"
24 | end
25 |
--------------------------------------------------------------------------------
/spec/dummy/blank_feature/config/routes.rb:
--------------------------------------------------------------------------------
1 | BlankFeature::Engine.automount!
2 | BlankFeature::Engine.routes.draw do
3 | end
4 |
--------------------------------------------------------------------------------
/spec/dummy/blank_feature/lib/blank_feature.rb:
--------------------------------------------------------------------------------
1 | require "chili"
2 | require "blank_feature/engine"
3 |
4 | module BlankFeature
5 | extend Chili::Base
6 | active_if { true } # edit this to activate/deactivate feature at runtime
7 | end
8 |
--------------------------------------------------------------------------------
/spec/dummy/blank_feature/lib/blank_feature/engine.rb:
--------------------------------------------------------------------------------
1 | module BlankFeature
2 | class Engine < ::Rails::Engine
3 | isolate_namespace BlankFeature
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/spec/dummy/blank_feature/lib/blank_feature/version.rb:
--------------------------------------------------------------------------------
1 | module BlankFeature
2 | VERSION = "0.0.1"
3 | end
4 |
--------------------------------------------------------------------------------
/spec/dummy/blank_feature/lib/generators/blank_feature_generator.rb:
--------------------------------------------------------------------------------
1 | class BlankFeatureGenerator < Rails::Generators::Base
2 | include Chili::GeneratorProxy
3 | end
4 |
--------------------------------------------------------------------------------
/spec/dummy/blank_feature/lib/tasks/blank_feature_tasks.rake:
--------------------------------------------------------------------------------
1 | # desc "Explaining what the task does"
2 | # task :blank_feature do
3 | # # Task goes here
4 | # end
5 |
--------------------------------------------------------------------------------
/spec/example_app/README.rdoc:
--------------------------------------------------------------------------------
1 | == README
2 |
3 | This README would normally document whatever steps are necessary to get the
4 | application up and running.
5 |
6 | Things you may want to cover:
7 |
8 | * Ruby version
9 |
10 | * System dependencies
11 |
12 | * Configuration
13 |
14 | * Database creation
15 |
16 | * Database initialization
17 |
18 | * How to run the test suite
19 |
20 | * Services (job queues, cache servers, search engines, etc.)
21 |
22 | * Deployment instructions
23 |
24 | * ...
25 |
26 |
27 | Please feel free to use a different markup language if you do not plan to run
28 | rake doc:app.
29 |
--------------------------------------------------------------------------------
/spec/example_app/Rakefile:
--------------------------------------------------------------------------------
1 | # Add your own tasks in files placed in lib/tasks ending in .rake,
2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3 |
4 | require File.expand_path('../config/application', __FILE__)
5 |
6 | Dummy::Application.load_tasks
7 |
--------------------------------------------------------------------------------
/spec/example_app/app/assets/javascripts/application.js:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/balvig/chili/3a5e24b1d8b4e731cb1a589a9ae276799549b126/spec/example_app/app/assets/javascripts/application.js
--------------------------------------------------------------------------------
/spec/example_app/app/assets/stylesheets/application.css:
--------------------------------------------------------------------------------
1 | /*
2 | * This is a manifest file that'll be compiled into application.css, which will include all the files
3 | * listed below.
4 | *
5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6 | * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7 | *
8 | * You're free to add application-wide styles to this file and they'll appear at the top of the
9 | * compiled file, but it's generally better to create a new file per style scope.
10 | *
11 | *= require_self
12 | *= require_tree .
13 | */
14 |
--------------------------------------------------------------------------------
/spec/example_app/app/assets/stylesheets/posts.css:
--------------------------------------------------------------------------------
1 | /*
2 | Place all the styles related to the matching controller here.
3 | They will automatically be included in application.css.
4 | */
5 |
--------------------------------------------------------------------------------
/spec/example_app/app/assets/stylesheets/scaffold.css:
--------------------------------------------------------------------------------
1 | body { background-color: #fff; color: #333; }
2 |
3 | body, p, ol, ul, td {
4 | font-family: verdana, arial, helvetica, sans-serif;
5 | font-size: 13px;
6 | line-height: 18px;
7 | }
8 |
9 | pre {
10 | background-color: #eee;
11 | padding: 10px;
12 | font-size: 11px;
13 | }
14 |
15 | a { color: #4CAEDD; }
16 | a:visited { color: #4CAEDD; }
17 | a:hover { color: #fff; background-color:#000; }
18 |
19 | div.field, div.actions {
20 | margin-bottom: 10px;
21 | }
22 |
23 | #notice {
24 | color: green;
25 | }
26 |
27 | .field_with_errors {
28 | padding: 2px;
29 | background-color: red;
30 | display: table;
31 | }
32 |
33 | #error_explanation {
34 | width: 450px;
35 | border: 2px solid red;
36 | padding: 7px;
37 | padding-bottom: 0;
38 | margin-bottom: 20px;
39 | background-color: #f0f0f0;
40 | }
41 |
42 | #error_explanation h2 {
43 | text-align: left;
44 | font-weight: bold;
45 | padding: 5px 5px 5px 15px;
46 | font-size: 12px;
47 | margin: -7px;
48 | margin-bottom: 0px;
49 | background-color: #c00;
50 | color: #fff;
51 | }
52 |
53 | #error_explanation ul li {
54 | font-size: 12px;
55 | list-style: square;
56 | }
57 |
58 | header {
59 | background:#DDD;
60 | padding:8px 6px;
61 | }
62 |
63 | header form, header form div {
64 | display: inline;
65 | }
66 |
67 | table {
68 | border:1px solid #CCC;
69 | border-radius:4px;
70 | }
71 |
72 | th {
73 | text-align:left;
74 | border-bottom:3px double #CCC;
75 | }
76 |
77 | th, td {
78 | padding:0.8em 1.1em;
79 | font-size: 1.1em;
80 | }
81 |
82 | .remark {
83 | font-weight:normal;
84 | font-style:italic;
85 | color:#888;
86 | }
87 |
88 | .disclaimer {
89 | background: #FFFF8B;
90 | padding: 9px;
91 | display: inline-block;
92 | }
93 |
--------------------------------------------------------------------------------
/spec/example_app/app/assets/stylesheets/users.css:
--------------------------------------------------------------------------------
1 | /*
2 | Place all the styles related to the matching controller here.
3 | They will automatically be included in application.css.
4 | */
5 |
--------------------------------------------------------------------------------
/spec/example_app/app/controllers/application_controller.rb:
--------------------------------------------------------------------------------
1 | class ApplicationController < ActionController::Base
2 | protect_from_forgery
3 | helper_method :current_user, :logged_in?
4 |
5 | def current_user
6 | User.find_by_id(session[:user_id])
7 | end
8 |
9 | def logged_in?
10 | current_user
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/spec/example_app/app/controllers/posts_controller.rb:
--------------------------------------------------------------------------------
1 | class PostsController < ApplicationController
2 | # GET /posts
3 | # GET /posts.json
4 | def index
5 | @posts = Post.all
6 |
7 | respond_to do |format|
8 | format.html # index.html.erb
9 | format.json { render json: @posts }
10 | end
11 | end
12 |
13 | # GET /posts/1
14 | # GET /posts/1.json
15 | def show
16 | @post = Post.find(params[:id])
17 |
18 | respond_to do |format|
19 | format.html # show.html.erb
20 | format.json { render json: @post }
21 | end
22 | end
23 |
24 | # GET /posts/new
25 | # GET /posts/new.json
26 | def new
27 | @post = Post.new
28 |
29 | respond_to do |format|
30 | format.html # new.html.erb
31 | format.json { render json: @post }
32 | end
33 | end
34 |
35 | # GET /posts/1/edit
36 | def edit
37 | @post = Post.find(params[:id])
38 | end
39 |
40 | # POST /posts
41 | # POST /posts.json
42 | def create
43 | @post = Post.new(post_params)
44 |
45 | respond_to do |format|
46 | if @post.save
47 | format.html { redirect_to @post, notice: 'Post was successfully created.' }
48 | format.json { render json: @post, status: :created, location: @post }
49 | else
50 | format.html { render action: "new" }
51 | format.json { render json: @post.errors, status: :unprocessable_entity }
52 | end
53 | end
54 | end
55 |
56 | # PUT /posts/1
57 | # PUT /posts/1.json
58 | def update
59 | @post = Post.find(params[:id])
60 |
61 | respond_to do |format|
62 | if @post.update_attributes(post_params)
63 | format.html { redirect_to @post, notice: 'Post was successfully updated.' }
64 | format.json { head :no_content }
65 | else
66 | format.html { render action: "edit" }
67 | format.json { render json: @post.errors, status: :unprocessable_entity }
68 | end
69 | end
70 | end
71 |
72 | # DELETE /posts/1
73 | # DELETE /posts/1.json
74 | def destroy
75 | @post = Post.find(params[:id])
76 | @post.destroy
77 |
78 | respond_to do |format|
79 | format.html { redirect_to posts_url }
80 | format.json { head :no_content }
81 | end
82 | end
83 |
84 | private
85 |
86 | def post_params
87 | params.require(:post).permit(:title)
88 | end
89 | end
90 |
--------------------------------------------------------------------------------
/spec/example_app/app/controllers/sessions_controller.rb:
--------------------------------------------------------------------------------
1 | class SessionsController < ApplicationController
2 | def create
3 | session[:user_id] = User.find_by_name(params[:name]).id
4 | redirect_to root_path
5 | end
6 |
7 | def destroy
8 | session[:user_id] = nil
9 | redirect_to root_path
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/spec/example_app/app/controllers/users_controller.rb:
--------------------------------------------------------------------------------
1 | class UsersController < ApplicationController
2 | # GET /users
3 | # GET /users.json
4 | def index
5 | @users = User.all
6 |
7 | respond_to do |format|
8 | format.html # index.html.erb
9 | format.json { render json: @users }
10 | end
11 | end
12 |
13 | # GET /users/1
14 | # GET /users/1.json
15 | def show
16 | @user = User.find(params[:id])
17 |
18 | respond_to do |format|
19 | format.html # show.html.erb
20 | format.json { render json: @user }
21 | end
22 | end
23 |
24 | # GET /users/new
25 | # GET /users/new.json
26 | def new
27 | @user = User.new
28 |
29 | respond_to do |format|
30 | format.html # new.html.erb
31 | format.json { render json: @user }
32 | end
33 | end
34 |
35 | # GET /users/1/edit
36 | def edit
37 | @user = User.find(params[:id])
38 | end
39 |
40 | # POST /users
41 | # POST /users.json
42 | def create
43 | @user = User.new(user_params)
44 |
45 | respond_to do |format|
46 | if @user.save
47 | format.html { redirect_to @user, notice: 'User was successfully created.' }
48 | format.json { render json: @user, status: :created, location: @user }
49 | else
50 | format.html { render action: "new" }
51 | format.json { render json: @user.errors, status: :unprocessable_entity }
52 | end
53 | end
54 | end
55 |
56 | # PUT /users/1
57 | # PUT /users/1.json
58 | def update
59 | @user = User.find(params[:id])
60 |
61 | respond_to do |format|
62 | if @user.update_attributes(user_params)
63 | format.html { redirect_to @user, notice: 'User was successfully updated.' }
64 | format.json { head :no_content }
65 | else
66 | format.html { render action: "edit" }
67 | format.json { render json: @user.errors, status: :unprocessable_entity }
68 | end
69 | end
70 | end
71 |
72 | # DELETE /users/1
73 | # DELETE /users/1.json
74 | def destroy
75 | @user = User.find(params[:id])
76 | @user.destroy
77 |
78 | respond_to do |format|
79 | format.html { redirect_to users_url }
80 | format.json { head :no_content }
81 | end
82 | end
83 |
84 | private
85 |
86 | def user_params
87 | params.require(:user).permit(:name)
88 | end
89 | end
90 |
--------------------------------------------------------------------------------
/spec/example_app/app/helpers/application_helper.rb:
--------------------------------------------------------------------------------
1 | module ApplicationHelper
2 | end
3 |
--------------------------------------------------------------------------------
/spec/example_app/app/helpers/posts_helper.rb:
--------------------------------------------------------------------------------
1 | module PostsHelper
2 | end
3 |
--------------------------------------------------------------------------------
/spec/example_app/app/helpers/users_helper.rb:
--------------------------------------------------------------------------------
1 | module UsersHelper
2 | end
3 |
--------------------------------------------------------------------------------
/spec/example_app/app/mailers/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/balvig/chili/3a5e24b1d8b4e731cb1a589a9ae276799549b126/spec/example_app/app/mailers/.gitkeep
--------------------------------------------------------------------------------
/spec/example_app/app/models/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/balvig/chili/3a5e24b1d8b4e731cb1a589a9ae276799549b126/spec/example_app/app/models/.gitkeep
--------------------------------------------------------------------------------
/spec/example_app/app/models/post.rb:
--------------------------------------------------------------------------------
1 | class Post < ActiveRecord::Base
2 | end
3 |
--------------------------------------------------------------------------------
/spec/example_app/app/models/user.rb:
--------------------------------------------------------------------------------
1 | class User < ActiveRecord::Base
2 | end
3 |
--------------------------------------------------------------------------------
/spec/example_app/app/overrides/posts/index/spree.html.erb.deface:
--------------------------------------------------------------------------------
1 |
2 | Permanent spree override
3 |
--------------------------------------------------------------------------------
/spec/example_app/app/views/layouts/application.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Dummy
5 | <%= stylesheet_link_tag "application", :media => "all" %>
6 | <%= javascript_include_tag "application", '//ajax.googleapis.com/ajax/libs/jquery/1.8.1/jquery.min.js', 'https://raw.github.com/rails/jquery-ujs/master/src/rails.js' %>
7 | <%= csrf_meta_tags %>
8 |
9 |
10 |
11 |
12 | <% if logged_in? %>
13 | Hi <%= current_user.name %>. <%= button_to 'Log out', main_app.session_path, method: 'delete' %>
14 | <% else %>
15 | <%= link_to "Log in", main_app.new_session_path %>
16 | <% end %>
17 |
18 |
19 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/spec/example_app/app/views/posts/_form.html.erb:
--------------------------------------------------------------------------------
1 | <%= form_for(@post) do |f| %>
2 | <% if @post.errors.any? %>
3 |
4 |
<%= pluralize(@post.errors.count, "error") %> prohibited this post from being saved:
5 |
6 |
7 | <% @post.errors.full_messages.each do |msg| %>
8 | - <%= msg %>
9 | <% end %>
10 |
11 |
12 | <% end %>
13 |
14 |
15 | <%= f.label :title %>
16 | <%= f.text_field :title %>
17 |
18 |
19 | <%= f.submit %>
20 |
21 | <% end %>
22 |
--------------------------------------------------------------------------------
/spec/example_app/app/views/posts/_post.html.erb:
--------------------------------------------------------------------------------
1 |
2 | <%= post.title %> |
3 |
4 |
--------------------------------------------------------------------------------
/spec/example_app/app/views/posts/edit.html.erb:
--------------------------------------------------------------------------------
1 | Editing post
2 |
3 | <%= render 'form' %>
4 |
5 | <%= link_to 'Show', @post %> |
6 | <%= link_to 'Back', posts_path %>
7 |
--------------------------------------------------------------------------------
/spec/example_app/app/views/posts/index.html.erb:
--------------------------------------------------------------------------------
1 | Listing posts
2 |
3 |
4 |
5 | Title |
6 |
7 |
8 | <%= render @posts %>
9 |
10 |
11 |
12 |
13 | <%= link_to 'New Post', new_post_path %>
14 |
--------------------------------------------------------------------------------
/spec/example_app/app/views/posts/new.html.erb:
--------------------------------------------------------------------------------
1 | New post
2 |
3 | <%= render 'form' %>
4 |
5 | <%= link_to 'Back', posts_path %>
6 |
--------------------------------------------------------------------------------
/spec/example_app/app/views/posts/show.html.erb:
--------------------------------------------------------------------------------
1 | <%= notice %>
2 |
3 |
4 | Title:
5 | <%= @post.title %>
6 |
7 |
8 |
9 | <%= link_to 'Edit', edit_post_path(@post) %> |
10 | <%= link_to 'Back', posts_path %>
11 |
--------------------------------------------------------------------------------
/spec/example_app/app/views/sessions/new.html.erb:
--------------------------------------------------------------------------------
1 | Input name
2 | <%= form_tag session_path do %>
3 | <%= text_field_tag :name %>
4 | <%= submit_tag 'Log in' %>
5 | <% end %>
6 |
--------------------------------------------------------------------------------
/spec/example_app/app/views/users/_form.html.erb:
--------------------------------------------------------------------------------
1 | <%= form_for(@user) do |f| %>
2 | <% if @user.errors.any? %>
3 |
4 |
<%= pluralize(@user.errors.count, "error") %> prohibited this user from being saved:
5 |
6 |
7 | <% @user.errors.full_messages.each do |msg| %>
8 | - <%= msg %>
9 | <% end %>
10 |
11 |
12 | <% end %>
13 |
14 |
15 | <%= f.label :name %>
16 | <%= f.text_field :name %>
17 |
18 |
19 | <%= f.submit %>
20 |
21 | <% end %>
22 |
--------------------------------------------------------------------------------
/spec/example_app/app/views/users/edit.html.erb:
--------------------------------------------------------------------------------
1 | Editing user
2 |
3 | <%= render 'form' %>
4 |
5 | <%= link_to 'Show', @user %> |
6 | <%= link_to 'Back', users_path %>
7 |
--------------------------------------------------------------------------------
/spec/example_app/app/views/users/index.html.erb:
--------------------------------------------------------------------------------
1 | Listing users
2 |
3 |
4 |
5 | Name |
6 | |
7 | |
8 | |
9 |
10 |
11 | <% @users.each do |user| %>
12 |
13 | <%= user.name %> |
14 | <%= link_to 'Show', user %> |
15 | <%= link_to 'Edit', edit_user_path(user) %> |
16 | <%= link_to 'Destroy', user, confirm: 'Are you sure?', method: :delete %> |
17 |
18 | <% end %>
19 |
20 |
21 |
22 |
23 | <%= link_to 'New User', new_user_path %>
24 |
--------------------------------------------------------------------------------
/spec/example_app/app/views/users/new.html.erb:
--------------------------------------------------------------------------------
1 | New user
2 |
3 | <%= render 'form' %>
4 |
5 | <%= link_to 'Back', users_path %>
6 |
--------------------------------------------------------------------------------
/spec/example_app/app/views/users/show.html.erb:
--------------------------------------------------------------------------------
1 | <%= notice %>
2 |
3 |
4 | Name:
5 | <%= @user.name %>
6 |
7 |
8 |
9 | <%= link_to 'Edit', edit_user_path(@user) %> |
10 | <%= link_to 'Back', users_path %>
11 |
--------------------------------------------------------------------------------
/spec/example_app/config.ru:
--------------------------------------------------------------------------------
1 | # This file is used by Rack-based servers to start the application.
2 |
3 | require ::File.expand_path('../config/environment', __FILE__)
4 | run Dummy::Application
5 |
--------------------------------------------------------------------------------
/spec/example_app/config/application.rb:
--------------------------------------------------------------------------------
1 | require File.expand_path('../boot', __FILE__)
2 |
3 | require 'rails/all'
4 |
5 | # Require the gems listed in Gemfile, including any gems
6 | # you've limited to :test, :development, or :production.
7 | Bundler.require(:default, Rails.env)
8 | require "chili"
9 | require "social_feature"
10 | require "invites_feature"
11 |
12 | module Dummy
13 | class Application < Rails::Application
14 | # Settings in config/environments/* take precedence over those specified here.
15 | # Application configuration should go into files in config/initializers
16 | # -- all .rb files in that directory are automatically loaded.
17 |
18 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
19 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
20 | # config.time_zone = 'Central Time (US & Canada)'
21 |
22 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
23 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
24 | # config.i18n.default_locale = :de
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/spec/example_app/config/boot.rb:
--------------------------------------------------------------------------------
1 | # Set up gems listed in the Gemfile.
2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../../Gemfile', __FILE__)
3 |
4 | require 'bundler/setup' if File.exists?(ENV['BUNDLE_GEMFILE'])
5 | $:.unshift File.expand_path('../../../../../lib', __FILE__)
6 | $:.unshift File.expand_path('../../lib/chili/social_feature/lib', __FILE__)
7 | $:.unshift File.expand_path('../../lib/chili/invites_feature/lib', __FILE__)
8 |
--------------------------------------------------------------------------------
/spec/example_app/config/database.yml:
--------------------------------------------------------------------------------
1 | # SQLite version 3.x
2 | # gem install sqlite3
3 | #
4 | # Ensure the SQLite 3 gem is defined in your Gemfile
5 | # gem 'sqlite3'
6 | development:
7 | adapter: sqlite3
8 | database: db/development.sqlite3
9 | pool: 5
10 | timeout: 5000
11 |
12 | # Warning: The database defined as "test" will be erased and
13 | # re-generated from your development database when you run "rake".
14 | # Do not set this db to the same as development or production.
15 | test:
16 | adapter: sqlite3
17 | database: db/test.sqlite3
18 | pool: 5
19 | timeout: 5000
20 |
21 | production:
22 | adapter: sqlite3
23 | database: db/production.sqlite3
24 | pool: 5
25 | timeout: 5000
26 |
--------------------------------------------------------------------------------
/spec/example_app/config/environment.rb:
--------------------------------------------------------------------------------
1 | # Load the Rails application.
2 | require File.expand_path('../application', __FILE__)
3 |
4 | # Initialize the Rails application.
5 | Dummy::Application.initialize!
6 |
--------------------------------------------------------------------------------
/spec/example_app/config/environments/development.rb:
--------------------------------------------------------------------------------
1 | Dummy::Application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb.
3 |
4 | # In the development environment your application's code is reloaded on
5 | # every request. This slows down response time but is perfect for development
6 | # since you don't have to restart the web server when you make code changes.
7 | config.cache_classes = false
8 |
9 | # Do not eager load code on boot.
10 | config.eager_load = false
11 |
12 | # Show full error reports and disable caching.
13 | config.consider_all_requests_local = true
14 | config.action_controller.perform_caching = false
15 |
16 | # Don't care if the mailer can't send.
17 | config.action_mailer.raise_delivery_errors = false
18 |
19 | # Print deprecation notices to the Rails logger.
20 | config.active_support.deprecation = :log
21 |
22 | # Raise an error on page load if there are pending migrations
23 | config.active_record.migration_error = :page_load
24 |
25 | # Debug mode disables concatenation and preprocessing of assets.
26 | # This option may cause significant delays in view rendering with a large
27 | # number of complex assets.
28 | config.assets.debug = true
29 | end
30 |
--------------------------------------------------------------------------------
/spec/example_app/config/environments/production.rb:
--------------------------------------------------------------------------------
1 | Dummy::Application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb.
3 |
4 | # Code is not reloaded between requests.
5 | config.cache_classes = true
6 |
7 | # Eager load code on boot. This eager loads most of Rails and
8 | # your application in memory, allowing both thread web servers
9 | # and those relying on copy on write to perform better.
10 | # Rake tasks automatically ignore this option for performance.
11 | config.eager_load = true
12 |
13 | # Full error reports are disabled and caching is turned on.
14 | config.consider_all_requests_local = false
15 | config.action_controller.perform_caching = true
16 |
17 | # Enable Rack::Cache to put a simple HTTP cache in front of your application
18 | # Add `rack-cache` to your Gemfile before enabling this.
19 | # For large-scale production use, consider using a caching reverse proxy like nginx, varnish or squid.
20 | # config.action_dispatch.rack_cache = true
21 |
22 | # Disable Rails's static asset server (Apache or nginx will already do this).
23 | config.serve_static_assets = false
24 |
25 | # Compress JavaScripts and CSS.
26 | config.assets.js_compressor = :uglifier
27 | # config.assets.css_compressor = :sass
28 |
29 | # Do not fallback to assets pipeline if a precompiled asset is missed.
30 | config.assets.compile = false
31 |
32 | # Generate digests for assets URLs.
33 | config.assets.digest = true
34 |
35 | # Version of your assets, change this if you want to expire all your assets.
36 | config.assets.version = '1.0'
37 |
38 | # Specifies the header that your server uses for sending files.
39 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
40 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
41 |
42 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
43 | # config.force_ssl = true
44 |
45 | # Set to :debug to see everything in the log.
46 | config.log_level = :info
47 |
48 | # Prepend all log lines with the following tags.
49 | # config.log_tags = [ :subdomain, :uuid ]
50 |
51 | # Use a different logger for distributed setups.
52 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
53 |
54 | # Use a different cache store in production.
55 | # config.cache_store = :mem_cache_store
56 |
57 | # Enable serving of images, stylesheets, and JavaScripts from an asset server.
58 | # config.action_controller.asset_host = "http://assets.example.com"
59 |
60 | # Precompile additional assets.
61 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
62 | # config.assets.precompile += %w( search.js )
63 |
64 | # Ignore bad email addresses and do not raise email delivery errors.
65 | # Set this to true and configure the email server for immediate delivery to raise delivery errors.
66 | # config.action_mailer.raise_delivery_errors = false
67 |
68 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
69 | # the I18n.default_locale when a translation can not be found).
70 | config.i18n.fallbacks = true
71 |
72 | # Send deprecation notices to registered listeners.
73 | config.active_support.deprecation = :notify
74 |
75 | # Disable automatic flushing of the log to improve performance.
76 | # config.autoflush_log = false
77 |
78 | # Use default logging formatter so that PID and timestamp are not suppressed.
79 | config.log_formatter = ::Logger::Formatter.new
80 | end
81 |
--------------------------------------------------------------------------------
/spec/example_app/config/environments/test.rb:
--------------------------------------------------------------------------------
1 | Dummy::Application.configure do
2 | # Settings specified here will take precedence over those in config/application.rb.
3 |
4 | # The test environment is used exclusively to run your application's
5 | # test suite. You never need to work with it otherwise. Remember that
6 | # your test database is "scratch space" for the test suite and is wiped
7 | # and recreated between test runs. Don't rely on the data there!
8 | config.cache_classes = true
9 |
10 | # Do not eager load code on boot. This avoids loading your whole application
11 | # just for the purpose of running a single test. If you are using a tool that
12 | # preloads Rails for running tests, you may have to set it to true.
13 | config.eager_load = false
14 |
15 | # Configure static asset server for tests with Cache-Control for performance.
16 | config.serve_static_assets = true
17 | config.static_cache_control = "public, max-age=3600"
18 |
19 | # Show full error reports and disable caching.
20 | config.consider_all_requests_local = true
21 | config.action_controller.perform_caching = false
22 |
23 | # Raise exceptions instead of rendering exception templates.
24 | config.action_dispatch.show_exceptions = false
25 |
26 | # Disable request forgery protection in test environment.
27 | config.action_controller.allow_forgery_protection = false
28 |
29 | # Tell Action Mailer not to deliver emails to the real world.
30 | # The :test delivery method accumulates sent emails in the
31 | # ActionMailer::Base.deliveries array.
32 | config.action_mailer.delivery_method = :test
33 |
34 | # Print deprecation notices to the stderr.
35 | config.active_support.deprecation = :stderr
36 | end
37 |
--------------------------------------------------------------------------------
/spec/example_app/config/initializers/backtrace_silencers.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
5 |
6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
7 | # Rails.backtrace_cleaner.remove_silencers!
8 |
--------------------------------------------------------------------------------
/spec/example_app/config/initializers/filter_parameter_logging.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Configure sensitive parameters which will be filtered from the log file.
4 | Rails.application.config.filter_parameters += [:password]
5 |
--------------------------------------------------------------------------------
/spec/example_app/config/initializers/inflections.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new inflection rules using the following format. Inflections
4 | # are locale specific, and you may define rules for as many different
5 | # locales as you wish. All of these examples are active by default:
6 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
7 | # inflect.plural /^(ox)$/i, '\1en'
8 | # inflect.singular /^(ox)en/i, '\1'
9 | # inflect.irregular 'person', 'people'
10 | # inflect.uncountable %w( fish sheep )
11 | # end
12 |
13 | # These inflection rules are supported but not enabled by default:
14 | # ActiveSupport::Inflector.inflections(:en) do |inflect|
15 | # inflect.acronym 'RESTful'
16 | # end
17 |
--------------------------------------------------------------------------------
/spec/example_app/config/initializers/mime_types.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Add new mime types for use in respond_to blocks:
4 | # Mime::Type.register "text/richtext", :rtf
5 | # Mime::Type.register_alias "text/html", :iphone
6 |
--------------------------------------------------------------------------------
/spec/example_app/config/initializers/secret_token.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Your secret key is used for verifying the integrity of signed cookies.
4 | # If you change this key, all old signed cookies will become invalid!
5 |
6 | # Make sure the secret is at least 30 characters and all random,
7 | # no regular words or you'll be exposed to dictionary attacks.
8 | # You can use `rake secret` to generate a secure secret key.
9 |
10 | # Make sure your secret_key_base is kept private
11 | # if you're sharing your code publicly.
12 | Dummy::Application.config.secret_key_base = '2a0617151da19d2aabb8ffe843d6c90ad2d4d9482f4291ec42ae5e60cd01210defd77db787cc47cc4d5997da47b3f40156fcc298b7b4caabd076b63e3e0aa26c'
13 |
--------------------------------------------------------------------------------
/spec/example_app/config/initializers/session_store.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | Dummy::Application.config.session_store :cookie_store, key: '_dummy_session'
4 |
--------------------------------------------------------------------------------
/spec/example_app/config/initializers/wrap_parameters.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # This file contains settings for ActionController::ParamsWrapper which
4 | # is enabled by default.
5 |
6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array.
7 | ActiveSupport.on_load(:action_controller) do
8 | wrap_parameters format: [:json] if respond_to?(:wrap_parameters)
9 | end
10 |
11 | # To enable root element in JSON for ActiveRecord objects.
12 | # ActiveSupport.on_load(:active_record) do
13 | # self.include_root_in_json = true
14 | # end
15 |
--------------------------------------------------------------------------------
/spec/example_app/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | # Files in the config/locales directory are used for internationalization
2 | # and are automatically loaded by Rails. If you want to use locales other
3 | # than English, add the necessary files in this directory.
4 | #
5 | # To use the locales, use `I18n.t`:
6 | #
7 | # I18n.t 'hello'
8 | #
9 | # In views, this is aliased to just `t`:
10 | #
11 | # <%= t('hello') %>
12 | #
13 | # To use a different locale, set it with `I18n.locale`:
14 | #
15 | # I18n.locale = :es
16 | #
17 | # This would use the information in config/locales/es.yml.
18 | #
19 | # To learn more, please read the Rails Internationalization guide
20 | # available at http://guides.rubyonrails.org/i18n.html.
21 |
22 | en:
23 | hello: "Hello world"
24 |
--------------------------------------------------------------------------------
/spec/example_app/config/routes.rb:
--------------------------------------------------------------------------------
1 | Dummy::Application.routes.draw do
2 | resources :users, :posts
3 | resource :session
4 | root to: 'posts#index'
5 | end
6 |
--------------------------------------------------------------------------------
/spec/example_app/db/migrate/20120513023816_create_posts.rb:
--------------------------------------------------------------------------------
1 | class CreatePosts < ActiveRecord::Migration
2 | def change
3 | create_table :posts do |t|
4 | t.string :title
5 |
6 | t.timestamps
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/spec/example_app/db/migrate/20120513023840_create_users.rb:
--------------------------------------------------------------------------------
1 | class CreateUsers < ActiveRecord::Migration
2 | def change
3 | create_table :users do |t|
4 | t.string :name, default: 'Bob'
5 | t.boolean :admin
6 | t.timestamps
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/spec/example_app/db/migrate/20120513032032_create_social_feature_likes.rb:
--------------------------------------------------------------------------------
1 | # This migration comes from social_feature (originally 20120513031021)
2 | class CreateSocialFeatureLikes < ActiveRecord::Migration
3 | def change
4 | create_table :social_feature_likes do |t|
5 | t.integer :post_id
6 | t.integer :user_id
7 |
8 | t.timestamps
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/spec/example_app/db/schema.rb:
--------------------------------------------------------------------------------
1 | # encoding: UTF-8
2 | # This file is auto-generated from the current state of the database. Instead
3 | # of editing this file, please use the migrations feature of Active Record to
4 | # incrementally modify your database, and then regenerate this schema definition.
5 | #
6 | # Note that this schema.rb definition is the authoritative source for your
7 | # database schema. If you need to create the application database on another
8 | # system, you should be using db:schema:load, not running all the migrations
9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations
10 | # you'll amass, the slower it'll run and the greater likelihood for issues).
11 | #
12 | # It's strongly recommended to check this file into your version control system.
13 |
14 | ActiveRecord::Schema.define(:version => 20120513032032) do
15 |
16 | create_table "posts", :force => true do |t|
17 | t.string "title"
18 | t.datetime "created_at", :null => false
19 | t.datetime "updated_at", :null => false
20 | end
21 |
22 | create_table "social_feature_likes", :force => true do |t|
23 | t.integer "post_id"
24 | t.integer "user_id"
25 | t.datetime "created_at", :null => false
26 | t.datetime "updated_at", :null => false
27 | end
28 |
29 | create_table "users", :force => true do |t|
30 | t.string "name", :default => "Bob"
31 | t.boolean "admin"
32 | t.datetime "created_at", :null => false
33 | t.datetime "updated_at", :null => false
34 | end
35 |
36 | end
37 |
--------------------------------------------------------------------------------
/spec/example_app/lib/assets/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/balvig/chili/3a5e24b1d8b4e731cb1a589a9ae276799549b126/spec/example_app/lib/assets/.gitkeep
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/invites_feature/.gitignore:
--------------------------------------------------------------------------------
1 | .bundle/
2 | log/*.log
3 | pkg/
4 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/invites_feature/app/assets/images/invites_feature/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/balvig/chili/3a5e24b1d8b4e731cb1a589a9ae276799549b126/spec/example_app/lib/chili/invites_feature/app/assets/images/invites_feature/.gitkeep
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/invites_feature/app/assets/javascripts/invites_feature/application.js:
--------------------------------------------------------------------------------
1 | // This is a manifest file that'll be compiled into application.js, which will include all the files
2 | // listed below.
3 | //
4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5 | // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6 | //
7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8 | // the compiled file.
9 | //
10 | // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11 | // GO AFTER THE REQUIRES BELOW.
12 | //
13 | //= require_tree .
14 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/invites_feature/app/assets/stylesheets/invites_feature/application.css:
--------------------------------------------------------------------------------
1 | /*
2 | * This is a manifest file that'll be compiled into application.css, which will include all the files
3 | * listed below.
4 | *
5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6 | * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7 | *
8 | * You're free to add application-wide styles to this file and they'll appear at the top of the
9 | * compiled file, but it's generally better to create a new file per style scope.
10 | *
11 | *= require_self
12 | *= require_tree .
13 | */
14 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/invites_feature/app/controllers/invites_feature/application_controller.rb:
--------------------------------------------------------------------------------
1 | module InvitesFeature
2 | class ApplicationController < Chili::ApplicationController
3 | end
4 | end
5 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/invites_feature/app/overrides/posts/index/disclaimer.html.erb.deface:
--------------------------------------------------------------------------------
1 |
2 | Invite functionality is also in beta
3 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/invites_feature/config/routes.rb:
--------------------------------------------------------------------------------
1 | InvitesFeature::Engine.automount!
2 | InvitesFeature::Engine.routes.draw do
3 | end
4 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/invites_feature/lib/generators/invites_feature_generator.rb:
--------------------------------------------------------------------------------
1 | class InvitesFeatureGenerator < Rails::Generators::Base
2 | include Chili::GeneratorProxy
3 | end
4 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/invites_feature/lib/invites_feature.rb:
--------------------------------------------------------------------------------
1 | require "chili"
2 | require "invites_feature/engine"
3 |
4 | module InvitesFeature
5 | extend Chili::Base
6 | active_if { logged_in? }
7 | end
8 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/invites_feature/lib/invites_feature/engine.rb:
--------------------------------------------------------------------------------
1 | module InvitesFeature
2 | class Engine < ::Rails::Engine
3 | isolate_namespace InvitesFeature
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/social_feature/app/assets/images/social_feature/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/balvig/chili/3a5e24b1d8b4e731cb1a589a9ae276799549b126/spec/example_app/lib/chili/social_feature/app/assets/images/social_feature/.gitkeep
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/social_feature/app/assets/javascripts/social_feature/application.js:
--------------------------------------------------------------------------------
1 | // This is a manifest file that'll be compiled into application.js, which will include all the files
2 | // listed below.
3 | //
4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5 | // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6 | //
7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8 | // the compiled file.
9 | //
10 | // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11 | // GO AFTER THE REQUIRES BELOW.
12 | //
13 | //= require_tree .
14 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/social_feature/app/assets/stylesheets/social_feature/application.css.scss:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/balvig/chili/3a5e24b1d8b4e731cb1a589a9ae276799549b126/spec/example_app/lib/chili/social_feature/app/assets/stylesheets/social_feature/application.css.scss
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/social_feature/app/controllers/social_feature/application_controller.rb:
--------------------------------------------------------------------------------
1 | module SocialFeature
2 | class ApplicationController < Chili::ApplicationController
3 | end
4 | end
5 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/social_feature/app/controllers/social_feature/likes_controller.rb:
--------------------------------------------------------------------------------
1 | module SocialFeature
2 | class LikesController < ApplicationController
3 |
4 | def index
5 | @likes = current_user.likes
6 | end
7 |
8 | def create
9 | @like = current_user.likes.create!(params[:like])
10 | redirect_to :back, notice: 'Post liked!'
11 | end
12 |
13 | private
14 |
15 | def current_user
16 | super.becomes(SocialFeature::User)
17 | end
18 |
19 | def like_params
20 | params.require(:like).permit(:post_id)
21 | end
22 |
23 | end
24 | end
25 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/social_feature/app/models/social_feature/like.rb:
--------------------------------------------------------------------------------
1 | module SocialFeature
2 | class Like < ActiveRecord::Base
3 | belongs_to :post
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/social_feature/app/models/social_feature/post.rb:
--------------------------------------------------------------------------------
1 | module SocialFeature
2 | class Post < ::Post
3 | has_many :likes
4 |
5 | def well_liked?
6 | likes.size >= 3
7 | end
8 | end
9 | end
10 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/social_feature/app/models/social_feature/user.rb:
--------------------------------------------------------------------------------
1 | module SocialFeature
2 | class User < ::User
3 | has_many :likes
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/social_feature/app/overrides/layouts/application/likes_link.html.erb.deface:
--------------------------------------------------------------------------------
1 |
2 | <%= link_to 'See Your Likes', social_feature.likes_path %>
3 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/social_feature/app/overrides/posts/_post/like_actions.html.erb.deface:
--------------------------------------------------------------------------------
1 |
2 | <% post.becomes(SocialFeature::Post).tap do |post| %>
3 | <%= link_to 'Like!', social_feature.likes_path(like: {post_id: post}), method: :post %> |
4 | <%= pluralize post.likes.size, 'like' %> |
5 |
6 | <% end %>
7 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/social_feature/app/overrides/posts/index/disclaimer.html.erb.deface:
--------------------------------------------------------------------------------
1 |
2 | Like functionality is in beta
3 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/social_feature/app/overrides/posts/index/table_headers.html.erb.deface:
--------------------------------------------------------------------------------
1 |
2 | Popularity |
3 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/social_feature/app/views/social_feature/likes/index.html.erb:
--------------------------------------------------------------------------------
1 | Your Likes
2 |
3 |
4 | <% @likes.each do |like| %>
5 | - <%= like.created_at.to_date %> - <%= like.post.title %>
6 | <% end %>
7 |
8 |
9 | <%= link_to 'Go Back', main_app.posts_path %>
10 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/social_feature/config/routes.rb:
--------------------------------------------------------------------------------
1 | SocialFeature::Engine.automount!
2 | SocialFeature::Engine.routes.draw do
3 | resources :likes
4 | end
5 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/social_feature/db/migrate/20120513031021_create_social_feature_likes.rb:
--------------------------------------------------------------------------------
1 | class CreateSocialFeatureLikes < ActiveRecord::Migration
2 | def change
3 | create_table :social_feature_likes do |t|
4 | t.integer :post_id
5 | t.integer :user_id
6 |
7 | t.timestamps
8 | end
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/social_feature/lib/generators/social_feature_generator.rb:
--------------------------------------------------------------------------------
1 | class SocialFeatureGenerator < Rails::Generators::Base
2 | include Chili::GeneratorProxy
3 | end
4 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/social_feature/lib/social_feature.rb:
--------------------------------------------------------------------------------
1 | require "chili"
2 | require "social_feature/engine"
3 |
4 | module SocialFeature
5 | extend Chili::Base
6 | active_if { logged_in? && current_user.admin? }
7 | end
8 |
--------------------------------------------------------------------------------
/spec/example_app/lib/chili/social_feature/lib/social_feature/engine.rb:
--------------------------------------------------------------------------------
1 | module SocialFeature
2 | class Engine < ::Rails::Engine
3 | isolate_namespace SocialFeature
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/spec/example_app/log/.gitkeep:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/balvig/chili/3a5e24b1d8b4e731cb1a589a9ae276799549b126/spec/example_app/log/.gitkeep
--------------------------------------------------------------------------------
/spec/example_app/public/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The page you were looking for doesn't exist (404)
5 |
17 |
18 |
19 |
20 |
21 |
22 |
The page you were looking for doesn't exist.
23 |
You may have mistyped the address or the page may have moved.
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/spec/example_app/public/422.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The change you wanted was rejected (422)
5 |
17 |
18 |
19 |
20 |
21 |
22 |
The change you wanted was rejected.
23 |
Maybe you tried to change something you didn't have access to.
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/spec/example_app/public/500.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | We're sorry, but something went wrong (500)
5 |
17 |
18 |
19 |
20 |
21 |
22 |
We're sorry, but something went wrong.
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/spec/example_app/public/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/balvig/chili/3a5e24b1d8b4e731cb1a589a9ae276799549b126/spec/example_app/public/favicon.ico
--------------------------------------------------------------------------------
/spec/example_app/script/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3 |
4 | APP_PATH = File.expand_path('../../config/application', __FILE__)
5 | require File.expand_path('../../config/boot', __FILE__)
6 | require 'rails/commands'
7 |
--------------------------------------------------------------------------------
/spec/example_app/spec/support/user_macros.rb:
--------------------------------------------------------------------------------
1 | module UserMacros
2 | def login(user)
3 | visit new_session_path
4 | fill_in 'name', with: user.name
5 | click_button 'Log in'
6 | end
7 | end
8 | RSpec.configure { |config| config.include(UserMacros) }
9 |
--------------------------------------------------------------------------------
/spec/features/social_feature_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | feature 'View overrides' do
4 | scenario 'when user is not admin active_if toggles overrides off' do
5 | login User.create!(admin: false)
6 | visit '/posts'
7 | page.should_not have_content('See Your Likes')
8 | page.should_not have_content('Like functionality is in beta')
9 | end
10 |
11 | scenario 'when admin active_if toggles overrides on' do
12 | login User.create!(admin: true)
13 | visit '/posts'
14 | page.should have_content('See Your Likes')
15 | end
16 | end
17 |
18 | feature 'Togglable controllers' do
19 | scenario 'when user is not admin active_if hides controllers in feature' do
20 | login User.create!(admin: false)
21 | visit '/chili/social_feature/likes'
22 | #expect { visit('/chili/social_feature/likes') }.to raise_error(ActionController::RoutingError)
23 | end
24 |
25 | scenario 'when admin active_if makes controllers available' do
26 | login User.create!(admin: true)
27 | visit '/chili/social_feature/likes'
28 | page.should have_content('Your Likes')
29 | end
30 | end
31 |
32 | feature 'Multiple chili features' do
33 | scenario 'multiple overrides do not redefine each other' do
34 | login User.create!(admin: true)
35 | visit '/posts'
36 | page.should have_content('Like functionality is in beta')
37 | page.should have_content('Invite functionality is also in beta')
38 | end
39 |
40 | scenario 'Chili works alongside permanent spree overrides' do
41 | visit '/posts'
42 | page.should have_content('Permanent spree override')
43 | end
44 | end
45 |
--------------------------------------------------------------------------------
/spec/generators/chili/feature_generator_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe 'FeatureGenerator' do
4 | describe 'rails g chili:feature NAME' do
5 | let(:app) { DummyApp.new }
6 | let(:template_path) { File.expand_path("../../../dummy/blank_feature", __FILE__) }
7 |
8 | before { app.setup! }
9 |
10 | it 'creates a new feature with a correct file structure and appends it to the gemfile' do
11 | puts `cd #{app.path} && rails g chili:feature blank`
12 |
13 | Dir.glob(File.join(template_path, "**/*")).reject { |f| File.directory?(f) }.each do |template|
14 | result = File.join(app.path, 'lib/chili/blank_feature', template.sub(template_path, ''))
15 | result_text = File.open(result, 'rb').read
16 | template_text = File.open(template, 'rb').read
17 | template_text.sub!('GIT_AUTHOR',`git config user.name`.chomp) # Git author is different on each machine
18 | template_text.sub!('GIT_EMAIL',`git config user.email`.chomp) # Git email is different on each machine
19 | result_text.should == template_text
20 | end
21 | end
22 |
23 | it "appends new features to the chili group within the gemfile" do
24 | puts `cd #{app.path} && rails g chili:feature blank`
25 | File.open(app.gemfile, 'rb').read.should include <<-RUBY.chomp
26 | group :chili do
27 | gem 'blank_feature', path: 'lib/chili/blank_feature'
28 | end
29 | RUBY
30 |
31 | puts `cd #{app.path} && rails g chili:feature another_blank`
32 | File.open(app.gemfile, 'rb').read.should include <<-RUBY.chomp
33 | group :chili do
34 | gem 'another_blank_feature', path: 'lib/chili/another_blank_feature'
35 | gem 'blank_feature', path: 'lib/chili/blank_feature'
36 | end
37 | RUBY
38 | end
39 | end
40 | end
41 |
--------------------------------------------------------------------------------
/spec/generators/chili/generator_proxy_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | describe Chili::GeneratorProxy do
4 | let(:app) { DummyApp.new }
5 |
6 | before do
7 | app.setup!
8 | puts `cd #{app.path} && rails g chili:feature blank`
9 | end
10 |
11 |
12 | context 'running generator from a newly created feature' do
13 | it "generates resources properly" do
14 | puts `cd #{app.path} && rails g blank_feature scaffold post`
15 | File.exist?(File.join(app.path, 'lib/chili/blank_feature/app/controllers/blank_feature/posts_controller.rb')).should be_true
16 | File.exist?(File.join(app.path, 'lib/chili/blank_feature/app/assets/stylesheets/blank_feature/posts.css')).should be_true
17 | end
18 | end
19 |
20 | context 'running deface override generator' do
21 | it "generates namespaced override properly" do
22 | puts `cd #{app.path} && rails g blank_feature deface:override posts/index add_links`
23 | File.exist?(File.join(app.path, 'lib/chili/blank_feature/app/overrides/posts/index/add_links.html.erb.deface')).should be_true
24 | end
25 | end
26 |
27 | context 'passing in options' do
28 | it "passes options on to rails generator" do
29 | puts `cd #{app.path} && rails g blank_feature scaffold post --stylesheets=false`
30 | File.exist?(File.join(app.path, 'lib/chili/blank_feature/app/controllers/blank_feature/posts_controller.rb')).should be_true
31 | File.exist?(File.join(app.path, 'lib/chili/blank_feature/app/assets/stylesheets/blank_feature/posts.css')).should be_false
32 | end
33 | end
34 |
35 | end
36 |
--------------------------------------------------------------------------------
/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | # This file is copied to spec/ when you run 'rails generate rspec:install'
2 | ENV["RAILS_ENV"] ||= 'test'
3 | require File.expand_path("../example_app/config/environment", __FILE__)
4 | require 'rspec/rails'
5 |
6 | # Requires supporting ruby files with custom matchers and macros, etc,
7 | # in spec/support/ and its subdirectories.
8 | Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f}
9 | Dir[File.join(File.dirname(__FILE__),'support', '**', '*.rb')].each {|f| require f}
10 |
11 | RSpec.configure do |config|
12 | # == Mock Framework
13 | #
14 | # If you prefer to use mocha, flexmock or RR, uncomment the appropriate line:
15 | #
16 | # config.mock_with :mocha
17 | # config.mock_with :flexmock
18 | # config.mock_with :rr
19 |
20 | # Remove this line if you're not using ActiveRecord or ActiveRecord fixtures
21 | config.fixture_path = "#{::Rails.root}/spec/fixtures"
22 |
23 | # If you're not using ActiveRecord, or you'd prefer not to run each of your
24 | # examples within a transaction, remove the following line or assign false
25 | # instead of true.
26 | config.use_transactional_fixtures = true
27 | end
28 |
--------------------------------------------------------------------------------
/spec/support/dummy_app.rb:
--------------------------------------------------------------------------------
1 | class DummyApp
2 | def path
3 | File.expand_path("../../dummy/app", __FILE__)
4 | end
5 |
6 | def gemfile
7 | File.join(path, 'Gemfile')
8 | end
9 |
10 | def setup!
11 | FileUtils.rm_rf File.join(path, 'lib')
12 | FileUtils.rm_rf gemfile
13 | File.open(gemfile, 'w') do |f|
14 | f.write <<-RUBY
15 | group :development do
16 | gem 'somegem'
17 | end
18 | RUBY
19 | end
20 | end
21 | end
22 |
--------------------------------------------------------------------------------