Compare commits
1 Commits
master
...
feature/re
Author | SHA1 | Date | |
---|---|---|---|
|
053093e660 |
@ -1 +1 @@
|
|||||||
walter
|
abraham
|
||||||
|
@ -1 +1 @@
|
|||||||
2.6.5
|
2.5.3
|
||||||
|
14
.travis.yml
Normal file
14
.travis.yml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
language: ruby
|
||||||
|
|
||||||
|
env:
|
||||||
|
- 'RAILS_VERSION=5.2.0'
|
||||||
|
- 'RAILS_VERSION=6.0.0'
|
||||||
|
- 'RAILS_VERSION=6.1.0'
|
||||||
|
|
||||||
|
before_script:
|
||||||
|
- 'yarn'
|
||||||
|
- 'bundle install'
|
||||||
|
- 'RAILS_ENV=test bundle exec rake db:create'
|
||||||
|
- 'RAILS_ENV=test bundle exec rake db:migrate'
|
||||||
|
|
||||||
|
script: 'RAILS_ENV=test bundle exec rake test'
|
2
Gemfile
2
Gemfile
@ -19,7 +19,7 @@ rails = case rails_version
|
|||||||
end
|
end
|
||||||
gem 'rails', rails
|
gem 'rails', rails
|
||||||
|
|
||||||
# Declare your gem's dependencies in walter.gemspec.
|
# Declare your gem's dependencies in abraham.gemspec.
|
||||||
# Bundler will treat runtime dependencies like base dependencies, and
|
# Bundler will treat runtime dependencies like base dependencies, and
|
||||||
# development dependencies will be added by default to the :development group.
|
# development dependencies will be added by default to the :development group.
|
||||||
gemspec
|
gemspec
|
||||||
|
204
README.md
204
README.md
@ -1,34 +1,29 @@
|
|||||||
# Walter
|
# Abraham
|
||||||
|
|
||||||
[](https://travis-ci.com/actmd/walter)
|
[](https://travis-ci.com/actmd/abraham)
|
||||||
|
|
||||||
<p align="center">
|
_Guide your users in the one true path._
|
||||||
<i>Product tours like a badass.</i>
|
|
||||||
<br/>
|

|
||||||
<img src="https://img.icons8.com/doodle/240/000000/walter-white.png"/>
|
|
||||||
<br/>
|
Abraham injects dynamically-generated [Shepherd](https://shepherdjs.dev/) JavaScript code into your Rails application whenever a user should see a guided tour. Skip a tour, and we'll try again next time; complete a tour, and it won't show up again.
|
||||||
<a style='font-size: 12px;' href="https://icons8.com/icon/5iWNvQRbAKx9/walter-white">Walter White icon by Icons8</a>
|
|
||||||
</p>
|
|
||||||
Walter makes it easy to show guided tours to users of your Rails application. When Walter shows a tour, it keeps track of whether the user has completed it (so it doesn't get shown again) or dismissed it for later (so it reappears in a future user session).
|
|
||||||
|
|
||||||
* Define tour content with simple YAML files, in any/many languages.
|
* Define tour content with simple YAML files, in any/many languages.
|
||||||
* Organize tours by controller and action.
|
* Organize tours by controller and action.
|
||||||
* Trigger tours automatically on page load or manually via JavaScript method.
|
* Plays nicely with Turbolinks.
|
||||||
* Built with the [Shepherd JS](https://shepherdjs.dev/) library. Plays nicely with Turbolinks.
|
* Ships with two basic CSS themes (default & dark) -- or write your own
|
||||||
* Ships with two basic CSS themes (default & dark) — or write your own
|
|
||||||
* Show video/html content in your
|
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
* Walter needs to know the current user to track tour views, e.g. `current_user` from Devise.
|
* Abraham needs to know the current user to track tour views, e.g. `current_user` from Devise.
|
||||||
* Walter is tested on Rails 5.2, 6.0, and 6.1
|
* Abraham is tested on Rails 5.2, 6.0, and 6.1
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
Add `walter` to your Gemfile:
|
Add `abraham` to your Gemfile:
|
||||||
|
|
||||||
```
|
```
|
||||||
gem 'walter'
|
gem 'abraham'
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -36,34 +31,34 @@ Install the gem and run the installer:
|
|||||||
|
|
||||||
```
|
```
|
||||||
$ bundle install
|
$ bundle install
|
||||||
$ rails generate walter:install
|
$ rails generate abraham:install
|
||||||
$ rails db:migrate
|
$ rails db:migrate
|
||||||
```
|
```
|
||||||
|
|
||||||
Install the JavaScript dependencies:
|
Install the JavaScript dependencies:
|
||||||
|
|
||||||
```
|
```
|
||||||
$ yarn add js-cookie@^2.2.0 shepherd.js@^6.0.0-beta
|
$ yarn add jquery@^3.4.0 js-cookie@^2.2.0 shepherd.js@^6.0.0-beta
|
||||||
```
|
```
|
||||||
|
|
||||||
Require `walter` in `app/assets/javascripts/application.js`
|
Require `abraham` in `app/assets/javascripts/application.js`
|
||||||
|
|
||||||
```
|
```
|
||||||
//= require walter
|
//= require abraham
|
||||||
```
|
```
|
||||||
|
|
||||||
Require a CSS theme in `app/assets/stylesheets/application.scss`
|
Require a CSS theme in `app/assets/stylesheets/application.scss`
|
||||||
|
|
||||||
```
|
```
|
||||||
*= require walter/theme-default
|
*= require abraham/theme-default
|
||||||
```
|
```
|
||||||
|
|
||||||
Walter provides the following themes:
|
Abraham provides the following themes:
|
||||||
|
|
||||||
- `theme-default`
|
- `theme-default`
|
||||||
- `theme-dark`
|
- `theme-dark`
|
||||||
|
|
||||||
Update `config/walter.yml` if you choose a different theme:
|
Update `config/abraham.yml` if you choose a different theme:
|
||||||
|
|
||||||
```
|
```
|
||||||
defaults: &defaults
|
defaults: &defaults
|
||||||
@ -72,25 +67,22 @@ defaults: &defaults
|
|||||||
|
|
||||||
You can also [write your own Shepherd theme](https://shepherdjs.dev/docs/tutorial-03-styling.html) based on Shepherd's [default CSS](https://github.com/shipshapecode/shepherd/releases/download/v6.0.0-beta.1/shepherd.css).
|
You can also [write your own Shepherd theme](https://shepherdjs.dev/docs/tutorial-03-styling.html) based on Shepherd's [default CSS](https://github.com/shipshapecode/shepherd/releases/download/v6.0.0-beta.1/shepherd.css).
|
||||||
|
|
||||||
Tell Walter where to insert its generated JavaScript in `app/views/layouts/application.html.erb`, just before the closing `body` tag:
|
Tell Abraham where to insert its generated JavaScript in `app/views/layouts/application.html.erb`, just before the closing `body` tag:
|
||||||
|
|
||||||
```erb
|
```erb
|
||||||
<%= walter_tour %>
|
<%= abraham_tour %>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
```
|
```
|
||||||
|
|
||||||
## Defining your tours
|
## Defining your tours
|
||||||
|
|
||||||
Define your tours in the `app/tours` directory corresponding to the views defined in your application. Its directory structure mirrors your application's controllers, and the tour files mirror your actions/views. (As of version 2.4.0, Walter respects controllers organized into modules.)
|
Define your tours in the `config/tours` directory. Its directory structure should mirror your application's controllers, and the tour files should mirror your actions/views.
|
||||||
|
|
||||||
```
|
```
|
||||||
app/
|
config/
|
||||||
└── tours/
|
└── tours/
|
||||||
├── admin/
|
└── blog/
|
||||||
│ └── articles/
|
|
||||||
│ └── edit.en.yml
|
|
||||||
├── blog/
|
|
||||||
│ ├── show.en.yml
|
│ ├── show.en.yml
|
||||||
│ └── show.es.yml
|
│ └── show.es.yml
|
||||||
└── articles/
|
└── articles/
|
||||||
@ -100,15 +92,11 @@ app/
|
|||||||
└── show.es.yml
|
└── show.es.yml
|
||||||
```
|
```
|
||||||
|
|
||||||
For example, per above, when a Spanish-speaking user visits `/articles/`, they'll see the tours defined by `config/tours/articles/index.es.yml`.
|
NB: You must specify a locale in the filename, even if you're only supporting one language.
|
||||||
|
|
||||||
(Note: You must specify a locale in the filename, even if you're only supporting one language.)
|
|
||||||
|
|
||||||
### Tour content
|
### Tour content
|
||||||
|
|
||||||
Within a tour file, each tour is composed of a series of **steps**. A step may have a `title` and must have `text`. You may attach a step to a particular element on the page, and place the callout in a particular position.
|
A tour is composed of a series of steps. A step may have a title and must have a description. You may attach a step to a particular element on the page, and place the callout in a particular position (see below).
|
||||||
|
|
||||||
In this example, we define a tour called "intro" with 3 steps:
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
intro:
|
intro:
|
||||||
@ -129,10 +117,10 @@ intro:
|
|||||||
placement: "bottom"
|
placement: "bottom"
|
||||||
```
|
```
|
||||||
|
|
||||||
Walter takes care of which buttons should appear with each step:
|
Abraham takes care of which buttons should appear with each step:
|
||||||
|
|
||||||
* "Later" and "Continue" buttons on the first step
|
* "Later" and "Continue" buttons on the first step
|
||||||
* "Exit", "Back" and "Continue" buttons on intermediate steps
|
* "Exit" and "Next" buttons on intermediate steps
|
||||||
* "Done" button on the last step
|
* "Done" button on the last step
|
||||||
|
|
||||||
When you specify an `attachTo` element, use the `placement` option to choose where the callout should appear relative to that element:
|
When you specify an `attachTo` element, use the `placement` option to choose where the callout should appear relative to that element:
|
||||||
@ -141,59 +129,113 @@ When you specify an `attachTo` element, use the `placement` option to choose whe
|
|||||||
* `bottom left`
|
* `bottom left`
|
||||||
* `bottom right`
|
* `bottom right`
|
||||||
* `center` / `middle` / `middle center`
|
* `center` / `middle` / `middle center`
|
||||||
* `left` / `middle left`
|
* `left` / `middle left'
|
||||||
* `right` / `middle right`
|
* `right` / `middle right`
|
||||||
* `top` / `top center`
|
* `top` / `top center`
|
||||||
* `top left`
|
* `top left`
|
||||||
* `top right`
|
* `top right`
|
||||||
|
|
||||||
Walter tries to be helpful when your tour steps attach to page elements that are missing:
|
Abraham tries to be helpful when your tour steps attach to page elements that are missing:
|
||||||
|
|
||||||
* If your first step is attached to a particular element, and that element is not present on the page, the tour won't start. ([#28](https://github.com/actmd/walter/issues/28))
|
* If your first step is attached to a particular element, and that element is not present on the page, the tour won't start. ([#28](https://github.com/actmd/abraham/issues/28))
|
||||||
* If your tour has an intermediate step attached to a missing element, Walter will skip that step and automatically show the next. ([#6](https://github.com/actmd/walter/issues/6))
|
* If your tour has an intermediate step attached to a missing element, Abraham will skip that step and automatically show the next. ([#6](https://github.com/actmd/abraham/issues/6))
|
||||||
|
|
||||||
### Automatic vs. manual tours
|
|
||||||
|
|
||||||
By default, Walter will automatically start a tour that the current user hasn't seen yet.
|
|
||||||
You can instead define a tour to be triggered manually using the `trigger` option:
|
|
||||||
|
|
||||||
```yml
|
|
||||||
walkthrough:
|
|
||||||
trigger: "manual"
|
|
||||||
steps:
|
|
||||||
1:
|
|
||||||
text: "This walkthrough will show you how to..."
|
|
||||||
```
|
|
||||||
|
|
||||||
This tour will not start automatically; instead, use the `Walter.startTour` method with the tour name:
|
|
||||||
|
|
||||||
```
|
|
||||||
<button id="startTour">Start tour</button>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
document.querySelector("#startTour").addEventListener("click", function() {
|
|
||||||
Walter.startTour("walkthrough"));
|
|
||||||
});
|
|
||||||
</script>
|
|
||||||
```
|
|
||||||
|
|
||||||
...or if you happen to use jQuery:
|
|
||||||
|
|
||||||
```
|
|
||||||
<script>
|
|
||||||
$("#startTour").on("click", function() { Walter.startTour('walkthrough'); })
|
|
||||||
</script>
|
|
||||||
```
|
|
||||||
|
|
||||||
### Testing your tours
|
### Testing your tours
|
||||||
|
|
||||||
Walter loads tour definitions once when you start your server. Restart your server to see tour changes.
|
Abraham loads tour definitions once when you start your server. Restart your server to see tour changes.
|
||||||
|
|
||||||
If you'd like to run JavaScript integrations tests without the Walter tours getting in the way, clear the Walter configuration in your test helper, e.g.
|
If you'd like to run JavaScript integrations tests without the Abraham tours getting in the way, clear the Abraham configuration in your test helper, e.g.
|
||||||
|
|
||||||
```
|
```
|
||||||
Rails.application.configure do
|
Rails.application.configure do
|
||||||
config.walter.tours = {}
|
config.abraham.tours = {}
|
||||||
end
|
end
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Full example
|
||||||
|
|
||||||
|
We provide a [small example app](https://github.com/actmd/abraham-example) that implements abraham, so you can see it in action.
|
||||||
|
|
||||||
|
## Upgrading from version 1
|
||||||
|
|
||||||
|
Abraham v1 was built using Shepherd 1.8, v2 now uses Shepherd 6 -- quite a jump, yes.
|
||||||
|
|
||||||
|
If you were using Abraham v1, you'll want to take the following steps to upgrade:
|
||||||
|
|
||||||
|
1. Update your gem to the latest version
|
||||||
|
1. Fix your yarn dependencies to use the right versions
|
||||||
|
1. Shepherd no longer provides a set of themes. Abraham maintains two of the legacy themes: default and dark. You'll want to choose one of those or migrate your theme to the new Shepherd structure.
|
||||||
|
1. Abraham now exposes the entire Shepherd configuration object, so your `abraham.yml` file should now fully define the `tour_options` value instead of `default_theme`
|
||||||
|
1. There's been a slight change to `initializers/abraham.rb`. Replace yours with [the latest](https://github.com/actmd/abraham/blob/master/lib/generators/abraham/templates/initializer.rb).
|
||||||
|
|
||||||
|
If you have any trouble at all, please [submit an issue](https://github.com/actmd/abraham/issues) for assistance!
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
Contributions are welcome!
|
||||||
|
|
||||||
|
Create a feature branch (using git-flow) and submit as a pull request (with a base branch of `develop`).
|
||||||
|
|
||||||
|
Everyone interacting in Abraham's codebase, issue tracker, etc. is expected to follow the [Contributor Covenent Code of Conduct](https://www.contributor-covenant.org/version/1/4/code-of-conduct).
|
||||||
|
|
||||||
|
### Getting started with the source code
|
||||||
|
|
||||||
|
Abraham uses `rvm` with a gemset to ensure the appropriate version of Ruby and its dependencies. Make sure that's installed before you get started.
|
||||||
|
|
||||||
|
```
|
||||||
|
~ git clone git@github.com:actmd/abraham.git
|
||||||
|
Cloning into 'abraham'...
|
||||||
|
~ cd abraham
|
||||||
|
ruby-2.5.3 - #gemset created /Users/jon/.rvm/gems/ruby-2.5.3@abraham
|
||||||
|
ruby-2.5.3 - #generating abraham wrappers - please wait
|
||||||
|
~ bundle install
|
||||||
|
Bundle complete! 13 Gemfile dependencies, 73 gems now installed.
|
||||||
|
Use `bundle info [gemname]` to see where a bundled gem is installed.
|
||||||
|
~ yarn install
|
||||||
|
```
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
#### Testing locally
|
||||||
|
|
||||||
|
This Rails engine contains a test app called `dummy` with controller and system tests. They'll all get run with `rails t`.
|
||||||
|
|
||||||
|
Please note that if you change anything in the `lib/generators` folder (i.e. configuration, intializer, migration) you'll need to migrate the `dummy` app accordingly.
|
||||||
|
|
||||||
|
Final testing should be done in a standalone Rails app, following the README instructions.
|
||||||
|
|
||||||
|
To install the `abraham` gem with a local path:
|
||||||
|
|
||||||
|
```
|
||||||
|
gem 'abraham', path: '~/Workspace/abraham'
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Automated testing
|
||||||
|
|
||||||
|
We use TravisCI to automatically test this engine with Rails 5.2, 6.0, and 6.1. For test history, venture over to [TravisCI](https://travis-ci.com/actmd/abraham).
|
||||||
|
|
||||||
|
### Releasing
|
||||||
|
|
||||||
|
Create a git-flow release:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ git flow release start VERSION_NUMBER
|
||||||
|
```
|
||||||
|
|
||||||
|
Edit `lib/abraham/version.rb` and increase the version number.
|
||||||
|
|
||||||
|
Build the gem and push to Rubygems:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ rake build
|
||||||
|
$ gem push pkg/abraham-VERSION_NUMBER.gem
|
||||||
|
```
|
||||||
|
|
||||||
|
Finish the git-flow release and push to GitHub:
|
||||||
|
|
||||||
|
```
|
||||||
|
$ git flow release finish
|
||||||
|
$ git push origin develop
|
||||||
|
$ git push origin master
|
||||||
|
$ git push --tags
|
||||||
|
```
|
||||||
|
2
Rakefile
2
Rakefile
@ -10,7 +10,7 @@ require "rdoc/task"
|
|||||||
|
|
||||||
RDoc::Task.new(:rdoc) do |rdoc|
|
RDoc::Task.new(:rdoc) do |rdoc|
|
||||||
rdoc.rdoc_dir = "rdoc"
|
rdoc.rdoc_dir = "rdoc"
|
||||||
rdoc.title = "Walter"
|
rdoc.title = "Abraham"
|
||||||
rdoc.options << "--line-numbers"
|
rdoc.options << "--line-numbers"
|
||||||
rdoc.rdoc_files.include("README.md")
|
rdoc.rdoc_files.include("README.md")
|
||||||
rdoc.rdoc_files.include("lib/**/*.rb")
|
rdoc.rdoc_files.include("lib/**/*.rb")
|
||||||
|
@ -3,16 +3,17 @@
|
|||||||
$LOAD_PATH.push File.expand_path("lib", __dir__)
|
$LOAD_PATH.push File.expand_path("lib", __dir__)
|
||||||
|
|
||||||
# Maintain your gem's version:
|
# Maintain your gem's version:
|
||||||
require "walter/version"
|
require "abraham/version"
|
||||||
|
|
||||||
# Describe your gem and declare its dependencies:
|
# Describe your gem and declare its dependencies:
|
||||||
Gem::Specification.new do |s|
|
Gem::Specification.new do |s|
|
||||||
s.name = "walter"
|
s.name = "abraham"
|
||||||
s.version = Walter::VERSION
|
s.version = Abraham::VERSION
|
||||||
s.authors = ["Mike Sutton"]
|
s.authors = ["Jonathan Abbett"]
|
||||||
s.email = ["tech@wizewerx.com"]
|
s.email = ["jonathan@act.md"]
|
||||||
s.summary = "Application tours for Rails"
|
s.homepage = "https://github.com/actmd/abraham"
|
||||||
s.description = "Application tours for Rails"
|
s.summary = "Trackable application tours for Rails with i18n support, based on Shepherd.js."
|
||||||
|
s.description = "Trackable application tours for Rails with i18n support, based on Shepherd.js."
|
||||||
s.license = "MIT"
|
s.license = "MIT"
|
||||||
|
|
||||||
s.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.md"]
|
s.files = Dir["{app,config,db,lib}/**/*", "MIT-LICENSE", "Rakefile", "README.md"]
|
7
app/assets/javascripts/abraham/index.js
Normal file
7
app/assets/javascripts/abraham/index.js
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
//= require js-cookie/src/js.cookie
|
||||||
|
//= require shepherd.js/dist/js/shepherd
|
||||||
|
|
||||||
|
document.addEventListener('turbolinks:before-cache', function() {
|
||||||
|
// Remove visible product tours
|
||||||
|
document.querySelectorAll(".shepherd-element").forEach(function(el) { el.remove() });
|
||||||
|
});
|
@ -1,28 +0,0 @@
|
|||||||
//= require js-cookie/src/js.cookie
|
|
||||||
//= require shepherd.js/dist/js/shepherd
|
|
||||||
|
|
||||||
var Walter = new Object();
|
|
||||||
|
|
||||||
Walter.tours = {};
|
|
||||||
Walter.incompleteTours = [];
|
|
||||||
Walter.startTour = function(tourName) {
|
|
||||||
if (!Shepherd.activeTour) {
|
|
||||||
setTimeout(function(){Walter.tours[tourName].start()}, 300);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
Walter.startNextIncompleteTour = function() {
|
|
||||||
if (Walter.incompleteTours.length) {
|
|
||||||
Walter.tours[Walter.incompleteTours[0]].checkAndStart();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
document.addEventListener("DOMContentLoaded", Walter.startNextIncompleteTour);
|
|
||||||
document.addEventListener("turbolinks:load", Walter.startNextIncompleteTour);
|
|
||||||
|
|
||||||
document.addEventListener('turbolinks:before-cache', function() {
|
|
||||||
// Remove visible product tours
|
|
||||||
document.querySelectorAll(".shepherd-element").forEach(function(el) { el.remove() });
|
|
||||||
// Clear Walter data
|
|
||||||
Walter.tours = {};
|
|
||||||
Walter.incompleteTours = [];
|
|
||||||
});
|
|
@ -79,7 +79,7 @@
|
|||||||
border-top-right-radius: 5px;
|
border-top-right-radius: 5px;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: flex-end;
|
justify-content: flex-end;
|
||||||
padding: 0.5rem 0rem 0;
|
padding: 0.5rem 1rem 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.shepherd-has-title .shepherd-content .shepherd-header {
|
.shepherd-has-title .shepherd-content .shepherd-header {
|
||||||
@ -108,7 +108,7 @@
|
|||||||
.shepherd-element {
|
.shepherd-element {
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
box-shadow: 0 1px 4px rgba(0, 0, 0, .2);
|
box-shadow: 0 1px 4px rgba(0, 0, 0, .2);
|
||||||
//max-width: 600px;
|
max-width: 400px;
|
||||||
outline: none;
|
outline: none;
|
||||||
z-index: 9999;
|
z-index: 9999;
|
||||||
line-height: 1.2;
|
line-height: 1.2;
|
@ -1,117 +0,0 @@
|
|||||||
.shepherd-button:hover {
|
|
||||||
background: #16202D;
|
|
||||||
color: #ffffff;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-button.shepherd-button-secondary {
|
|
||||||
background: #CAD5D5;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-button.shepherd-button-secondary:hover {
|
|
||||||
color: #CAD5D5;
|
|
||||||
background: #16202D;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-cancel-icon {
|
|
||||||
font-family: "GT Pressura", sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-element {
|
|
||||||
border: solid 4px #16202D;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-element,
|
|
||||||
.shepherd-header,
|
|
||||||
.shepherd-footer {
|
|
||||||
border-radius: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-element .shepherd-arrow {
|
|
||||||
border-width: 0;
|
|
||||||
height: auto;
|
|
||||||
width: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-arrow::before {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-element .shepherd-arrow:after {
|
|
||||||
content: url('../assets/img/arrow.svg');
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-element[data-popper-placement^='top'] .shepherd-arrow,
|
|
||||||
.shepherd-element.shepherd-pinned-top .shepherd-arrow {
|
|
||||||
bottom: -35px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-element[data-popper-placement^='top'] .shepherd-arrow:after,
|
|
||||||
.shepherd-element.shepherd-pinned-top .shepherd-arrow:after {
|
|
||||||
transform: rotate(270deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-element[data-popper-placement^='bottom'] .shepherd-arrow {
|
|
||||||
top: -35px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-element[data-popper-placement^='bottom'] .shepherd-arrow:after {
|
|
||||||
transform: rotate(90deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-element[data-popper-placement^='left'] .shepherd-arrow,
|
|
||||||
.shepherd-element.shepherd-pinned-left .shepherd-arrow {
|
|
||||||
right: -35px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-element[data-popper-placement^='left'] .shepherd-arrow:after,
|
|
||||||
.shepherd-element.shepherd-pinned-left .shepherd-arrow:after {
|
|
||||||
transform: rotate(180deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-element[data-popper-placement^='right'] .shepherd-arrow,
|
|
||||||
.shepherd-element.shepherd-pinned-right .shepherd-arrow {
|
|
||||||
left: -35px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-footer {
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-footer button:not(:last-of-type) {
|
|
||||||
border-right: solid 4px #16202D;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-has-title .shepherd-content .shepherd-cancel-icon {
|
|
||||||
margin-top: -7px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-has-title .shepherd-content .shepherd-header {
|
|
||||||
background: transparent;
|
|
||||||
font-family: "GT Pressura", sans-serif;
|
|
||||||
padding-bottom: 0;
|
|
||||||
padding-left: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-has-title .shepherd-content .shepherd-header .shepherd-title {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-text {
|
|
||||||
font-size: 1.2rem;
|
|
||||||
padding: 2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-text a, .shepherd-text a:visited,
|
|
||||||
.shepherd-text a:active {
|
|
||||||
border-bottom: 1px dotted;
|
|
||||||
border-bottom-color: rgba(0, 0, 0, 0.75);
|
|
||||||
color: rgba(0, 0, 0, 0.75);
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.shepherd-text a:hover, .shepherd-text a:visited:hover,
|
|
||||||
.shepherd-text a:active:hover {
|
|
||||||
border-bottom-style: solid;
|
|
||||||
}
|
|
22
app/controllers/abraham_histories_controller.rb
Normal file
22
app/controllers/abraham_histories_controller.rb
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AbrahamHistoriesController < ApplicationController
|
||||||
|
def create
|
||||||
|
@abraham_history = AbrahamHistory.new(abraham_history_params)
|
||||||
|
@abraham_history.creator_id = current_user.id
|
||||||
|
respond_to do |format|
|
||||||
|
if @abraham_history.save
|
||||||
|
format.json { render json: @abraham_history, status: :created }
|
||||||
|
else
|
||||||
|
format.json { render json: @abraham_history.errors, status: :unprocessable_entity }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# Never trust parameters from the scary internet, only allow the white list through.
|
||||||
|
def abraham_history_params
|
||||||
|
params.require(:abraham_history).permit(:controller_name, :action_name, :tour_name)
|
||||||
|
end
|
||||||
|
end
|
@ -1,21 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class WalterHistoriesController < ApplicationController
|
|
||||||
def create
|
|
||||||
@walter_history = WalterHistory.new(walter_history_params)
|
|
||||||
@walter_history.creator_id = current_user.id
|
|
||||||
respond_to do |format|
|
|
||||||
if @walter_history.save
|
|
||||||
format.json { render json: @walter_history, status: :created }
|
|
||||||
else
|
|
||||||
format.json { render json: @walter_history.errors, status: :unprocessable_entity }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
private
|
|
||||||
|
|
||||||
def walter_history_params
|
|
||||||
params.require(:walter_history).permit(:controller_name, :action_name, :tour_name)
|
|
||||||
end
|
|
||||||
end
|
|
43
app/helpers/abraham_helper.rb
Normal file
43
app/helpers/abraham_helper.rb
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module AbrahamHelper
|
||||||
|
def abraham_tour
|
||||||
|
# Do we have tours for this controller/action in the user's locale?
|
||||||
|
tours = Rails.configuration.abraham.tours["#{controller_name}.#{action_name}.#{I18n.locale}"]
|
||||||
|
|
||||||
|
tours ||= Rails.configuration.abraham.tours["#{controller_name}.#{action_name}.#{I18n.default_locale}"]
|
||||||
|
|
||||||
|
if tours
|
||||||
|
completed = AbrahamHistory.where(
|
||||||
|
creator_id: current_user.id,
|
||||||
|
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/abraham",
|
||||||
|
locals: { tour_name: remaining.first,
|
||||||
|
steps: tours[remaining.first]["steps"] })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def abraham_cookie_prefix
|
||||||
|
"abraham-#{fetch_application_name.to_s.underscore}-#{current_user.id}-#{controller_name}-#{action_name}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def fetch_application_name
|
||||||
|
if Module.method_defined?(:module_parent)
|
||||||
|
Rails.application.class.module_parent
|
||||||
|
else
|
||||||
|
Rails.application.class.parent
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
def abraham_domain
|
||||||
|
request.host
|
||||||
|
end
|
||||||
|
end
|
@ -1,50 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
module WalterHelper
|
|
||||||
def walter_tour
|
|
||||||
# Do we have tours for this controller/action in the user's locale?
|
|
||||||
tours = Walter.tours["#{controller_path}.#{action_name}.#{I18n.locale}"]
|
|
||||||
# Otherwise, default to the default locale
|
|
||||||
tours ||= Walter.tours["#{controller_path}.#{action_name}.#{I18n.default_locale}"]
|
|
||||||
|
|
||||||
if tours
|
|
||||||
# Have any automatic tours been completed already?
|
|
||||||
completed = WalterHistory.where(
|
|
||||||
creator_id: current_user.id,
|
|
||||||
controller_name: controller_path,
|
|
||||||
action_name: action_name
|
|
||||||
)
|
|
||||||
|
|
||||||
tour_keys_completed = completed.map(&:tour_name)
|
|
||||||
tour_keys = tours.keys
|
|
||||||
|
|
||||||
tour_html = ''
|
|
||||||
|
|
||||||
tour_keys.each do |key|
|
|
||||||
tour_html += (render(partial: "application/shepherd",
|
|
||||||
locals: { tour_name: key,
|
|
||||||
tour_completed: tour_keys_completed.include?(key),
|
|
||||||
trigger: tours[key]["trigger"],
|
|
||||||
tour_delay: tours[key]['delay']||500,
|
|
||||||
steps: tours[key]["steps"] }))
|
|
||||||
end
|
|
||||||
tour_html.html_safe
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def walter_cookie_prefix
|
|
||||||
"walter-#{fetch_application_name.to_s.underscore}-#{current_user.id}-#{controller_path}-#{action_name}"
|
|
||||||
end
|
|
||||||
|
|
||||||
def fetch_application_name
|
|
||||||
if Module.method_defined?(:module_parent)
|
|
||||||
Rails.application.class.module_parent
|
|
||||||
else
|
|
||||||
Rails.application.class.parent
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def walter_domain
|
|
||||||
request.host
|
|
||||||
end
|
|
||||||
end
|
|
4
app/models/abraham_history.rb
Normal file
4
app/models/abraham_history.rb
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AbrahamHistory < ActiveRecord::Base
|
||||||
|
end
|
@ -1,4 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class WalterHistory < ActiveRecord::Base
|
|
||||||
end
|
|
68
app/views/application/_abraham.html.erb
Normal file
68
app/views/application/_abraham.html.erb
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
<script>
|
||||||
|
var tour = new Shepherd.Tour(<%= Rails.configuration.abraham.tour_options.html_safe unless Rails.configuration.abraham.tour_options.nil? %>);
|
||||||
|
|
||||||
|
tour.on("complete", function() {
|
||||||
|
// Make AJAX call to save history of tour completion
|
||||||
|
return fetch("/abraham_histories/", {
|
||||||
|
method: "POST",
|
||||||
|
headers: { 'Content-Type': 'application/json' },
|
||||||
|
body: JSON.stringify({
|
||||||
|
authenticity_token: '<%= form_authenticity_token %>',
|
||||||
|
controller_name: '<%= controller_name %>',
|
||||||
|
action_name: '<%= action_name %>',
|
||||||
|
tour_name: '<%= tour_name %>'
|
||||||
|
})
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
tour.on("cancel", function() {
|
||||||
|
Cookies.set('<%= abraham_cookie_prefix %>-<%= tour_name %>', 'later', { domain: '<%= abraham_domain %>' });
|
||||||
|
});
|
||||||
|
|
||||||
|
<% steps.each_with_index do |(key, step), index| %>
|
||||||
|
tour.addStep({
|
||||||
|
id: 'step-<%= key %>',
|
||||||
|
<% if step.key?('title') %>
|
||||||
|
title: "<%= step['title'] %>",
|
||||||
|
<% end %>
|
||||||
|
text: "<%= step['text'] %>",
|
||||||
|
<% if step.key?('attachTo') %>
|
||||||
|
attachTo: { element: "<%= step['attachTo']['element'] %>", on: "<%= step['attachTo']['placement'] %>" },
|
||||||
|
showOn: function() {
|
||||||
|
// Only display this step if its selector is present
|
||||||
|
return document.querySelector("<%= step['attachTo']['element'] %>") ? true : false
|
||||||
|
},
|
||||||
|
<% end %>
|
||||||
|
buttons: [
|
||||||
|
<% if index == 0 %>
|
||||||
|
{ text: '<%= t('abraham.later') %>', action: tour.cancel, classes: 'shepherd-button-secondary' },
|
||||||
|
{ text: '<%= t('abraham.continue') %>', action: tour.next }
|
||||||
|
<% else %>
|
||||||
|
<% if index == steps.size - 1 %>
|
||||||
|
{ text: '<%= t('abraham.done') %>', action: tour.complete }
|
||||||
|
<% else %>
|
||||||
|
{ text: '<%= t('abraham.exit') %>', action: tour.cancel, classes: 'shepherd-button-secondary' },
|
||||||
|
{ text: '<%= t('abraham.next') %>', action: tour.next }
|
||||||
|
<% end %>
|
||||||
|
<% end %>
|
||||||
|
]
|
||||||
|
});
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
tour.start = function (start) {
|
||||||
|
return function () {
|
||||||
|
// Don't start the tour if the user dismissed it once this session
|
||||||
|
var tourMayStart = !Cookies.get('<%= abraham_cookie_prefix %>-<%= tour_name %>', {domain: '<%= abraham_domain %>'});
|
||||||
|
<% if steps.first[1]['attachTo'] %>
|
||||||
|
// Don't start the tour if the first step's element is missing
|
||||||
|
tourMayStart = tourMayStart && document.querySelector("<%= steps.first[1]['attachTo']['element'] %>");
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
if (tourMayStart) {
|
||||||
|
start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}(tour.start)
|
||||||
|
|
||||||
|
tour.start()
|
||||||
|
</script>
|
@ -1,77 +0,0 @@
|
|||||||
<script>
|
|
||||||
Walter.tours["<%= tour_name %>"] = new Shepherd.Tour(<%= Rails.configuration.walter.tour_options.html_safe unless Rails.configuration.walter.tour_options.nil? %>);
|
|
||||||
|
|
||||||
<% if trigger != 'manual' %>
|
|
||||||
Walter.tours["<%= tour_name %>"].on("complete", function() {
|
|
||||||
// Make AJAX call to save history of tour completion
|
|
||||||
return fetch("/walter_histories/", {
|
|
||||||
method: "POST",
|
|
||||||
headers: { 'Content-Type': 'application/json' },
|
|
||||||
body: JSON.stringify({
|
|
||||||
authenticity_token: '<%= form_authenticity_token %>',
|
|
||||||
controller_name: '<%= controller_path %>',
|
|
||||||
action_name: '<%= action_name %>',
|
|
||||||
tour_name: '<%= tour_name %>'
|
|
||||||
})
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
Walter.tours["<%= tour_name %>"].on("cancel", function() {
|
|
||||||
Cookies.set('<%= walter_cookie_prefix %>-<%= tour_name %>', 'later', { domain: '<%= walter_domain %>' });
|
|
||||||
});
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<% steps.each_with_index do |(key, step), index| %>
|
|
||||||
Walter.tours["<%= tour_name %>"].addStep({
|
|
||||||
id: 'step-<%= key %>',
|
|
||||||
<% if step.key?('title') %>
|
|
||||||
title: "<%== step['title'] %>",
|
|
||||||
<% end %>
|
|
||||||
text: "<%== step['text'] %>",
|
|
||||||
<% if step.key?('attachTo') %>
|
|
||||||
attachTo: { element: "<%= step['attachTo']['element'] %>", on: "<%= step['attachTo']['placement'] %>" },
|
|
||||||
showOn: function() {
|
|
||||||
// Only display this step if its selector is present
|
|
||||||
return document.querySelector("<%= step['attachTo']['element'] %>") ? true : false
|
|
||||||
},
|
|
||||||
<% end %>
|
|
||||||
buttons: [
|
|
||||||
<% if index == steps.size - 1 %>
|
|
||||||
<% if steps.size > 1 %>
|
|
||||||
{ text: '<%= t('walter.back') %>', action: Walter.tours["<%= tour_name %>"].back, classes: 'shepherd-button-secondary' },
|
|
||||||
<% end %>
|
|
||||||
{ text: '<%= t('walter.done') %>', action: Walter.tours["<%= tour_name %>"].complete },
|
|
||||||
<% else %>
|
|
||||||
<% if index == 0 %>
|
|
||||||
{ text: '<%= t('walter.later') %>', action: Walter.tours["<%= tour_name %>"].cancel, classes: 'shepherd-button-secondary' },
|
|
||||||
<% else %>
|
|
||||||
{ text: '<%= t('walter.back') %>', action: Walter.tours["<%= tour_name %>"].back, classes: 'shepherd-button-secondary' },
|
|
||||||
<% end %>
|
|
||||||
{ text: '<%= t('walter.continue') %>', action: Walter.tours["<%= tour_name %>"].next },
|
|
||||||
<% end %>
|
|
||||||
]
|
|
||||||
});
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<% if trigger != "manual" %>
|
|
||||||
Walter.tours["<%= tour_name %>"].checkAndStart = function (start) {
|
|
||||||
return function () {
|
|
||||||
// Don't start the tour if the user dismissed it once this session
|
|
||||||
var tourMayStart = !Cookies.get('<%= walter_cookie_prefix %>-<%= tour_name %>', {domain: '<%= walter_domain %>'});
|
|
||||||
<% if steps.first[1]['attachTo'] %>
|
|
||||||
// Don't start the tour if the first step's element is missing
|
|
||||||
tourMayStart = tourMayStart && document.querySelector("<%= steps.first[1]['attachTo']['element'] %>");
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
if (tourMayStart) {
|
|
||||||
setTimeout(function(){start();}, <%= tour_delay %>); // need to delay this
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}(Walter.tours["<%= tour_name %>"].start)
|
|
||||||
|
|
||||||
<% if !tour_completed %>
|
|
||||||
Walter.incompleteTours.push("<%= tour_name %>");
|
|
||||||
<% end %>
|
|
||||||
<% end %>
|
|
||||||
|
|
||||||
</script>
|
|
@ -5,7 +5,7 @@
|
|||||||
# installed from the root of your application.
|
# installed from the root of your application.
|
||||||
|
|
||||||
ENGINE_ROOT = File.expand_path("..", __dir__)
|
ENGINE_ROOT = File.expand_path("..", __dir__)
|
||||||
ENGINE_PATH = File.expand_path("../lib/walter/engine", __dir__)
|
ENGINE_PATH = File.expand_path("../lib/abraham/engine", __dir__)
|
||||||
|
|
||||||
# Set up gems listed in the Gemfile.
|
# Set up gems listed in the Gemfile.
|
||||||
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
ENV["BUNDLE_GEMFILE"] ||= File.expand_path("../Gemfile", __dir__)
|
||||||
|
@ -1,8 +1,7 @@
|
|||||||
en:
|
en:
|
||||||
walter:
|
abraham:
|
||||||
later: "Later"
|
later: "Later"
|
||||||
continue: "Continue"
|
continue: "Continue"
|
||||||
exit: "Exit"
|
exit: "Exit"
|
||||||
done: "Done"
|
done: "Done"
|
||||||
next: "Next"
|
next: "Next"
|
||||||
back: "Back"
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
es:
|
es:
|
||||||
walter:
|
abraham:
|
||||||
later: "Luego"
|
later: "Luego"
|
||||||
continue: "Continuar"
|
continue: "Continuar"
|
||||||
exit: "Dejar"
|
exit: "Dejar"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
fr:
|
fr:
|
||||||
walter:
|
abraham:
|
||||||
later: "Plus tard"
|
later: "Plus tard"
|
||||||
continue: "Continuer"
|
continue: "Continuer"
|
||||||
exit: "Quitter"
|
exit: "Quitter"
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
Rails.application.routes.draw do
|
Rails.application.routes.draw do
|
||||||
resources :walter_histories, only: :create
|
resources :abraham_histories, only: :create
|
||||||
end
|
end
|
||||||
|
6
lib/abraham.rb
Normal file
6
lib/abraham.rb
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
require "abraham/engine"
|
||||||
|
|
||||||
|
module Abraham
|
||||||
|
end
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
require "rubygems"
|
require "rubygems"
|
||||||
|
|
||||||
module Walter
|
module Abraham
|
||||||
class Engine < ::Rails::Engine
|
class Engine < ::Rails::Engine
|
||||||
end
|
end
|
||||||
end
|
end
|
@ -1,5 +1,5 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Walter
|
module Abraham
|
||||||
VERSION = "2.5"
|
VERSION = "2.1.2"
|
||||||
end
|
end
|
@ -3,14 +3,13 @@
|
|||||||
require "rails/generators"
|
require "rails/generators"
|
||||||
require "rails/generators/active_record"
|
require "rails/generators/active_record"
|
||||||
|
|
||||||
module Walter
|
module Abraham
|
||||||
module Generators
|
module Generators
|
||||||
class InstallGenerator < ActiveRecord::Generators::Base
|
class InstallGenerator < ActiveRecord::Generators::Base
|
||||||
argument :name, type: :string, default: "random_name"
|
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-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"
|
class_option :'skip-initializer', type: :boolean, desc: "Don't generate an initializer"
|
||||||
class_option :'skip-config', type: :boolean, desc: "Don't generate a config file"
|
|
||||||
|
|
||||||
source_root File.expand_path(File.join(File.dirname(__FILE__), "templates"))
|
source_root File.expand_path(File.join(File.dirname(__FILE__), "templates"))
|
||||||
|
|
||||||
@ -18,19 +17,14 @@ module Walter
|
|||||||
def copy_files
|
def copy_files
|
||||||
return if options["skip-migration"]
|
return if options["skip-migration"]
|
||||||
|
|
||||||
migration_template "migration.rb", "db/migrate/create_walter_histories.rb"
|
migration_template "migration.rb", "db/migrate/create_abraham_histories.rb"
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_initializer
|
def create_initializer
|
||||||
return if options["skip-initializer"]
|
return if options["skip-initializer"]
|
||||||
|
|
||||||
copy_file "initializer.rb", "config/initializers/walter.rb"
|
copy_file "initializer.rb", "config/initializers/abraham.rb"
|
||||||
end
|
copy_file "abraham.yml", "config/abraham.yml"
|
||||||
|
|
||||||
def create_config
|
|
||||||
return if options["skip-config"]
|
|
||||||
|
|
||||||
copy_file "walter.yml", "config/walter.yml"
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
24
lib/generators/abraham/templates/initializer.rb
Normal file
24
lib/generators/abraham/templates/initializer.rb
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
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
|
||||||
|
|
||||||
|
abraham_config = Rails.application.config_for :abraham
|
||||||
|
config.abraham = ActiveSupport::OrderedOptions.new
|
||||||
|
config.abraham.tour_options = abraham_config[:tour_options]
|
||||||
|
config.abraham.tours = tours
|
||||||
|
end
|
@ -1,12 +1,12 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class CreateWalterHistories < ActiveRecord::Migration[5.0]
|
class CreateAbrahamHistories < ActiveRecord::Migration[5.0]
|
||||||
def change
|
def change
|
||||||
create_table :walter_histories do |t|
|
create_table :abraham_histories do |t|
|
||||||
t.string :controller_name
|
t.string :controller_name
|
||||||
t.string :action_name
|
t.string :action_name
|
||||||
t.string :tour_name
|
t.string :tour_name
|
||||||
t.string :creator_id, null: false, index: true
|
t.references :creator, null: false, index: true
|
||||||
|
|
||||||
t.timestamps index: true
|
t.timestamps index: true
|
||||||
end
|
end
|
@ -1,10 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
Rails.application.configure do
|
|
||||||
tours_path ="app/tours"
|
|
||||||
walter_config = Rails.application.config_for :walter
|
|
||||||
config.walter = ActiveSupport::OrderedOptions.new
|
|
||||||
config.walter.tour_options = walter_config[:tour_options]
|
|
||||||
config.walter.tours_path = tours_path
|
|
||||||
Walter::Tourguide.load_tours(tours_path)
|
|
||||||
end
|
|
@ -1,5 +1,5 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
# desc "Explaining what the task does"
|
# desc "Explaining what the task does"
|
||||||
# task :walter do
|
# task :abraham do
|
||||||
# # Task goes here
|
# # Task goes here
|
||||||
# end
|
# end
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require "walter/engine"
|
|
||||||
|
|
||||||
module Walter
|
|
||||||
require 'walter/tourguide'
|
|
||||||
|
|
||||||
def self.load_tours(tp=nil)
|
|
||||||
Walter::Tourguide.instance.load_tours(tp)
|
|
||||||
end
|
|
||||||
|
|
||||||
def self.tours
|
|
||||||
Walter::Tourguide.instance.tours
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,39 +0,0 @@
|
|||||||
module Walter
|
|
||||||
class Tourguide
|
|
||||||
include Singleton
|
|
||||||
@tours = {}
|
|
||||||
attr_accessor :reload
|
|
||||||
|
|
||||||
def initialize
|
|
||||||
super
|
|
||||||
@reload = true
|
|
||||||
end
|
|
||||||
|
|
||||||
def tours
|
|
||||||
load_tours
|
|
||||||
@tours
|
|
||||||
end
|
|
||||||
|
|
||||||
def load_tours(tours_path=nil)
|
|
||||||
return unless @reload
|
|
||||||
|
|
||||||
@tours = {}
|
|
||||||
tours_path ||= Rails.application.config.walter.tours_path
|
|
||||||
tours_root = Pathname.new(Rails.root.join(tours_path))
|
|
||||||
if Rails.root.join(tours_path).exist?
|
|
||||||
Dir.glob(Rails.root.join("#{tours_path}/**/*.yml")).each do |yml|
|
|
||||||
relative_filename = Pathname.new(yml).relative_path_from(tours_root)
|
|
||||||
# `controller_path` is either "controller_name" or "module_name/controller_name"
|
|
||||||
controller_path, filename = relative_filename.split
|
|
||||||
file_parts = filename.to_s.split(".")
|
|
||||||
action = file_parts[0]
|
|
||||||
locale = file_parts[1]
|
|
||||||
t = YAML.load_file(yml)
|
|
||||||
@tours["#{controller_path}.#{action}.#{locale}"] = t
|
|
||||||
end
|
|
||||||
end
|
|
||||||
puts "#{@tours.size} tours loaded"
|
|
||||||
@reload = ENV['WALTER_RELOAD_TOURS'].present? || Rails.env.development?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
@ -1,8 +1,8 @@
|
|||||||
{
|
{
|
||||||
"name": "walter",
|
"name": "abraham",
|
||||||
"private": true,
|
"private": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"js-cookie": "^2.2.0",
|
"js-cookie": "^2.2.0",
|
||||||
"shepherd.js": "^8.3.1"
|
"shepherd.js": "^6.0.0-beta"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
require "test_helper"
|
require "test_helper"
|
||||||
|
|
||||||
class Walter::Test < ActiveSupport::TestCase
|
class Abraham::Test < ActiveSupport::TestCase
|
||||||
test "truth" do
|
test "truth" do
|
||||||
assert_kind_of Module, Walter
|
assert_kind_of Module, Abraham
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -11,5 +11,5 @@
|
|||||||
// about supported directives.
|
// about supported directives.
|
||||||
//
|
//
|
||||||
//= require turbolinks
|
//= require turbolinks
|
||||||
//= require walter
|
//= require abraham
|
||||||
//= require_tree .
|
//= require_tree .
|
||||||
|
@ -10,6 +10,6 @@
|
|||||||
* files in this directory. Styles in this file should be added after the last require_* statement.
|
* 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.
|
* It is generally better to create a new file per style scope.
|
||||||
*
|
*
|
||||||
*= require walter/theme-default
|
*= require abraham/theme-default
|
||||||
*= require_tree .
|
*= require_tree .
|
||||||
*/
|
*/
|
@ -1,5 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
class Foobar::DashboardController < ApplicationController
|
|
||||||
def home; end
|
|
||||||
end
|
|
@ -1,26 +1,8 @@
|
|||||||
<h1>Dashboard#home</h1>
|
<h1>Dashboard#home</h1>
|
||||||
<p>Find me in app/views/dashboard/home.html.erb</p>
|
<p>Find me in app/views/dashboard/home.html.erb</p>
|
||||||
|
|
||||||
<%= link_to "Other Page", dashboard_other_url %>
|
|
||||||
|
|
||||||
<div class="notice-me" style="width:300px;height:300px;background-color:whitesmoke;">
|
<div class="notice-me" style="width:300px;height:300px;background-color:whitesmoke;">
|
||||||
a content element to notice
|
a content element to notice
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<button id="restart_automatic">Restart the automatic tour</button>
|
<%= link_to "Other Page", dashboard_other_url %>
|
||||||
<button id="show_manual">Show manual tour</button>
|
|
||||||
<button id="show_another_manual">Show ANOTHER manual tour</button>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
document.querySelector("#restart_automatic").addEventListener("click", function() {
|
|
||||||
Walter.startTour("intro");
|
|
||||||
});
|
|
||||||
|
|
||||||
document.querySelector("#show_manual").addEventListener("click", function() {
|
|
||||||
Walter.startTour("a_manual_tour");
|
|
||||||
});
|
|
||||||
|
|
||||||
document.querySelector("#show_another_manual").addEventListener("click", function() {
|
|
||||||
Walter.startTour("another_manual_tour");
|
|
||||||
});
|
|
||||||
</script>
|
|
@ -1,4 +1,2 @@
|
|||||||
<h1>Dashboard#other</h1>
|
<h1>Dashboard#other</h1>
|
||||||
<p>Find me in app/views/dashboard/other.html.erb</p>
|
<p>Find me in app/views/dashboard/other.html.erb</p>
|
||||||
|
|
||||||
<%= link_to "Home Page", dashboard_home_url %>
|
|
@ -1,4 +0,0 @@
|
|||||||
<h1>Foobar::Dashboard#home</h1>
|
|
||||||
<p>Find me in app/views/foobar/dashboard/home.html.erb</p>
|
|
||||||
|
|
||||||
We should get a unique tour for this module, not the same one as Dashboard#home
|
|
@ -11,10 +11,6 @@
|
|||||||
<body>
|
<body>
|
||||||
<%= yield %>
|
<%= yield %>
|
||||||
|
|
||||||
<hr>
|
<%= abraham_tour %>
|
||||||
|
|
||||||
<p><em>current_user.id = <%= current_user.id %></em></p>
|
|
||||||
|
|
||||||
<%= walter_tour %>
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
@ -5,7 +5,7 @@ require_relative "boot"
|
|||||||
require "rails/all"
|
require "rails/all"
|
||||||
|
|
||||||
Bundler.require(*Rails.groups)
|
Bundler.require(*Rails.groups)
|
||||||
require "walter"
|
require "abraham"
|
||||||
|
|
||||||
module Dummy
|
module Dummy
|
||||||
class Application < Rails::Application
|
class Application < Rails::Application
|
||||||
|
@ -2,23 +2,23 @@
|
|||||||
|
|
||||||
Rails.application.configure do
|
Rails.application.configure do
|
||||||
tours = {}
|
tours = {}
|
||||||
tours_root = Pathname.new(Rails.root.join("config/tours"))
|
|
||||||
|
|
||||||
if Rails.root.join("config/tours").exist?
|
if Rails.root.join("config/tours").exist?
|
||||||
Dir.glob(Rails.root.join("config/tours/**/*.yml")).each do |yml|
|
Dir[Rails.root.join("config/tours/*/")].each do |dir|
|
||||||
relative_filename = Pathname.new(yml).relative_path_from(tours_root)
|
Dir[dir + "*.yml"].each do |yml|
|
||||||
# `controller_path` is either "controller_name" or "module_name/controller_name"
|
path_parts = yml.split(File::SEPARATOR)
|
||||||
controller_path, filename = relative_filename.split
|
controller = path_parts[path_parts.size - 2]
|
||||||
file_parts = filename.to_s.split(".")
|
file_parts = path_parts[path_parts.size - 1].split(".")
|
||||||
action = file_parts[0]
|
action = file_parts[0]
|
||||||
locale = file_parts[1]
|
locale = file_parts[1]
|
||||||
t = YAML.load_file(yml)
|
t = YAML.load_file(yml)
|
||||||
tours["#{controller_path}.#{action}.#{locale}"] = t
|
tours["#{controller}.#{action}.#{locale}"] = t
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
walter_config = Rails.application.config_for :walter
|
abraham_config = Rails.application.config_for :abraham
|
||||||
config.walter = ActiveSupport::OrderedOptions.new
|
config.abraham = ActiveSupport::OrderedOptions.new
|
||||||
config.walter.tour_options = walter_config[:tour_options]
|
config.abraham.tour_options = abraham_config[:tour_options]
|
||||||
config.walter.tours = tours
|
config.abraham.tours = tours
|
||||||
end
|
end
|
||||||
|
@ -6,9 +6,5 @@ Rails.application.routes.draw do
|
|||||||
get "dashboard/placement"
|
get "dashboard/placement"
|
||||||
get "dashboard/missing"
|
get "dashboard/missing"
|
||||||
|
|
||||||
namespace :foobar do
|
|
||||||
get "dashboard/home"
|
|
||||||
end
|
|
||||||
|
|
||||||
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
|
# For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html
|
||||||
end
|
end
|
||||||
|
@ -17,13 +17,3 @@ intro:
|
|||||||
attachTo:
|
attachTo:
|
||||||
element: ".notice-me"
|
element: ".notice-me"
|
||||||
placement: "right"
|
placement: "right"
|
||||||
a_manual_tour:
|
|
||||||
trigger: manual
|
|
||||||
steps:
|
|
||||||
1:
|
|
||||||
text: "You triggered the manual tour"
|
|
||||||
another_manual_tour:
|
|
||||||
trigger: manual
|
|
||||||
steps:
|
|
||||||
1:
|
|
||||||
text: "You triggered the OTHER manual tour"
|
|
@ -1,4 +0,0 @@
|
|||||||
module:
|
|
||||||
steps:
|
|
||||||
1:
|
|
||||||
text: "This tour should appear for the Foobar::DashboardController only"
|
|
@ -1,8 +1,8 @@
|
|||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class CreateWalterHistories < ActiveRecord::Migration[5.0]
|
class CreateAbrahamHistories < ActiveRecord::Migration[5.0]
|
||||||
def change
|
def change
|
||||||
create_table :walter_histories do |t|
|
create_table :abraham_histories do |t|
|
||||||
t.string :controller_name
|
t.string :controller_name
|
||||||
t.string :action_name
|
t.string :action_name
|
||||||
t.string :tour_name
|
t.string :tour_name
|
||||||
|
@ -12,16 +12,16 @@
|
|||||||
|
|
||||||
ActiveRecord::Schema.define(version: 2016_11_18_143752) do
|
ActiveRecord::Schema.define(version: 2016_11_18_143752) do
|
||||||
|
|
||||||
create_table "walter_histories", force: :cascade do |t|
|
create_table "abraham_histories", force: :cascade do |t|
|
||||||
t.string "controller_name"
|
t.string "controller_name"
|
||||||
t.string "action_name"
|
t.string "action_name"
|
||||||
t.string "tour_name"
|
t.string "tour_name"
|
||||||
t.integer "creator_id", null: false
|
t.integer "creator_id", null: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
t.index ["created_at"], name: "index_walter_histories_on_created_at"
|
t.index ["created_at"], name: "index_abraham_histories_on_created_at"
|
||||||
t.index ["creator_id"], name: "index_walter_histories_on_creator_id"
|
t.index ["creator_id"], name: "index_abraham_histories_on_creator_id"
|
||||||
t.index ["updated_at"], name: "index_walter_histories_on_updated_at"
|
t.index ["updated_at"], name: "index_abraham_histories_on_updated_at"
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
require "test_helper"
|
require "test_helper"
|
||||||
|
|
||||||
class WalterHistoriesControllerTest < ActionDispatch::IntegrationTest
|
class AbrahamHistoriesControllerTest < ActionDispatch::IntegrationTest
|
||||||
test "should create WalterHistory" do
|
test "should create AbrahamHistory" do
|
||||||
assert_difference ["WalterHistory.count"] do
|
assert_difference ["AbrahamHistory.count"] do
|
||||||
post walter_histories_url, as: :json, params: { walter_history: { action_name: "foo", controller_name: "bar", tour_name: "baz" } }
|
post abraham_histories_url, as: :json, params: { abraham_history: { action_name: "foo", controller_name: "bar", tour_name: "baz" } }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -13,7 +13,7 @@ class DashboardControllerTest < ActionDispatch::IntegrationTest
|
|||||||
|
|
||||||
test "uses configured shepherd configuration" do
|
test "uses configured shepherd configuration" do
|
||||||
# No options
|
# No options
|
||||||
Rails.configuration.walter.tour_options = nil
|
Rails.configuration.abraham.tour_options = nil
|
||||||
get dashboard_home_url
|
get dashboard_home_url
|
||||||
assert_response :success
|
assert_response :success
|
||||||
assert_select "body script" do |element|
|
assert_select "body script" do |element|
|
||||||
@ -22,7 +22,7 @@ class DashboardControllerTest < ActionDispatch::IntegrationTest
|
|||||||
end
|
end
|
||||||
|
|
||||||
# Custom options
|
# Custom options
|
||||||
Rails.configuration.walter.tour_options = '{ defaultStepOptions: { classes: "my-custom-class" } }'
|
Rails.configuration.abraham.tour_options = '{ defaultStepOptions: { classes: "my-custom-class" } }'
|
||||||
get dashboard_home_url
|
get dashboard_home_url
|
||||||
assert_select "body script" do |element|
|
assert_select "body script" do |element|
|
||||||
# Config-specified options passed into Tour()
|
# Config-specified options passed into Tour()
|
||||||
|
@ -1,15 +0,0 @@
|
|||||||
# frozen_string_literal: true
|
|
||||||
|
|
||||||
require "test_helper"
|
|
||||||
|
|
||||||
class Foobar::DashboardControllerTest < ActionDispatch::IntegrationTest
|
|
||||||
test "home should have home tour code" do
|
|
||||||
get foobar_dashboard_home_url
|
|
||||||
assert_response :success
|
|
||||||
|
|
||||||
assert_select "body script" do |element|
|
|
||||||
# it's the Foobar module home tour
|
|
||||||
assert element.text.include? "This tour should appear for the Foobar::DashboardController only"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
@ -3,7 +3,7 @@ require "application_system_test_case"
|
|||||||
class ToursTest < ApplicationSystemTestCase
|
class ToursTest < ApplicationSystemTestCase
|
||||||
setup do
|
setup do
|
||||||
@user_id = Random.rand(1..99999)
|
@user_id = Random.rand(1..99999)
|
||||||
@cookie_name = "walter-dummy-#{@user_id}-dashboard-home-intro"
|
@cookie_name = "abraham-dummy-#{@user_id}-dashboard-home-intro"
|
||||||
ApplicationController.any_instance.stubs(:current_user).returns(OpenStruct.new(id: @user_id))
|
ApplicationController.any_instance.stubs(:current_user).returns(OpenStruct.new(id: @user_id))
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -17,11 +17,6 @@ class ToursTest < ApplicationSystemTestCase
|
|||||||
assert_selector ".shepherd-button", text: "Continue"
|
assert_selector ".shepherd-button", text: "Continue"
|
||||||
find(".shepherd-button", text: "Continue").click
|
find(".shepherd-button", text: "Continue").click
|
||||||
|
|
||||||
# Now try to manually trigger another tour
|
|
||||||
find('#show_manual').click
|
|
||||||
# Even though we triggered another tour, it should not appear since one is already active
|
|
||||||
assert_selector ".shepherd-element", count: 1, visible: true
|
|
||||||
|
|
||||||
# Tour Step 2
|
# Tour Step 2
|
||||||
assert_selector ".shepherd-header", text: "ENGLISH This step has a title"
|
assert_selector ".shepherd-header", text: "ENGLISH This step has a title"
|
||||||
assert_selector ".shepherd-text", text: "ENGLISH This intermediate step has some text"
|
assert_selector ".shepherd-text", text: "ENGLISH This intermediate step has some text"
|
||||||
@ -45,17 +40,6 @@ class ToursTest < ApplicationSystemTestCase
|
|||||||
# Tour should not reappear on reload
|
# Tour should not reappear on reload
|
||||||
visit dashboard_home_url
|
visit dashboard_home_url
|
||||||
refute_selector ".shepherd-element"
|
refute_selector ".shepherd-element"
|
||||||
|
|
||||||
# Now start a manual tour
|
|
||||||
find('#show_manual').click
|
|
||||||
assert_selector ".shepherd-element", visible: true
|
|
||||||
assert_selector ".shepherd-text", text: "You triggered the manual tour"
|
|
||||||
assert_selector ".shepherd-button", text: "Done"
|
|
||||||
find(".shepherd-button", text: "Done").click
|
|
||||||
|
|
||||||
# Even though we finished the manual tour, we can start it again right away
|
|
||||||
find('#show_manual').click
|
|
||||||
assert_selector ".shepherd-element", visible: true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
test "mark a tour for Later and it will not come back in this session" do
|
test "mark a tour for Later and it will not come back in this session" do
|
||||||
@ -93,22 +77,4 @@ class ToursTest < ApplicationSystemTestCase
|
|||||||
# No tour should be visible, since the first step is invalid
|
# No tour should be visible, since the first step is invalid
|
||||||
refute_selector ".shepherd-element"
|
refute_selector ".shepherd-element"
|
||||||
end
|
end
|
||||||
|
|
||||||
test "page with two incomplete tours shows them on consecutive visits" do
|
|
||||||
# First tour should appear at first visit
|
|
||||||
visit dashboard_other_url
|
|
||||||
assert_selector ".shepherd-element", visible: true
|
|
||||||
assert_selector ".shepherd-header", text: "TOUR ONE step one ENGLISH"
|
|
||||||
find(".shepherd-button", text: "Done").click
|
|
||||||
|
|
||||||
# Second tour should appear at second visit
|
|
||||||
visit dashboard_other_url
|
|
||||||
assert_selector ".shepherd-element", visible: true
|
|
||||||
assert_selector ".shepherd-header", text: "TOUR TWO step one ENGLISH"
|
|
||||||
find(".shepherd-button", text: "Done").click
|
|
||||||
|
|
||||||
# Now no tours should appear since they're both done
|
|
||||||
visit dashboard_other_url
|
|
||||||
refute_selector ".shepherd-element"
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
require "test_helper"
|
require "test_helper"
|
||||||
require "rails/generators"
|
require "rails/generators"
|
||||||
require "generators/walter/install_generator"
|
require "generators/abraham/install_generator"
|
||||||
|
|
||||||
class InstallGeneratorTest < Rails::Generators::TestCase
|
class InstallGeneratorTest < Rails::Generators::TestCase
|
||||||
tests Walter::Generators::InstallGenerator
|
tests Abraham::Generators::InstallGenerator
|
||||||
destination File.expand_path("../tmp", __dir__)
|
destination File.expand_path("../tmp", __dir__)
|
||||||
|
|
||||||
setup :prepare_destination
|
setup :prepare_destination
|
||||||
@ -13,7 +13,7 @@ class InstallGeneratorTest < Rails::Generators::TestCase
|
|||||||
test "should generate a migration" do
|
test "should generate a migration" do
|
||||||
begin
|
begin
|
||||||
run_generator
|
run_generator
|
||||||
assert_migration "db/migrate/create_walter_histories"
|
assert_migration "db/migrate/create_abraham_histories"
|
||||||
ensure
|
ensure
|
||||||
FileUtils.rm_rf destination_root
|
FileUtils.rm_rf destination_root
|
||||||
end
|
end
|
||||||
@ -22,7 +22,7 @@ class InstallGeneratorTest < Rails::Generators::TestCase
|
|||||||
test "should skip the migration when told to do so" do
|
test "should skip the migration when told to do so" do
|
||||||
begin
|
begin
|
||||||
run_generator ["--skip-migration"]
|
run_generator ["--skip-migration"]
|
||||||
assert_no_migration "db/migrate/create_walter_histories"
|
assert_no_migration "db/migrate/create_abraham_histories"
|
||||||
ensure
|
ensure
|
||||||
FileUtils.rm_rf destination_root
|
FileUtils.rm_rf destination_root
|
||||||
end
|
end
|
||||||
@ -31,8 +31,8 @@ class InstallGeneratorTest < Rails::Generators::TestCase
|
|||||||
test "should generate an initializer" do
|
test "should generate an initializer" do
|
||||||
begin
|
begin
|
||||||
run_generator
|
run_generator
|
||||||
assert_file "config/initializers/walter.rb"
|
assert_file "config/initializers/abraham.rb"
|
||||||
assert_file "config/walter.yml"
|
assert_file "config/abraham.yml"
|
||||||
ensure
|
ensure
|
||||||
FileUtils.rm_rf destination_root
|
FileUtils.rm_rf destination_root
|
||||||
end
|
end
|
||||||
@ -41,7 +41,7 @@ class InstallGeneratorTest < Rails::Generators::TestCase
|
|||||||
test "should skip the initializer when told to do so" do
|
test "should skip the initializer when told to do so" do
|
||||||
begin
|
begin
|
||||||
run_generator ["--skip-initializer"]
|
run_generator ["--skip-initializer"]
|
||||||
assert_no_file "config/initializers/walter.rb"
|
assert_no_file "config/initializers/abraham.rb"
|
||||||
ensure
|
ensure
|
||||||
FileUtils.rm_rf destination_root
|
FileUtils.rm_rf destination_root
|
||||||
end
|
end
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
require "test_helper"
|
require "test_helper"
|
||||||
|
|
||||||
class WalterHistoryTest < ActiveSupport::TestCase
|
class AbrahamHistoryTest < ActiveSupport::TestCase
|
||||||
# test "the truth" do
|
# test "the truth" do
|
||||||
# assert true
|
# assert true
|
||||||
# end
|
# end
|
||||||
|
Loading…
x
Reference in New Issue
Block a user