Fully functioning, ready for code review.

This commit is contained in:
Jonathan Abbett 2016-11-21 16:01:27 -05:00
parent 55a510bac0
commit 3849d72de9
40 changed files with 4236 additions and 59 deletions

3
.gitignore vendored
View File

@ -41,4 +41,5 @@ bower.json
# Ignore Byebug command history file.
.byebug_history
.idea/
.idea/
/test/dummy/tmp/

View File

@ -1 +1 @@
2.3.1
2.3.2

View File

@ -2,8 +2,10 @@ PATH
remote: .
specs:
abraham (0.1.0)
jquery-rails
rails (~> 5.0.0, >= 5.0.0.1)
rails-assets-shepherd.js (~> 1.8)
sass-rails (~> 5.0)
GEM
remote: http://rubygems.org/
@ -53,6 +55,10 @@ GEM
globalid (0.3.7)
activesupport (>= 4.1.0)
i18n (0.7.0)
jquery-rails (4.2.1)
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
loofah (2.0.3)
nokogiri (>= 1.5.9)
mail (2.6.4)
@ -96,6 +102,13 @@ GEM
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
rake (11.3.0)
sass (3.4.22)
sass-rails (5.0.6)
railties (>= 4.0.0, < 6)
sass (~> 3.1)
sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3)
sprockets (3.7.0)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
@ -106,6 +119,7 @@ GEM
sqlite3 (1.3.12)
thor (0.19.1)
thread_safe (0.3.5)
tilt (2.0.5)
tzinfo (1.2.2)
thread_safe (~> 0.1)
websocket-driver (0.6.4)

View File

@ -17,8 +17,10 @@ Gem::Specification.new do |s|
s.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.md"]
s.add_dependency "rails", "~> 5.0.0", ">= 5.0.0.1"
s.add_dependency 'sass-rails', '~> 5.0'
s.add_dependency "rails-assets-shepherd.js", "~> 1.8"
s.add_development_dependency "sqlite3"
s.add_runtime_dependency "rails-assets-shepherd.js", "~> 1.8"
s.add_runtime_dependency 'jquery-rails'
end

View File

@ -1,9 +1,10 @@
class AbrahamHistoriesController < ApplicationController
def create
@abraham_history = AbrahamHistory.new(abraham_history_params)
@abraham_history.creator_id = current_user
respond_to do |format|
if @abraham_history.save
format.json { render :show, status: :created, location: @abraham_history }
format.json { render json: @abraham_history, status: :created }
else
format.json { render json: @abraham_history.errors, status: :unprocessable_entity }
end

View File

@ -1,22 +1,22 @@
module AbrahamHelper
def abraham_tour
# Do we have tours for this controller/action in the user's locale?
tours = Rails.configuration.abraham["#{controller_name}.#{action_name}.#{I18n.locale}"]
tours = Rails.configuration.abraham.tours["#{controller_name}.#{action_name}.#{I18n.locale}"]
unless tours
# How about the default locale?
tours = Rails.configuration.abraham["#{controller_name}.#{action_name}.#{I18n.default_locale}"]
tours = Rails.configuration.abraham.tours["#{controller_name}.#{action_name}.#{I18n.default_locale}"]
end
if tours
completed = AbrahamHistory.where(
creator: @current_person, controller_name: controller_name,
creator_id: current_user, controller_name: controller_name,
action_name: action_name)
remaining = tours.keys - completed.map(&:tour_name)
if remaining.any?
# Generate the javascript snippet for the next remaining tour
render(:partial => 'application/tour',
render(:partial => 'application/abraham',
:locals => {:tour_name => remaining.first,
:steps => tours[remaining.first]['steps']})
end

View File

@ -1,8 +1,7 @@
<script>
var tour = new Shepherd.Tour({
defaults: {
// TODO In abraham, this should be configurable
classes: 'shepherd-theme-default'
classes: '<%= Rails.configuration.abraham.default_theme %>'
}
});

View File

@ -1,2 +1,3 @@
Rails.application.routes.draw do
resources :abraham_histories, only: :create
end

View File

@ -1,5 +1,4 @@
require "abraham/engine"
require 'abraham/engine'
module Abraham
# Your code goes here...
end

View File

@ -1,3 +1,7 @@
require 'rubygems'
require 'rails-assets-shepherd.js'
require 'jquery-rails'
module Abraham
class Engine < ::Rails::Engine
end

View File

@ -0,0 +1,26 @@
require 'rails/generators'
require "rails/generators/active_record"
module Abraham
module Generators
class InstallGenerator < ActiveRecord::Generators::Base
argument :name, type: :string, default: 'random_name'
class_option :'skip-migration', :type => :boolean, :desc => "Don't generate a migration for the histories table"
class_option :'skip-initializer', :type => :boolean, :desc => "Don't generate an initializer"
source_root File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
# Copies the migration template to db/migrate.
def copy_files
return if options['skip-migration']
migration_template 'migration.rb', 'db/migrate/create_abraham_histories.rb'
end
def create_initializer
return if options['skip-initializer']
copy_file 'initializer.rb', 'config/initializers/abraham.rb'
end
end
end
end

View File

@ -15,5 +15,6 @@ Rails.application.configure do
end
end
config.abraham = tours
config.abraham.default_theme = 'shepherd-theme-default'
config.abraham.tours = tours
end

View File

@ -0,0 +1,12 @@
class CreateAbrahamHistories < ActiveRecord::Migration[5.0]
def change
create_table :abraham_histories do |t|
t.string :controller_name
t.string :action_name
t.string :tour_name
t.references :creator, null: false, index: true
t.timestamps index: true
end
end
end

View File

@ -1,22 +0,0 @@
require 'rails/generators'
require "rails/generators/active_record"
class AbrahamGenerator < ActiveRecord::Generators::Base
argument :name, type: :string, default: 'random_name'
class_option :'skip-migration', :type => :boolean, :desc => "Don't generate a migration for the histories table"
class_option :'skip-initializer', :type => :boolean, :desc => "Don't generate an initializer"
source_root File.expand_path('../../abraham', __FILE__)
# Copies the migration template to db/migrate.
def copy_files
return if options['skip-migration']
migration_template 'migration.rb', 'db/migrate/create_abraham_histories.rb'
end
def create_initializer
return if options['skip-initializer']
copy_file 'initializer.rb', 'config/initializers/abraham.rb'
end
end

View File

@ -10,4 +10,8 @@
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require jquery
//= require jquery_ujs
//= require tether
//= require shepherd.js.js
//= require_tree .

View File

@ -0,0 +1,2 @@
// Place all the behaviors and hooks related to the matching controller here.
// All this logic will automatically be available in application.js.

View File

@ -10,6 +10,6 @@
* files in this directory. Styles in this file should be added after the last require_* statement.
* It is generally better to create a new file per style scope.
*
*= require "shepherd.js/dist/css/shepherd-theme-default"
*= require_tree .
*= require_self
*/

View File

@ -0,0 +1,4 @@
/*
Place all the styles related to the matching controller here.
They will automatically be included in application.css.
*/

View File

@ -1,3 +1,8 @@
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
helper_method :current_user
def current_user
SecureRandom.uuid
end
end

View File

@ -0,0 +1,7 @@
class DashboardController < ApplicationController
def home
end
def other
end
end

View File

@ -0,0 +1,2 @@
module DashboardHelper
end

View File

@ -0,0 +1,6 @@
<h1>Dashboard#home</h1>
<p>Find me in app/views/dashboard/home.html.erb</p>
<div class="notice-me" style="width:300px;height:300px;background-color:whitesmoke;">
a content element to notice
</div>

View File

@ -0,0 +1,2 @@
<h1>Dashboard#other</h1>
<p>Find me in app/views/dashboard/other.html.erb</p>

View File

@ -10,5 +10,7 @@
<body>
<%= yield %>
<%= abraham_tour %>
</body>
</html>

View File

@ -0,0 +1,21 @@
Rails.application.configure do
tours = {}
if Rails.root.join('config/tours').exist?
Dir[Rails.root.join('config/tours/*/')].each do |dir|
Dir[dir + '*.yml'].each do |yml|
path_parts = yml.split(File::SEPARATOR)
controller = path_parts[path_parts.size - 2]
file_parts = path_parts[path_parts.size - 1].split('.')
action = file_parts[0]
locale = file_parts[1]
t = YAML.load_file(yml)
tours["#{controller}.#{action}.#{locale}"] = t
end
end
end
config.abraham = ActiveSupport::OrderedOptions.new
config.abraham.default_theme = 'shepherd-theme-default'
config.abraham.tours = tours
end

View File

@ -1,3 +1,7 @@
Rails.application.routes.draw do
get 'dashboard/home'
get 'dashboard/other'
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
end

View File

@ -0,0 +1,13 @@
intro:
steps:
1:
text: "ENGLISH This first HOME step is centered text-only"
2:
title: "ENGLISH This step has a title"
text: "ENGLISH This intermediate step has some text"
3:
title: "ENGLISH The final step"
text: "ENGLISH Some text here too, and it's attached to the right"
attachTo:
element: ".notice-me"
position: "right"

View File

@ -0,0 +1,13 @@
intro:
steps:
1:
text: "SPANISH This first HOME step is centered text-only"
2:
title: "SPANISH This step has a title"
text: "This intermediate step has some text"
3:
title: "SPANISH The final step"
text: "Some text here too, and it's attached to the right"
attachTo:
element: ".notice-me"
position: "right"

View File

@ -0,0 +1,11 @@
tour_one:
steps:
1:
title: "TOUR ONE step one ENGLISH"
text: "we show this on your first visit"
tour_two:
steps:
1:
title: "TOUR TWO step one ENGLISH"
text: "we show this on your second visit"

Binary file not shown.

View File

@ -0,0 +1,12 @@
class CreateAbrahamHistories < ActiveRecord::Migration[5.0]
def change
create_table :abraham_histories do |t|
t.string :controller_name
t.string :action_name
t.string :tour_name
t.references :creator, null: false, index: true
t.timestamps index: true
end
end
end

27
test/dummy/db/schema.rb Normal file
View File

@ -0,0 +1,27 @@
# This file is auto-generated from the current state of the database. Instead
# of editing this file, please use the migrations feature of Active Record to
# incrementally modify your database, and then regenerate this schema definition.
#
# Note that this schema.rb definition is the authoritative source for your
# database schema. If you need to create the application database on another
# system, you should be using db:schema:load, not running all the migrations
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
# you'll amass, the slower it'll run and the greater likelihood for issues).
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20161118143752) do
create_table "abraham_histories", force: :cascade do |t|
t.string "controller_name"
t.string "action_name"
t.string "tour_name"
t.integer "creator_id", null: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.index ["created_at"], name: "index_abraham_histories_on_created_at"
t.index ["creator_id"], name: "index_abraham_histories_on_creator_id"
t.index ["updated_at"], name: "index_abraham_histories_on_updated_at"
end
end

Binary file not shown.

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,9 @@
require 'test_helper'
class AbrahamHistoriesControllerTest < ActionDispatch::IntegrationTest
test "should create AbrahamHistory" do
assert_difference ['AbrahamHistory.count'] do
post abraham_histories_url, as: :json, params: { abraham_history: { action_name: "foo", controller_name: "bar", tour_name: "baz"} }
end
end
end

View File

@ -0,0 +1,55 @@
require 'test_helper'
class DashboardControllerTest < ActionDispatch::IntegrationTest
test "uses configured shepherd theme" do
# default
get dashboard_home_url
assert_response :success
assert_select "body script" do |element|
# it's the home tour
assert element.text.include? "classes: 'shepherd-theme-default'"
end
# custom
Rails.configuration.abraham.default_theme = "my-custom-theme"
get dashboard_home_url
assert_select "body script" do |element|
# it's the home tour
assert element.text.include? "classes: 'my-custom-theme'"
end
end
test "home should have home tour code" do
get dashboard_home_url
assert_response :success
assert_select "body script" do |element|
# it's the home tour
assert element.text.include? "ENGLISH This first HOME step is centered text-only"
# it has three steps
assert element.text.include? "step-1"
assert element.text.include? "step-2"
assert element.text.include? "step-3"
# it will post the right completion information
assert element.text.include? "controller_name: 'dashboard'"
assert element.text.include? "action_name: 'home'"
assert element.text.include? "tour_name: 'intro'"
end
end
test "other should have other tour code" do
get dashboard_other_url
assert_response :success
assert_select "body script" do |element|
# it's the home tour
assert element.text.include? "TOUR ONE step one ENGLISH"
# it has only one steps
assert element.text.include? "step-1"
# it will post the right completion information
assert element.text.include? "controller_name: 'dashboard'"
assert element.text.include? "action_name: 'other'"
assert element.text.include? "tour_name: 'tour_one'"
end
end
end

View File

@ -1,11 +0,0 @@
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
one:
controller_name: MyString
action_name: MyString
tour_name: MyString
one:
controller_name: MyString
action_name: MyString
tour_name: MyString

View File

@ -1,10 +1,10 @@
require 'test_helper'
require "rails/generators"
require "generators/abraham_generator"
require "generators/abraham/install_generator"
class AbrahamGeneratorTest < Rails::Generators::TestCase
class InstallGeneratorTest < Rails::Generators::TestCase
tests AbrahamGenerator
tests Abraham::Generators::InstallGenerator
destination File.expand_path("../../tmp", __FILE__)
setup :prepare_destination

View File

@ -8,12 +8,3 @@ require "rails/test_help"
# Filter out Minitest backtrace while allowing backtrace from other libraries
# to be shown.
Minitest.backtrace_filter = Minitest::BacktraceFilter.new
# Load fixtures from the engine
if ActiveSupport::TestCase.respond_to?(:fixture_path=)
ActiveSupport::TestCase.fixture_path = File.expand_path("../fixtures", __FILE__)
ActionDispatch::IntegrationTest.fixture_path = ActiveSupport::TestCase.fixture_path
ActiveSupport::TestCase.file_fixture_path = ActiveSupport::TestCase.fixture_path + "/files"
ActiveSupport::TestCase.fixtures :all
end