How to run prelude functions - javascript

I downloaded prelude.js and added it in my application. I linked the js file in my html file in the following way:
<script type="text/javascript" src="prelude-browser-min.js"></script>
I didn't link any dependent file in my html file. I opened the browser console and ran the following code, which is not working:
tail [1 to 5]
It looks like I'm not able to see the prelude function.
So do I need to add any other file in my html headers ? What am I doing wrong ?

That's livescript syntax, but if you want to use vanilla js; here's a jsfiddle setup.
var prelude = require('prelude-ls')
tail = prelude.tail([1,2,3,4,5])
console.log(tail);

Related

How to create QUnit tests with reference to another class?

I'm trying to add unit testing for JavaScript into my web site. I use VS2013 and my project is an ASP.NET web site.
Based on recommendations (http://www.rhyous.com/2013/02/20/creating-a-qunit-test-project-in-visual-studio-2010/) I've done so far:
Created new ASP.NET app
Imported QUnit (using NuGet)
Into "Scripts" added links to js-file in my original web site (files PlayerSkill.js - containts PlayerSkill class and trainings.js - contains Trainer and some other classes)
Created new folder "TestScripts"
Added TrainingTests.js file
Wrote simple test:
test( "Trainer should have non-empty group", function () {
var group = "group";
var trainer = new Trainer(123, "Name123", group, 123);
EQUAL(trainer.getTrainerGroup(), group);
});
Notice: my trainings.js file among others contains
function Trainer(id, name, group, level) {
...
var _group = group;
this.getTrainerGroup = function () { return _group ; }
};
When I execute my test I see error: Trainer is not defined.
It looks like reference to my class is not recognized. I feel like linking file is not enough, but what did I miss?
Please help add reference to the original file with class and run unit test.
Thank you.
P.S. Question 2: Can I add reference to 2 files (my unit test will require one more class which is in another file)? How?
You should add all the relevant logic of your application to your unit testing file so they all execute before you run your tests
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>QUnit Test Results</title>
<link rel="stylesheet" href="/Content/qunit.css">
</head>
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="/Scripts/qunit.js"></script>
<script src="/Scripts/PlayerSkill.js"></script>
<script src="/Scripts/trainings.js"></script>
<script src="/TestScripts/TrainingTests.js"></script>
</body>
</html>
You should not use linked files because they will not exist physically in the script folder.
If you really want to use them you should let the Visual Studio intellisense resolve the physical path of the file like this.
Type the script tag <script src=""></script>
Place the cursor inside the quotes in the src attribute and press CTRL + SPACE
Search your files and let the resolved path untouched
If your project location changes you must update the linked files and also the script references.
{Edit1}
Solution 2:
You could also use an MVC Controller and a Razor View to create your unit testing page and the linked files will work as expected with the only issue that you will have an extra controller in your project but this is not bad at all if for example you want to test the loading of content using ajax that is by default blocked by the browser if they are run from a local file.
Solution 3:
You can also setup a new MVC project just for your javascript unit testing just as you usually setup a new project for any server side code and this will help to prevent your testing to interfere with your production code
{Edit 2}
Solution 4:
As part of the javascript ecosystem you could use grunt or gulp to automate the copy of your scripts from anywhere to your project before running the tests. You could write a gulpfile.js like this
var sourcefiles = [/*you project file paths*/];
gulp.task('default', function () {
return gulp.src(sourcefiles).pipe(gulp.dest('Scripts'));
});
And then run it opening a console and running the command gulp or gulp default
Looks like trainings.js is not defined when calling TrainingTests.js . See this question for more details regarding why this happens! Once that is fixed it does work. And yes similar to trainings.js you can have any number of files in any folder as long as you reference them properly. I have created a sample fiddle accessible # http://plnkr.co/edit/PnqVebOzmPpGu7x2qWLs?p=preview
<body>
<div id="qunit"></div>
<div id="qunit-fixture"></div>
<script src="http://code.jquery.com/qunit/qunit-1.18.0.js"></script>
<script src="trainings.js"></script>
<script src="TrainingTests.js"></script>
</body>
In my case I wanted to run my tests from within my ASP.NET web application, and also on a CI server. In addition to the other information here I needed the following, otherwise I experienced the same error as the OP on my CI server:
Add one or more require() calls to test scripts.
Set the NODE_PATH environment variable to the root of my application.
Example of require()
Within my test scripts I include a requires block, the conditional allows me to use this script from a web browser without needing to adopt a third-party equivalent such as requirejs (which is convenient.)
if (typeof(require) !== 'undefined') {
require('lib/3rdparty/dist/3p.js');
require('js/my.js');
require('js/app.js');
}
Example of setting NODE_PATH
Below, 'wwwroot' is the path of where /lib/ and other application files are located. My test files are located within /tests/.
Using bash
#!/bin/bash
cd 'wwwroot'
export NODE_PATH=`pwd`
qunit tests
Using powershell
#!/usr/bin/pwsh
cd 'wwwroot'
$env:NODE_PATH=(pwd)
qunit tests
This allowed me to run tests both within my ASP.NET web application, and also from a CI server using a script.
HTH.
If you're wondering how to make your tests see your code when running from command line (not from browser!), here is a bit expanded version of Shaun Wilson's answer (which doesn't work out-of-the-box, but contains a good idea where to start)
Having following structure:
project
│ index.js <--- Your script with logic
└───test
tests.html <--- QUnit tests included in standard HTML page for "running" locally
tests.js <--- QUnit test code
And let's imagine that in your index.js you have following:
function doSomething(arg) {
// do smth
return arg;
}
And the test code in tests.js (not that it can be the whole content of the file - you don't need anything else to work):
QUnit.test( "test something", function( assert ) {
assert.ok(doSomething(true));
});
Running from command line
To make your code accessible from the tests you need to add two things to the scripts.
First is to explicitly "import" your script from tests. Since JS doesn't have sunch a functionality out-of-the box, we'll need to use require coming from NPM. And to keep our tests working from HTML (when you run it from browser, require is undefined) add simple check:
// Add this in the beginning of tests.js
// Use "require" only if run from command line
if (typeof(require) !== 'undefined') {
// It's important to define it with the very same name in order to have both browser and CLI runs working with the same test code
doSomething = require('../index.js').doSomething;
}
But if index.js does not expose anything, nothing will be accessible. So it's required to expose functions you want to test explicitly (read more about exports). Add this to index.js:
//This goes to the very bottom of index.js
if (typeof module !== 'undefined' && module.exports) {
exports.doSomething = doSomething;
}
When it's done, just type
qunit
And the output should be like
TAP version 13
ok 1 Testing index.js > returnTrue returns true
1..1
# pass 1
# skip 0
# todo 0
# fail 0
Well, due to help of two answers I did localize that problem indeed was in inability of VS to copy needed file into test project.
This can be probably resolved by multiple ways, I found one, idea copied from: http://www.javascriptkit.com/javatutors/loadjavascriptcss.shtml
Solution is simple: add tag dynamically
In order to achieve this, I've added the following code into tag:
<script>
var fileref = document.createElement('script');
fileref.setAttribute("type", "text/javascript");
var path = 'path'; // here is an absolute address to JS-file on my web site
fileref.setAttribute("src", path);
document.getElementsByTagName("head")[0].appendChild(fileref);
loadjscssfile(, "js") //dynamically load and add this .js file
</script>
And moved my tests into (required also reference to jquery before)
$(document).ready(function () {
QUnit.test("Test #1 description", function () { ... });
});
Similar approach also works for pure test files.

gulp: Automatically add version number to request for preventing browser cache

I deploy my project by building source files with gulp right on the server. To prevent caching issues, the best practice could be adding a unique number to request url, see: Preventing browser caching on web application upgrades;
In npm repositories, I couldn't find a tool for automatically adding version number to request. I'm asking if someone has invented such tool before.
Possible implementation could be the following:
I have a file index.html in src/ folder, with following script tag
<script src="js/app.js<!-- %nocache% -->"></script>
During build it is copied to dist/ folder, and comment is replaced by autoincrement number
<script src="js/app.js?t=1234"></script>
You can use gulp-version-number for this. It can add version numbers to linked scripts, stylesheets, and other files in you HTML documents, by appending an argument to the URLs. For example:
<link rel="stylesheet" href="main.css">
becomes:
<link rel="stylesheet" href="main.css?v=474dee2efac59e2dcac7bf6c37365ed0">
You don't even have to specify a placeholder, like you showed in your example implementation. And it's configurable.
Example usage:
const $ = gulpLoadPlugins();
const versionConfig = {
'value': '%MDS%',
'append': {
'key': 'v',
'to': ['css', 'js'],
},
};
gulp.task('html', () => {
return gulp.src('src/**/*.html')
.pipe($.htmlmin({collapseWhitespace: true}))
.pipe($.versionNumber(versionConfig))
.pipe(gulp.dest('docroot'));
});
NOTE:
I can no longer recommend this plugin. It is no longer maintained and there are some issues with it. I created a pull request some time ago, but there is no response from the author.
You can use the gulp-rev module. This will append a version number to the files, the version is a hash of the file content, so it will only change if the file changes.
You then output a manifest file containing the mapping between the file e.g. Scripts.js to Scripts-8wrefhn.js.
Then use a helper function when returning the page content to map the correct values.
I have used the above process. However there's another module gulp-rev-all which is an forked extension of gulp-rev which does a little more, e.g. automatic updating of file references in pages.
Documentation here:
gulp-rev: https://github.com/sindresorhus/gulp-rev
gulp-rev-all: https://www.npmjs.com/package/gulp-rev-all
I worked onto writing an regex, which in use along with gulp-replace works just fine.
Please find the code below. Following is a quick code for the image and css for views files codeigniter framework. But it should work fine for all the kinds of files given the source folder specified correctly.
You may customize the code as per your use.
You can call the tasks altogether, using gulp default or individual task at a time.
'use strict';
var gulp = require('gulp');
var replace = require('gulp-replace');
function makeid() {
return (Math.random() + 1).toString(36).substring(7);
}
gulp.task('versioningCss', () => {
return gulp.src('application/modules/**/views/*.php')
.pipe(replace(/(.*)\.css\?(_v=.+&)*(.*)/g, '$1.css?_v='+makeid()+'&$3'))
.pipe(replace(/(.*)\.css\"(.*)/g, '$1.css?_v='+makeid()+'"$2'))
.pipe(replace(/(.*)\.css\'(.*)/g, '$1.css?_v='+makeid()+'\'$2'))
.pipe(gulp.dest('application/modules'));
});
gulp.task('versioningJs', () => {
return gulp.src('application/modules/**/views/*.php')
.pipe(replace(/(.*)\.js\?(_v=.+&)*(.*)/g, '$1.js?_v='+makeid()+'&$3'))
.pipe(replace(/(.*)\.js\"(.*)/g, '$1.js?_v='+makeid()+'"$2'))
.pipe(replace(/(.*)\.js\'(.*)/g, '$1.js?_v='+makeid()+'\'$2'))
.pipe(gulp.dest('application/modules'));
});
gulp.task('versioningImage', () => {
return gulp.src('application/modules/**/views/*.php')
.pipe(replace(/(.*)\.(png|jpg|jpeg|gif)\?(_v=.+&)*(.*)/g, '$1.$2?_v='+makeid()+'&$4'))
.pipe(replace(/(.*)\.(png|jpg|jpeg|gif)\"(.*)/g, '$1.$2?_v='+makeid()+'"$3'))
.pipe(replace(/(.*)\.(png|jpg|jpeg|gif)\'(.*)/g, '$1.$2?_v='+makeid()+'\'$3'));
});
gulp.task('default', [ 'versioningCss', 'versioningJs', 'versioningImage']);
It looks like you may have quite a few options.
https://www.npmjs.com/package/gulp-cachebust
https://www.npmjs.com/package/gulp-buster
Hope this helps.
You can use
<script type="text/javascript" src="js/app.js?seq=<%=DateTime.Now.Ticks%>"></script>
or
<script type="text/javascript" src="js/app.js?seq=<%=DateTime.Now.ToString("yyyyMMddHHmm") %>"></script>

How to create a snapshot of .js file -> webkit nwjs v8

Can somebody please explain me how to make a snapshot of javascript file in nodewebkit (now known as http://nwjs.io/) aplication.
I found this wiki https://github.com/nwjs/nw.js/wiki/Protect-JavaScript-source-code-with-v8-snapshot
but i cannot find nwsnapshot aplication.
Or where i need to input code (nwsnapshot --extra_code mytest.js mytest.bin) to convert - compile it?
If you cannot find nwsnapshot, then look after nwjc.
To make a snapshot, you'll type under console (replace names accordingly):
nwjc yourjsfiletoprotect.js jshidden.bin
Then, you'll need to import jshidden.bin into your HTML file. You will not achieve this using <script src="jshidden.bin"></script>. That won't work.
You'll achieve this by writing:
<script>
var nw = require('nw.gui');
nw.Window.get().evalNWBin(null, 'jshidden.bin');
</script>
You'd be aware that there are serious limitations when it comes to using nw snapshots.

Use prelude-ls with LiveScript

I just need to use prelude-ls library in LiveScript, but no from the REPL. In my little test, I have 4 files:
main.htm
application.ls
application.js
require.js
I have the latest version of require.js (2.1.15) and in my main.htm I load the scripts:
<!DOCTYPE html>
<html>
<head>
<script src="./require.js" type="text/javascript"></script>
<script src="./prelude.js" type="text/javascript"></script>
</head>
<body>
</body>
</html>
Then, I go to my application.ls to test:
require! 'prelude-ls'
[1 2 3] |> prelude-ls.map (* 2)
My compile command is:
lsc -cwd $myFilePath
And it compiles just fine. Then, I go there to get the final result, to test and receive the following error:
Uncaught Error: Module name "prelude-ls" has not been loaded yet for context: _. Use require([])
Well, I saw the this is a very common error and its corrections would happen in the js file, not in the ls and none of the links I followed solved my problems. I've tried it in 2 computers and had the really same result.
My final js file, application.js is:
// Generated by LiveScript 1.2.0
(function(){
var preludeLs;
preludeLs = require('prelude-ls');
preludeLs.map((function(it){
return it * 2;
}))(
[1, 2, 3]);
}).call(this);
Plase, help me if possible. I really read all the documentation of livescript and it doens't cites its first use with prelude-ls.
I think you're confusing AMD.js (here, Require.JS) and CommonJS.
AMD.js uses the
require(['dep1', 'dep2'], function (dep1, dep2) {
dep1.callSomething();
});
(this allows for async loading)
CommonJS (which is what prelude-ls uses), on the other hand, is basically what node does (and what we generate with require!):
var preludeLs = require('prelude-ls')
At first I didn't understand, I find the answer confusing, though correct. Please let me sum it up.
Actually it's very simple and it works as says the doc.
We must install prelude-ls with npm or bower. We need to include the file prelude-browser.js (at prelude-ls/browser/prelude-browser.js).
Then we just require prelude at the beginning of our code:
prelude = require 'prelude-ls'
and we can call prelude.sum, etc.
A second option is to import exactly the function we need, like so:
{map, filter, lines} = require 'prelude-ls'
so we can call them directly.
That works with gulp and angularjs FYI.
This answer is clear.

Using Crypto.js in meteor

I am trying to include some crypto.js libraries in a meteor js app (meteor version 0.6.4.1).
http://crypto-js.googlecode.com/svn/tags/3.1.2/build/rollups/hmac-sha256.js
http://crypto-js.googlecode.com/svn/tags/3.1.2/build/components/enc-base64-min.js
When I copy and paste the contents into the server/main.js file it works fine, but this makes it very un-readable.
When I put the libraries in separate files in the server directory (I also tried placing them in the lib directory) I get the error ReferenceError: CryptoJS is not defined.
gist of server/main.js:
Meteor.methods({
encrypt:function(bundleID){
return CryptoJS.HmacSHA256(string, 'something');
}
});
I also tried changing the first line of the hmac-sha256.js file from
var CryptoJS=CryptoJS||function(h,s){...
to:
CryptoJS=CryptoJS||function(h,s){...
to make it global, but this also did not work. How do I include this library properly?
In your application dir create folder 'packages/cryptojs' and put there files:
hmac-sha256.js
enc-base64-min.js
package.js
packages / cryptojs / package.js:
Package.describe({
summary: "CryptoJS"
});
Package.on_use(function (api, where) {
api.add_files(['hmac-sha256.js'], ['client','server']);
api.add_files(['enc-base64-min.js'], ['client','server']);
});
You need to modify hmac-sha256.js by changing beginning of line 7 from:
var CryptoJS=CryptoJS||function(h,s){
to:
CryptoJS=function(h,s){
After that, you can use it:
var hash = CryptoJS.HmacSHA256("Message", "secret");
var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
console.log(hashInBase64)
Example source
I followed as parhelium's guide, but still not work, then I found new way to fix this issue:
Just replace line 7 in hmac-sha512.js to this one to globalize CryptoJS object:
this.CryptoJS=this.CryptoJS
Fix the same for other cryptojs. To use with Base64, you must make sure the base64.js is loaded after other libraries.
The reason this is happening is due to the variable scoping in meteor. Try putting the cryptojs library files in /server/compatibility. This way the cryptojs library can be accessed in other files.
You could also get it working without putting it in /compatibility by removing the var used in the cryptojs source files. The thing is if you do this its harder to keep the files up to date.

Categories

Resources