I am having trouble getting my handlebars templates accessible in rails 3.1. I have the following controller:
Lead.Controllers.UrlSearch = Ember.Object.extend
init: ->
view = Ember.View.create
controller: #
urlSearchBinding: 'controller.url_search'
templateName: 'app/templates/url_search/show'
On the rails side of things, I have a the following initialisation script in config/initializers/sprockets.rb
require 'sprockets/ember_handlebars'
Rails.application.assets.register_engine 'hjs', EmberHandlebars
My EmberHandleBars looks like this:
require 'tilt'
require 'json'
class EmberHandlebars < Tilt::Template
def self.default_mime_type
"application/javascript"
end
def prepare
end
def evaluate(scope, locals, &block)
"Ember.TEMPLATES['#{scope.logical_path}'] = Ember.Handlebars.compile(#{data.to_json})"
end
end
Finally, the template is located in:
app/assets/javascripts/app/templates/url_search/show.jst.hjs
In there error console, I get this 404 resource error:
GET
http://localhost:3000/assets/app/templates/url_search/show.hjs.js?body=1
404 (Not Found)
and also
Error: - Unable to find template
"app/templates/url_search/show".
I am confused why it is looking for an hjs.js file when I have specified otherwise and why it cannot find the template.
Can anyone see what I am doing wrong?
Changing the file extensions form .jst.hjs to just .hjs fixed the problem.
Related
I love testing-library, have used it a lot in a React project, and I'm trying to use it in an Angular project now - but I've always struggled with the enormous error output, including the HTML text of the render. Not only is this not usually helpful (I couldn't find an element, here's the HTML where it isn't); but it gets truncated, often before the interesting line if you're running in debug mode.
I simply added it as a library alongside the standard Angular Karma+Jasmine setup.
I'm sure you could say the components I'm testing are too large if the HTML output causes my console window to spool for ages, but I have a lot of integration tests in Protractor, and they are SO SLOW :(.
I would say the best solution would be to use the configure method and pass a custom function for getElementError which does what you want.
You can read about configuration here: https://testing-library.com/docs/dom-testing-library/api-configuration
An example of this might look like:
configure({
getElementError: (message: string, container) => {
const error = new Error(message);
error.name = 'TestingLibraryElementError';
error.stack = null;
return error;
},
});
You can then put this in any single test file or use Jest's setupFiles or setupFilesAfterEnv config options to have it run globally.
I am assuming you running jest with rtl in your project.
I personally wouldn't turn it off as it's there to help us, but everyone has a way so if you have your reasons, then fair enough.
1. If you want to disable errors for a specific test, you can mock the console.error.
it('disable error example', () => {
const errorObject = console.error; //store the state of the object
console.error = jest.fn(); // mock the object
// code
//assertion (expect)
console.error = errorObject; // assign it back so you can use it in the next test
});
2. If you want to silence it for all the test, you could use the jest --silent CLI option. Check the docs
The above might even disable the DOM printing that is done by rtl, I am not sure as I haven't tried this, but if you look at the docs I linked, it says
"Prevent tests from printing messages through the console."
Now you almost certainly have everything disabled except the DOM recommendations if the above doesn't work. On that case you might look into react-testing-library's source code and find out what is used for those print statements. Is it a console.log? is it a console.warn? When you got that, just mock it out like option 1 above.
UPDATE
After some digging, I found out that all testing-library DOM printing is built on prettyDOM();
While prettyDOM() can't be disabled you can limit the number of lines to 0, and that would just give you the error message and three dots ... below the message.
Here is an example printout, I messed around with:
TestingLibraryElementError: Unable to find an element with the text: Hello ther. This could be because the text is broken up by multiple elements. In this case, you can provide a function for your text matcher to make your matcher more flexible.
...
All you need to do is to pass in an environment variable before executing your test suite, so for example with an npm script it would look like:
DEBUG_PRINT_LIMIT=0 npm run test
Here is the doc
UPDATE 2:
As per the OP's FR on github this can also be achieved without injecting in a global variable to limit the PrettyDOM line output (in case if it's used elsewhere). The getElementError config option need to be changed:
dom-testing-library/src/config.js
// called when getBy* queries fail. (message, container) => Error
getElementError(message, container) {
const error = new Error(
[message, prettyDOM(container)].filter(Boolean).join('\n\n'),
)
error.name = 'TestingLibraryElementError'
return error
},
The callstack can also be removed
You can change how the message is built by setting the DOM testing library message building function with config. In my Angular project I added this to test.js:
configure({
getElementError: (message: string, container) => {
const error = new Error(message);
error.name = 'TestingLibraryElementError';
error.stack = null;
return error;
},
});
This was answered here: https://github.com/testing-library/dom-testing-library/issues/773 by https://github.com/wyze.
currently I need to add log4js support in my test case, like below:
it(' QuestionController saveQuestion method Testing ', inject(function(localStorageService) {
***var log4js = require('log4js');
var logger = log4js.getLogger();
logger.debug("Some debug messages");***
expect({}).toEqual(localStorageService.get('questionInfoStorage'));
}));
I have tried to include the log4js js and repire js file in karma.conf.js file, it is not working and giving some error like "Module name "events" has not been loaded yet for context" something.
Is there anybody coming the same issue previously? thanks advance!
I am trying to migrate a project from 0.9.9 to 0.10.5
We were using dust templating engine in our porject instead of the default ejs engine.
Contents of config/views.js file
module.exports.views = {
engine: 'dust',
layout: 'layout'
};
In my controller, I was able to render this view like this
res.view('layout', obj);
However, in sails 0.10.5, when I lift sails, first of all I get this warning
warn: Sails' built-in layout support only works with the `ejs` view engine.
warn: You're using `dust`.
warn: Ignoring `sails.config.views.layout`...
And then when I try to render the view as I was doing earlier, I get following error:
error: Sending 500 ("Server Error") response:
Error: ENOENT, open '/.dust'
{ [Error: ENOENT, open '/.dust'] errno: 34, code: 'ENOENT', path: '/.dust' }
Any idea what is the correct way of doing this in 0.10.5 ?
The layout property does not apply to dust (just ejs). Set layout to false to get the warning to go away. You want to use Dust's built-in support for partials and blocks anyways.
Using res.view('layout', obj); means that you expect a file called views/layout.dust to exist. Prior to 0.10, sails was including the layout property from config/views.js as part of the path.
So my best guess is that your res.view() call is actually being invoked with an empty string as the first parameter, and it wasn't breaking because you were trying to render something called layout. I'd check your invocation to make sure that you're calling res.view() with an instantiated variable.
I'm working on a Sinatra project that's using Sprockets. When I add a new stylesheet in the assets folder, I get this error:
Error compiling CSS asset
Sprockets::NotImplementedError: Custom asset_path helper is not
implemented
Extend your environment context with a custom method.
environment.context_class.class_eval do
def asset_path(path, options = {})
end
end
What am I doing wrong?
I followed the error message's suggestion: I defined the asset_path method in config.ru:
environment.context_class.class_eval do
def asset_path(path, options = {})
"/assets/#{path}"
end
end
I'm still not sure why this is needed, but it made the error go away.
To fix the same error in Padrino, I defined this method in my app.rb and changed environment to assets:
assets.context_class.class_eval do
def asset_path(path, options = {})
"/assets/#{path}"
end
end
Has already proposed, you need to define the method asset_path for your environment.
This method is used by helpers like image_url, ... commonly used in CSS files. You might want to make it a little different depending on the options[:type] then.
Example:
environment.context_class.class_eval do
def asset_path(path, options = {})
if type = options[:type]
"/assets/#{type.to_s.pluralize}/#{path}"
else
"/assets/#{path}"
end
end
end
Doing so mill make the asset_url to return /assets/path/to/your/file while the image_url helper will return /assets/images/path/to/your/file
Don't we need an instance of sprockets call?
For a Rails app that I'm playing with I used this in the config.ru to get rid of the error.
map '/assets' do
environment = Sprockets::Environment.new
environment.context_class.class_eval do
def asset_path(path, options = {})
"app/assets/#{path}"
end
end
environment.append_path 'app/assets/javascripts'
environment.append_path 'app/assets/stylesheets'
run environment
end
I'm currently working on a Rails plugin used for generating iPhone specific HTML meta-tags. I'm trying to use ActionView::TestCase for unit tests but keep getting the same error. See file contents and error below. Any ideas or help would be much appreciated.
test_helper.rb
require 'rubygems'
require 'test/unit'
require 'active_support'
require 'action_view'
require File.join(File.dirname(__FILE__), '..', 'lib', 'iphone_helper')
iphone_test_helper.rb
require 'test_helper'
class IphoneHelperTest < ActionView::TestCase
test 'br' do
tag = tag('br')
assert_tag_in tag, '<br />'
end
end
error
RuntimeError: In order to use #url_for, you must include routing helpers explicitly. For instance, `include Rails.application.routes.url_helpers
Awful and hacky workaround that worked for me (since I am working on a gem and not in a full rails environment):
require 'ostruct'
module ActionController::UrlFor
def _routes
helpers = OpenStruct.new
helpers.url_helpers = Module.new
helpers
end
end
Did you try to include the respective Module in an old-fashioned way?:
include ActionDispatch::Routing::RouteSet
If a NameError is raised telling you that ActionDispatch is unknown you might have to require 'action_dispatch'.
Maybe a stupid question, but is the fact that the class name and the file name don't match possibly a problem (IphoneHelperTest vs. iphone_test_helper.rb)? Sometimes that leads to classes not being loaded.