I have a Cucumber Rails scenario using Scenario Outline
Scenario Outline: User can see the logo
Given I am on the <path>
Examples:
| focus_area | path |
| Homepage | root_path |
This has the steps of
Given (/^I am on the ([^"]*)$/) do |path|
visit path
end
When I run this the application attempts to go to /root_path by using this string in the address.
What I actually want is for the helper method to be called so that the path is obtained correctly.
Related
I have folder insider test/fixtures/schemas where I define some schemas that I use to validate the JSON response of some controllers like this:
test
|
|
controllers
|
|
....
fixtures
|
|
organizations.yml
|
|
schemas
|
|
clients
|
|
show.rb
|
|
organizations
...
the file under fixtures/schemas/client/show.rb looks like this:
module Clients
class Show < Dry::Validation::Contract
json do
required(:id).filled(:string)
required(:state).filled(:string)
...
it works fine and I can use this schema on my tests with Clients::Show but we also have a rubocop rule that enforces us to use compact module and class style like this:
class Clients::Show < Dry::Validation::Contract
but when I define it like this, I get a NameError
test/fixtures/schemas/client/show.rb:3:in `<top (required)>': uninitialized constant Client (NameError)
I find it weird that one structure works and the other doesn't. I read through the Zeitwerk manual but couldn't anything that would explain my problem, and tried different things like defining a client.rb file with an empty module but it didn't work.
Both versions are not the same.
module Clients
class Show
defines a module with the name Clients and a class Show in the namespace Clients. But
class Clients::Show
only defines a class Show in the namespace Clients. There isn't automatically a module with the name Clients defined in this case.
Given a list of paths:
* /costumers/1
* /home
* /do/something/action-name
How can check the corresponding controller for these without need do the real call?
Context:
I have a spreadsheet with many routes (exported from application analytic [New Relic]).
I'm try discover how routes doesn't are being called.
This check does not be does programmatically.
I'm using rails 4.2
Thank's
You would do this with rails routes which will list all routes, verb, controller, and method.
You can search for certain routes with -g. rails routes -g /costumers for example. Don't search for /costumers/1. The 1 is not part of the route, it is the ID of the Costumer to show. Something like /costumers/:id. If your version does not support -g, pipe the output to grep rake routes | grep /costumers or use your pager rake routes | less.
You can also visit http://localhost:3000/rails/info/routes
See Rails Routing from the Outside In for more.
I could not find a way to generate engines with nested namespaces under rails. Every time I do that, I basically have to edit and move around the generated files by hand.
Is there really no support for nested namespaces in rails? Seems unlikely.
At the company we namespace everything like this:
CompanyName::SerivceName::Module
So when I'm working on Service1, and making the engine which will be integrated into the app that customer support uses to play around with the users and data of that service on customer requests, I'd like to create that engine under
CompanyName::Serive1::CustomerSupport
However rails seems to be unable to do that.
Using rails plugin new a::b::blah is not accepted:
akovanm0:test avandra$ rails plugin new a::b::blah -T --dummy-path=spec/dummy --mountable --full --mountable
Invalid plugin name a::b::blah. Please give a name which use only alphabetic or numeric or "_" characters.
Specifying rails plugin new a/b/blah generates an engine, but has the same output as rails plugin new blah
Specifying rails plugin new a_b_blah generates an engine with the literal name a_b_blah, not namespaced. (and the actual name is camelcased to ABBlah)
What I'd like to achieve is an engine whose controllers, models and views are generated under the a::b::blah namespace, and it is mountable the same way.
I want all generated controllers to go under app/controllers/a/b/blah, the models to go under app/models/a/b/blah, and so on...
Is there a way to achieve this?
For anyone reading this in 2022, I believe later versions of Rails handle engine names with dashes as separate namespaces.
rails plugin new parent_engine-sub_engine --mountable
Will create the following engine.rb:
module ParentEngine
module SubEngine
class Engine < ::Rails::Engine
isolate_namespace ParentEngine::SubEngine
end
end
end
You need to create engine with mountable option enabled like this,
rails plugin new engine_name --mountable.
It will add isolate_namespace EngineName method call in lib/engine_name/engine.rb to isolate engine namespace.
I think you can't do that :(
EDIT: Look at the bottom of the answer, I have modified the rails plugin generator just to do it :)
If you look carefully to the source (https://github.com/rails/rails/blob/5f07366bed77116dbfbb5b98d1cdf6c61b3dfc9b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb#L299) you will see that the plugin name is just the basename of the destination folder.
def original_name
#original_name ||= File.basename(destination_root)
end
So if you write rails plugin new a/b/c then the plugin will be created at the a/b/c subfolder in your current folder but the name will be just c :(
If you override that original_name method to return a/b/c as desired then you will need to fight both the valid_const? method (https://github.com/rails/rails/blob/5f07366bed77116dbfbb5b98d1cdf6c61b3dfc9b/railties/lib/rails/generators/rails/plugin/plugin_generator.rb#L307) that validates the format name and accepts "only alphabetic or numeric or _ characters." and the templates that creates the modules.
def valid_const?
if original_name =~ /[^0-9a-zA-Z_]+/
raise Error, "Invalid plugin name #{original_name}. Please give a name which use only alphabetic or numeric or \"_\" characters."
elsif camelized =~ /^\d/
raise Error, "Invalid plugin name #{original_name}. Please give a name which does not start with numbers."
elsif RESERVED_NAMES.include?(name)
raise Error, "Invalid plugin name #{original_name}. Please give a name which does not match one of the reserved rails words."
elsif Object.const_defined?(camelized)
raise Error, "Invalid plugin name #{original_name}, constant #{camelized} is already in use. Please choose another plugin name."
end
end
I'm thinking on using a plugin template (http://edgeguides.rubyonrails.org/rails_application_templates.html) for my namespaced plugins instead :(
EDIT: I lied about what methods you would have to fight. It's not the name method, it's the templates
EDIT (II): I have modified the plugin_new folder so nested namespaces are allowed. You have it here: https://github.com/brenes/nested-plugin-generator
I would appreciate any feedback :)
Try https://github.com/T-Dnzt/Modular-Engine or create your own generator
I'm getting started with rspec, capybara, etc, and I want to do some test driven development in Rails.
The specification I'm working with has very precise definitions for the appearance of the headers and the footers, and I figure that these are a good place to start learning.
For the footer, I want to have the following rule:
If the user is logged in, then the header contains just a logo image. The logo image should be a link to the user's landing page, which is determined by the rights the user has. If the user is not logged in, then the image is not a link, and four other links should appear in the footer as well, in a table.
Coding this is actually fairly straightfoward in erb, but I'm trying to Do The Right Thing, and make a series of tests here. My problems is that I can't seem to be able to test whether or not an image is shown on the screen. I've read the rspec book, but I don't see where it says something like 'shows this image found in the assets directory.'
So my setup is, in the views/layouts directory,
_header.html.erb
_footer.html.erb
_shim.html.erb
application.html.erb
I would think that I could test the footer partial directly, using something like:
require "spec_helper"
describe "rendering views/layouts/_footer.html.erb" do
#from https://www.relishapp.com/rspec/rspec-rails/v/2-8/docs/view-specs/view-spec
it "shows the logo" do
render :template => "layouts/_footer.html.erb"
rendered.should =~ "/images/mainlogo.png"
end
describe "rendering views/layouts/_footer.html.erb as admin" do
before do
FactoryGirl.create(:admin_user)
end
it "links to landing from the logo"
render :template => "layouts/_footer.html.erb"
rendered.should contain("link/to/admin/landing")
end
end
#repeat landing tests for various user types
And then, in other pages, I can simply test for the presence of the footer itself using something like
it should contain("footer")
My problem is, I can't even get off the ground to check to see if the image has been shown, much less if the image matches the right one in the assets directory. What should I be doing here?
The above code for testing the presence of the image (just the first describe/it block, not the stuff with the 'as admin' or the 'should contain') gives me the following warning and error:
DEPRECATION WARNING: Passing a template handler in the template name is deprecated.
TypeError:
type mismatch: String given
The first is probably due to me using syntax I don't understand, but the second seems to suggest that the comparison is with strings rather than assets. What's the syntax to compare images? Is there one?
Your type mismatch error is because you're passing a string to =~ which is a regular expression matcher. You can either change the string to a regular expression, or use the include instead. I'd go with include just because it's more readable:
rendered.should include("/images/mainlogo.png")
To get rid of the deprecation warning, just remove the .erb from the template name:
render :template => "layouts/_footer.html"
I'm testing rails app with the Cucumber and Capybara/rack_test.
I have following step definition:
Then /^I should see '([^']*)'$/ do |content|
visit about_path
response.should have_content(content)
end
where about_path maps to /about.
Every time my story fails with the message
Feature: Some Great Feature
So that I can blah-blah
As a Blah-blah
I want blah-blah
Scenario: Show project label on about page # features/about.feature:7
Given I'm on '/about' page # features/step_definitions/about_steps.rb:1
Then I should see 'About' # features/step_definitions/about_steps.rb:5
expected there to be content "About" in "" (RSpec::Expectations::ExpectationNotMetError)
./features/step_definitions/about_steps.rb:7:in `/^I should see '([^']*)'$/'
features/about.feature:9:in `Then I should see 'About''
Failing Scenarios:
cucumber features/about.feature:7 # Scenario: Show project label on about page
1 scenario (1 failed)
2 steps (1 failed, 1 passed)
Note that actual content is empty. It is empty with every path I've tried.
It is strange because rspecs passes.
Is there anything I could try? Tell me if you need additional information.
You shouldn't use response to get to the content. Try with page instead.