I was not able to find any JSFiddle examples with Jasmine 2.2 so I decided to create my own. Despite including all the Jasmine JavaScript files it still complains that there are No Specs Found. What am I missing please?
http://jsfiddle.net/gfinzer/dgrwtc6k/3/
describe("Common tests", function() {
it("ExtractNumbers method should extract numbers from a string", function () {
expect(ExtractNumbers("Logan 5, Francis 7")).toBe("57");
});
});
function ExtractNumbers(text) {
if (!text)
return text;
return text.replace( /\D+/g, '');
}
Your code is right. Is just the setup for Fiddle. Use 'No wrap - in head'.
<html>
<head>
<title>Stuff</title>
<script>
/* your code */
</script>
</head>
http://jsfiddle.net/40xk6hfv/
Related
I am trying to open asp.net mvc view in jquery dialog.
Here is my view from where i am trying to open dialog:
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.11.0/jquery-ui.min.js"></script>
<script type="text/javascript">
$(function () {
$('#my-dialog').dialog({
autoOpen: false,
width: 400,
resizable: false,
modal: true
});
$('.modal').click(function () {
$('#my-dialog').load(this.href, function () {
$(this).dialog('open');
});
return false;
});
});
</script>
<div id="my-dialog"></div>
#Html.ActionLink("Add Question", "AddQuestionInPage", new { pageID = #ViewBag.PageID },new { #class = "modal" })
But it shows this error in console:
Uncaught TypeError: undefined is not a function
It show the error on this line:
$(this).dialog('open');
What is going wrong? why dialog is undefined as i have added jquery-ui file.
Plz guide me,
Thanx
This is one of the things you will experience when you got somekind of a mismatch between the path to the jQuery library or the order of ordering the references to the libraries you got.
Take a look at this, im sure it might be helpful: Uncaught TypeError: undefined is not a function on loading jquery-min.js
Finally I managed to open view in dialog by doing following things:
In Layout file I ordered the scripts in this way:
<script src="#Url.Content("~/Scripts/jquery-1.5.1.js")" type="text/javascript"></script>
<script src="#Url.Content("~/Scripts/jquery-ui-1.8.11.js")"></script>
as Karsten suggested, thanx Karsten your answer really helped!
And i replaced the following line:
$(this).dialog('open');
with this:
$('#my-dialog').dialog();
as ZippyV suggested in comment. Thanx ZippyV it helped!
Thanx. .
This code in a simple HTML file works:
<script>
function load() {
alert("load event detected!");
}
window.onload = load;
</script>
However, if I put it into the index.html file of an AngularJS web app, it does not. Does anybody know why not?
Call your function with ng-init
var app = angular.module('app',[]);
app.controller('myController', function($scope){
$scope.load = function () {
alert("load event detected!");
}
});
<script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<div ng-app='app'>
<div ng-controller='myController' ng-init='load()'></div>
</div>
I prefer putting this kind of code in the app.run() function of angular.
e.g.
angular
.module('testApp', ['someModule'])
.constant('aConstant', 'hi')
.config(function($rootProvider) {/*some routing here*/})
.run(['$window', function($window) {
$window.onload = function() {/*do your thing*/};
}]);
also check this nice post that depicts the order that some things happen in angular
AngularJS app.run() documentation?
the following should work:
jQuery(function(){ /** my window onload functions **/ })
since angular uses a subset of jquery anyways you also may include the real thing.
better yet:
Instead of using this, you may consider using the angular way of initialising things:
that would be: http://docs.angularjs.org/api/ng.directive:ngInit
< any ng-init="functionInController(something)"...
to make it invisible until init: http://docs.angularjs.org/api/ng.directive:ngCloak
< any ng-cloak .....
to initialise/customize whole parts: http://docs.angularjs.org/guide/directive
< any directive-name....
Try
angular.element($window).bind('load', function() {
});
Here is the test spec file:
describe('Test main controller', function(){
it('Should initialize value to Loading', function(){
$scope = {}
ctrl = new mainNavController($scope)
expect($scope.wksp_name).toBe('Loading')
})
})
Here is the controller file
function mainNavController($scope) {
$scope.wksp_name = 'Loading...'
$scope.$on('broadCastWkspNameEvent', function (e, args) {
$scope.wksp_name = args
})
}
mainNavController.$inject=['$scope']
But my test fails saying Object #<Object> has no method '$on'
I am using the basic setup of jasmine.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<title>Jasmine Spec Runner</title>
<link rel="shortcut icon" type="image/png" href="testlib/jasmine-1.2.0/jasmine_favicon.png">
<link rel="stylesheet" type="text/css" href="testlib/jasmine-1.2.0/jasmine.css">
<script type="text/javascript" src="testlib/jasmine-1.2.0/jasmine.js"></script>
<script type="text/javascript" src="testlib/jasmine-1.2.0/jasmine-html.js"></script>
<!-- include source files here... -->
<script type="text/javascript" src="/static_files/js/test-specs/main-nav-spec.js"></script>
<!-- include spec files here... -->
<script type="text/javascript" src="/static_files/js/common/jquery/latest.js"></script>
<script type="text/javascript" src="/static_files/js/common/angular/angular-1.0.1.min.js"></script>
<script type="text/javascript" src="/static_files/js/common/angular/angular-resource-1.0.1.min.js"></script>
<script type="text/javascript" src="/static_files/js/section/main-nav-controller.js"></script>
<script type="text/javascript">
(function() {
var jasmineEnv = jasmine.getEnv();
jasmineEnv.updateInterval = 1000;
var htmlReporter = new jasmine.HtmlReporter();
jasmineEnv.addReporter(htmlReporter);
jasmineEnv.specFilter = function(spec) {
return htmlReporter.specFilter(spec);
};
var currentWindowOnload = window.onload;
window.onload = function() {
if (currentWindowOnload) {
currentWindowOnload();
}
execJasmine();
};
function execJasmine() {
jasmineEnv.execute();
}
})();
</script>
</head>
<body>
</body>
</html>
What is it that I am doing wrong? I am not able to understand how this thing is supposed to work :)
The main problem with your test code is that it tries to create a controller's instance "by hand" using the new operator. When doing so AngularJS has no chance to inject dependencies. What you should be doing is to allow AngularJS inject dependencies:
var $scope, ctrl;
//you need to inject dependencies first
beforeEach(inject(function($rootScope) {
$scope = $rootScope.$new();
}));
it('Should initialize value to Loading', inject(function($controller) {
ctrl = $controller('MainNavController', {
$scope: $scope
});
expect($scope.wksp_name).toBe('Loading...');
}));
Here is the link to a complete jsFiddle: http://jsfiddle.net/pkozlowski_opensource/7a7KR/3/
There are 2 things worth noting in the above example:
You can use the inject() method from the ngMock module to inject dependencies: https://docs.angularjs.org/api/ngMock/function/angular.mock.inject
To create a controller instance (that supports dependency injection) you would use the $controller service: http://docs.angularjs.org/api/ng.$controller
As the last remark: I would advise naming controllers starting with an uppercase letter - this way we won't confuse them with variable names.
Great answer by #pkozlowski.opensource. To elaborate a bit more... Sometimes it could be also handy to assert that $scope.$on was really called by your controller. In this case you can spy on $scope.$on as pointed out below:
beforeEach(inject(function($rootScope) {
$scope = $rootScope.$new();
spyOn($scope, '$on').andCallThrough();
}));
And then you can assert that $on was called with your event name and some function as arguments:
it('Should bind to "broadCastWkspNameEvent"', inject(function($controller) {
ctrl = $controller('MainNavController', {
$scope: $scope
});
expect($scope.$on).toHaveBeenCalledWith('broadCastWkspNameEvent', jasmine.any(Function));
}));
I agree with pkozowski's response, but to answer your question more directly, you need to stub out '$on'
Your example would pass if your $scope looked like:
$scope = {
$on: function() {}
}
My html document looks like this:
<html>
<head> .. load jquery and other stuff </head>
<body>
<div id="cool_container">
<div class="cool">.. no script friendly markup ..</div>
</div>
<a id="cool_link">Link</a>
<script>
function installStuff(){
$('.cool').coolPlugin();
$('#cool_link').click(function(){
$('#cool_container').load('/anothercooldiv.html');
});
}
$(document).load(function(){ installStuff(); });
</script>
</body>
</html>
Of course, /anothercooldiv.html gives another <div class="cool"> .. etc ...</div> fragment.
So what's the best way to turn the fresh cool div into a coolPlugin without breaking everything (and writing some nasty hacks) ?
It'd would be great to be able to either:
Call installStuff with a default jQuery context '#cool_container', so I could call something like:
$.doThisInContext(function(){installStuff();}, $('#cool_container');
In the load callback.
Or, have an equivalent of 'live' (that would solve the problem of links if cool contains links), but on an element existence, that I could use like that in my function installStuff:
$('.cool').exists(function(what){ what.coolPlugin() };
Then the coolPlugin would be installed on all cool elements now and in the future.
I'd suggest the .livequery() plugin for this still:
$(function() {
$('.cool').livequery(function() {
$(this).coolPlugin();
});
$('#cool_link').click(function(){
$('#cool_container').load('/anothercooldiv.html');
});
});
The important bit:
$('.cool').livequery(function() {
$(this).coolPlugin();
});
Will run for every current and future .cool element as they're added, running the plugin on each.
Applying the plugin to the newly ajax loaded content shouldn't be too tricky:
$('#cool_container').load('/anothercooldiv.html', function() {
$(this).coolPlugin();
});
I was today seeking the net for information about textbox-validation, but even on Dojo-Homepage I couldn't get any useful information.
My problem: I've got a NumberSpinner, in which only numbers in steps of ten (10, 20, 30, ...) should be allowed. But I've got no idea how to set a validator for this. In the 'constraints'-statement there seems to be no possibility to do this. And I don't know how to use the validator-function so that the box shows me warning sign immediately when typing in somethin wrong.
Another question is how to check if any part of a form is not valid before sending it. Is there an attribute in every input/select-box like 'valid' to check them all at once?
Oh, one hint, I create all widgets programmatically.
Hopefully anyone out there can help me!!!
Best regards,
Robin
You can override the NumberSpinner's isValid() method. For example:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>class</title>
<link rel="stylesheet" href="http://ajax.googleapis.com/ajax/libs/dojo/1.3/dijit/themes/soria/soria.css" />
<script src="http://ajax.googleapis.com/ajax/libs/dojo/1.3/dojo/dojo.xd.js"></script>
<script type="text/javascript">
dojo.config.parseOnLoad = true;
dojo.addOnLoad(function() {
dojo.require('dijit.form.NumberSpinner');
dojo.require('dojo.parser');
dojo.addOnLoad(function() {
new dijit.form.NumberSpinner({
isValid: function(isFocused) {
var value = parseFloat(this.attr('value'));
if (isNaN(value) || (value % 10 != 0)) {
return false;
} else {
return true;
}
}
}, 'here');
});
});
</script>
</head>
<body class="soria">
<div id="here"></div>
</body>
</html>
dijit.form.NumberSpinner is derived from dijit.form.ValidationTextBox, and as such it would accept the same arguments (see dijit.form.ValidationTextBox docs and inline docs in its source code). Just write a regular expression (as a string) that can validate your input. Something like that should do the trick:
var box = new dijit.form.NumberSpinner({
regExpGen: function(){ return "\\d+0"; }
}, "my_node");
You can also use the delta/smallDelta attribute for this. See the example at Dojo Campus