├── .gitignore ├── .jshintignore ├── .travis.yml ├── .jshintrc ├── .jscsrc ├── LICENSE.txt ├── package.json ├── Gruntfile.js ├── README.md ├── dist └── jquery.json.min.js ├── test ├── index.html └── jquery.json.test.js ├── HISTORY.md └── src └── jquery.json.js /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /.jshintignore: -------------------------------------------------------------------------------- 1 | dist 2 | libs 3 | node_modules 4 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | // Enforcing 3 | "bitwise": false, 4 | "eqeqeq": true, 5 | "freeze": true, 6 | "latedef": true, 7 | "noarg": true, 8 | "nonew": true, 9 | "undef": true, 10 | "unused": true, 11 | 12 | // Environment 13 | "browser": true, 14 | 15 | "globals": { 16 | "jQuery": false, 17 | "define": false, 18 | "require": false 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.jscsrc: -------------------------------------------------------------------------------- 1 | { 2 | "preset": "crockford", 3 | 4 | "disallowKeywords": [ "with" ], 5 | "disallowMultipleLineBreaks": true, 6 | "disallowQuotedKeysInObjects": true, 7 | "disallowSpaceAfterObjectKeys": true, 8 | "disallowYodaConditions": true, 9 | "requireBlocksOnNewline": 1, 10 | "requireCamelCaseOrUpperCaseIdentifiers": true, 11 | "requireVarDeclFirst": null, 12 | "requireMultipleVarDecl": true, 13 | "validateIndentation": "\t", 14 | "validateLineBreaks": "LF", 15 | "validateQuoteMarks": "'" 16 | } 17 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Copyright 2009-2011 Brantley Harris 2 | Copyright 2010–2016 Timo Tijhof 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the 6 | "Software"), to deal in the Software without restriction, including 7 | without limitation the rights to use, copy, modify, merge, publish, 8 | distribute, sublicense, and/or sell copies of the Software, and to 9 | permit persons to whom the Software is furnished to do so, subject to 10 | the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be 13 | included in all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 16 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 17 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 18 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 19 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 20 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 21 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "jquery-json", 3 | "description": "jQuery plugin for serialising to and parsing from JSON.", 4 | "version": "2.6.0", 5 | "keywords": [ 6 | "jquery-plugin" 7 | ], 8 | "homepage": "https://github.com/Krinkle/jquery-json", 9 | "repository": { 10 | "type": "git", 11 | "url": "git://github.com/Krinkle/jquery-json.git" 12 | }, 13 | "bugs": { 14 | "url": "https://github.com/Krinkle/jquery-json/issues" 15 | }, 16 | "author": "Brantley Harris (https://github.com/DeadWisdom)", 17 | "contributors": [ 18 | "Timo Tijhof (https://github.com/Krinkle)" 19 | ], 20 | "license": "MIT", 21 | "scripts": { 22 | "test": "grunt test", 23 | "build": "npm install && grunt build" 24 | }, 25 | "files": [ 26 | "src", 27 | "dist", 28 | "LICENSE.txt", 29 | "README.md" 30 | ], 31 | "main": "./src/jquery.json.js", 32 | "devDependencies": { 33 | "grunt": "1.0.1", 34 | "grunt-contrib-connect": "1.0.2", 35 | "grunt-contrib-jshint": "1.0.0", 36 | "grunt-contrib-qunit": "1.2.0", 37 | "grunt-contrib-uglify": "2.0.0", 38 | "grunt-jscs": "3.0.1", 39 | "jquery": "1.11.2", 40 | "qunitjs": "2.0.1" 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | /*jshint node:true */ 2 | module.exports = function (grunt) { 3 | grunt.loadNpmTasks('grunt-contrib-connect'); 4 | grunt.loadNpmTasks('grunt-contrib-jshint'); 5 | grunt.loadNpmTasks('grunt-contrib-qunit'); 6 | grunt.loadNpmTasks('grunt-contrib-uglify'); 7 | grunt.loadNpmTasks('grunt-jscs'); 8 | 9 | grunt.initConfig({ 10 | pkg: grunt.file.readJSON('package.json'), 11 | jshint: { 12 | options: { 13 | jshintrc: true 14 | }, 15 | all: ['*.js', '{src,test}/**/*.js'] 16 | }, 17 | jscs: { 18 | all: '<%= jshint.all %>' 19 | }, 20 | connect: { 21 | qunit: { 22 | options: { 23 | hostname: 'localhost', 24 | port: 9002 25 | } 26 | } 27 | }, 28 | qunit: { 29 | all: { 30 | options: { 31 | urls: [ 32 | 'http://localhost:9002/test/index.html?disableNative=true', 33 | 'http://localhost:9002/test/index.html?disableNative=true&distmin=true' 34 | ] 35 | } 36 | } 37 | }, 38 | uglify: { 39 | all: { 40 | files: { 41 | 'dist/jquery.json.min.js': ['src/jquery.json.js'] 42 | }, 43 | options: { 44 | banner: '/*! jQuery JSON plugin v<%= pkg.version %> | github.com/Krinkle/jquery-json */\n' 45 | } 46 | } 47 | } 48 | }); 49 | 50 | grunt.registerTask('lint', ['jshint', 'jscs']); 51 | grunt.registerTask('build', ['lint', 'uglify']); 52 | grunt.registerTask('test', ['build', 'connect', 'qunit']); 53 | }; 54 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![npm](https://img.shields.io/npm/v/jquery-json.svg?style=flat)](https://www.npmjs.com/package/jquery-json) 2 | [![Tested with QUnit](https://img.shields.io/badge/tested_with-qunit-9c3493.svg)](https://qunitjs.com/) 3 | 4 | # jQuery JSON 5 | 6 | JSON plugin for jQuery, provides simple ways to convert to JSON and back again. 7 | 8 | ## Usage 9 | 10 | ```js 11 | $.toJSON(myObject); 12 | $.toJSON({ foo: 'bar' }); 13 | ``` 14 | 15 | ## Development 16 | 17 | To create the minified build, run this command from the root directory of the repository: 18 | 19 | ```bash 20 | $ npm run build 21 | ``` 22 | 23 | ## Test 24 | 25 | Open up `./test/index.html` in your browser to run the test suite, or run it from 26 | the command line with Grunt: 27 | 28 | ``` 29 | $ npm install 30 | $ npm test 31 | ``` 32 | 33 | For it to pass in modern browsers, you have to enable the `disableNative` 34 | option from the QUnit toolbar. 35 | 36 | Also, before releasing. Make sure to test the minifed version as well, you can 37 | do so by enabling the `distmin` option in the QUnit toolbar. This will load 38 | the minified build from the `./dist/` directory instead of `./src/`. 39 | 40 | ## Versioning 41 | 42 | We use the Semantic Versioning guidelines as much as possible. 43 | 44 | Releases will be numbered in the following format: 45 | 46 | `..` 47 | 48 | For more information on SemVer, please visit http://semver.org/. 49 | -------------------------------------------------------------------------------- /dist/jquery.json.min.js: -------------------------------------------------------------------------------- 1 | /*! jQuery JSON plugin v2.6.0 | github.com/Krinkle/jquery-json */ 2 | !function(a){"function"==typeof define&&define.amd?define(["jquery"],a):a("object"==typeof exports?require("jquery"):jQuery)}(function($){"use strict";var escape=/["\\\x00-\x1f\x7f-\x9f]/g,meta={"\b":"\\b","\t":"\\t","\n":"\\n","\f":"\\f","\r":"\\r",'"':'\\"',"\\":"\\\\"},hasOwn=Object.prototype.hasOwnProperty;$.toJSON="object"==typeof JSON&&JSON.stringify?JSON.stringify:function(a){if(null===a)return"null";var b,c,d,e,f=$.type(a);if("undefined"!==f){if("number"===f||"boolean"===f)return String(a);if("string"===f)return $.quoteString(a);if("function"==typeof a.toJSON)return $.toJSON(a.toJSON());if("date"===f){var g=a.getUTCMonth()+1,h=a.getUTCDate(),i=a.getUTCFullYear(),j=a.getUTCHours(),k=a.getUTCMinutes(),l=a.getUTCSeconds(),m=a.getUTCMilliseconds();return g<10&&(g="0"+g),h<10&&(h="0"+h),j<10&&(j="0"+j),k<10&&(k="0"+k),l<10&&(l="0"+l),m<100&&(m="0"+m),m<10&&(m="0"+m),'"'+i+"-"+g+"-"+h+"T"+j+":"+k+":"+l+"."+m+'Z"'}if(b=[],$.isArray(a)){for(c=0;c 2 | 3 | 4 | 5 | jQuery JSON Test Suite 6 | 7 | 8 | 9 | 75 | 76 | 77 |
78 | 79 | 80 | -------------------------------------------------------------------------------- /HISTORY.md: -------------------------------------------------------------------------------- 1 | ## 2.6.0 / 2016-08-19 2 | 3 | * (#57) Added support for AMD and CommonJS loading. 4 | 5 | ## 2.5.0 / 2014-07-11 6 | 7 | * (#66) build: Switch to UglifyJS for better minification (2.3kb -> 1.9kb). 8 | * Published to npm. 9 | * Compatible with jQuery 1.11. 10 | * Moved project from Google Code to GitHub: https://github.com/Krinkle/jquery-json/releases. 11 | 12 | ## 2.4.0 / 2012-11-14 13 | 14 | * (#50) Inherited properties should be left out. 15 | * (#51) Use `hasOwnProperty` from the Object prototype to guard against objects 16 | with a property by the name "hasOwnProperty". 17 | * (#59) Array detection should not use `.constructor` (broken in IE9). 18 | Also fixed for Date object detection. 19 | * (#60) Constructed/Instantiated primitives should be stringified like their 20 | primitive equivalents. 21 | * (#56) Fixed spelling errors in documentation comments. 22 | * Improved build and unit test process. 23 | 24 | ## 2.3.0 / 2011-09-18 25 | 26 | * (#49) Improved performance by use direct reference to the native API. 27 | Methods `$.toJSON`, `$.evalJSON` and `$.secureEvalJSON` will link directly to 28 | the native `JSON.stringify` and `JSON.parse`, no longer checks on every call. 29 | * (#48) Minor performance improvements by not executing a typeof check if the 30 | result is not used. 31 | * (#27) Object members with value of type "undefined" should be omitted. 32 | * Reorganized testing environment (now using QUnit). 33 | * Code clean up and JSHint validation (Yay!). 34 | 35 | ## 2.2.0 / 2009-08-14 36 | 37 | * Fixed exception thrown in WebKit browsers. 38 | 39 | ## 2.1.0 / 2009-08-14 40 | 41 | * Fixed a problem in how it was representing arrays and undefined values. 42 | 43 | ## 2.0.0 / 2009-08-14 44 | 45 | * Fixed a bug where dates weren't converting correctly. 46 | * The code has been re-written. It is now easier to read and follow; less 47 | of a mish-mash. 48 | * Support for native JSON has been included. This means that if you are using a 49 | browser that supports JSON.stringify, it will be used. Also evalJSON and 50 | secureEvalJSON will use JSON.parse if available. 51 | * Changes were made in the JSON output to match the JSON specification. This 52 | means 2.0 is not backwards compatible with the previous versions. 53 | * $.toJSON now renders like $.compactJSON used to and $.compactJSON has been 54 | removed. As per the JSON specification, needless spaces are now removed. This 55 | makes it less readable; patches for a $.prettyJSON are welcome! 56 | * Differences between output when JSON.stringify is available and when it is 57 | not could exist. I am unable to test all strings. Be aware of this when 58 | testing your application. 59 | -------------------------------------------------------------------------------- /src/jquery.json.js: -------------------------------------------------------------------------------- 1 | /** 2 | * jQuery JSON plugin v2.6.0 3 | * https://github.com/Krinkle/jquery-json 4 | * 5 | * @author Brantley Harris, 2009-2011 6 | * @author Timo Tijhof, 2011-2016 7 | * @source This plugin is heavily influenced by MochiKit's serializeJSON, which is 8 | * copyrighted 2005 by Bob Ippolito. 9 | * @source Brantley Harris wrote this plugin. It is based somewhat on the JSON.org 10 | * website's http://www.json.org/json2.js, which proclaims: 11 | * "NO WARRANTY EXPRESSED OR IMPLIED. USE AT YOUR OWN RISK.", a sentiment that 12 | * I uphold. 13 | * @license MIT License 14 | */ 15 | (function (factory) { 16 | if (typeof define === 'function' && define.amd) { 17 | // AMD 18 | define(['jquery'], factory); 19 | } else if (typeof exports === 'object') { 20 | // CommonJS 21 | factory(require('jquery')); 22 | } else { 23 | // Browser globals 24 | factory(jQuery); 25 | } 26 | }(function ($) { 27 | 'use strict'; 28 | 29 | var escape = /["\\\x00-\x1f\x7f-\x9f]/g, 30 | meta = { 31 | '\b': '\\b', 32 | '\t': '\\t', 33 | '\n': '\\n', 34 | '\f': '\\f', 35 | '\r': '\\r', 36 | '"': '\\"', 37 | '\\': '\\\\' 38 | }, 39 | hasOwn = Object.prototype.hasOwnProperty; 40 | 41 | /** 42 | * jQuery.toJSON 43 | * Converts the given argument into a JSON representation. 44 | * 45 | * @param o {Mixed} The json-serializable *thing* to be converted 46 | * 47 | * If an object has a toJSON prototype, that will be used to get the representation. 48 | * Non-integer/string keys are skipped in the object, as are keys that point to a 49 | * function. 50 | * 51 | */ 52 | $.toJSON = typeof JSON === 'object' && JSON.stringify ? JSON.stringify : function (o) { 53 | if (o === null) { 54 | return 'null'; 55 | } 56 | 57 | var pairs, k, name, val, 58 | type = $.type(o); 59 | 60 | if (type === 'undefined') { 61 | return undefined; 62 | } 63 | 64 | // Also covers instantiated Number and Boolean objects, 65 | // which are typeof 'object' but thanks to $.type, we 66 | // catch them here. I don't know whether it is right 67 | // or wrong that instantiated primitives are not 68 | // exported to JSON as an {"object":..}. 69 | // We choose this path because that's what the browsers did. 70 | if (type === 'number' || type === 'boolean') { 71 | return String(o); 72 | } 73 | if (type === 'string') { 74 | return $.quoteString(o); 75 | } 76 | if (typeof o.toJSON === 'function') { 77 | return $.toJSON(o.toJSON()); 78 | } 79 | if (type === 'date') { 80 | var month = o.getUTCMonth() + 1, 81 | day = o.getUTCDate(), 82 | year = o.getUTCFullYear(), 83 | hours = o.getUTCHours(), 84 | minutes = o.getUTCMinutes(), 85 | seconds = o.getUTCSeconds(), 86 | milli = o.getUTCMilliseconds(); 87 | 88 | if (month < 10) { 89 | month = '0' + month; 90 | } 91 | if (day < 10) { 92 | day = '0' + day; 93 | } 94 | if (hours < 10) { 95 | hours = '0' + hours; 96 | } 97 | if (minutes < 10) { 98 | minutes = '0' + minutes; 99 | } 100 | if (seconds < 10) { 101 | seconds = '0' + seconds; 102 | } 103 | if (milli < 100) { 104 | milli = '0' + milli; 105 | } 106 | if (milli < 10) { 107 | milli = '0' + milli; 108 | } 109 | return '"' + year + '-' + month + '-' + day + 'T' + 110 | hours + ':' + minutes + ':' + seconds + 111 | '.' + milli + 'Z"'; 112 | } 113 | 114 | pairs = []; 115 | 116 | if ($.isArray(o)) { 117 | for (k = 0; k < o.length; k++) { 118 | pairs.push($.toJSON(o[k]) || 'null'); 119 | } 120 | return '[' + pairs.join(',') + ']'; 121 | } 122 | 123 | // Any other object (plain object, RegExp, ..) 124 | // Need to do typeof instead of $.type, because we also 125 | // want to catch non-plain objects. 126 | if (typeof o === 'object') { 127 | for (k in o) { 128 | // Only include own properties, 129 | // Filter out inherited prototypes 130 | if (hasOwn.call(o, k)) { 131 | // Keys must be numerical or string. Skip others 132 | type = typeof k; 133 | if (type === 'number') { 134 | name = '"' + k + '"'; 135 | } else if (type === 'string') { 136 | name = $.quoteString(k); 137 | } else { 138 | continue; 139 | } 140 | type = typeof o[k]; 141 | 142 | // Invalid values like these return undefined 143 | // from toJSON, however those object members 144 | // shouldn't be included in the JSON string at all. 145 | if (type !== 'function' && type !== 'undefined') { 146 | val = $.toJSON(o[k]); 147 | pairs.push(name + ':' + val); 148 | } 149 | } 150 | } 151 | return '{' + pairs.join(',') + '}'; 152 | } 153 | }; 154 | 155 | /** 156 | * jQuery.evalJSON 157 | * Evaluates a given json string. 158 | * 159 | * @param str {String} 160 | */ 161 | $.evalJSON = typeof JSON === 'object' && JSON.parse ? JSON.parse : function (str) { 162 | /*jshint evil: true */ 163 | return eval('(' + str + ')'); 164 | }; 165 | 166 | /** 167 | * jQuery.secureEvalJSON 168 | * Evals JSON in a way that is *more* secure. 169 | * 170 | * @param str {String} 171 | */ 172 | $.secureEvalJSON = typeof JSON === 'object' && JSON.parse ? JSON.parse : function (str) { 173 | var filtered = 174 | str 175 | .replace(/\\["\\\/bfnrtu]/g, '@') 176 | .replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']') 177 | .replace(/(?:^|:|,)(?:\s*\[)+/g, ''); 178 | 179 | if (/^[\],:{}\s]*$/.test(filtered)) { 180 | /*jshint evil: true */ 181 | return eval('(' + str + ')'); 182 | } 183 | throw new SyntaxError('Error parsing JSON, source is not valid.'); 184 | }; 185 | 186 | /** 187 | * jQuery.quoteString 188 | * Returns a string-repr of a string, escaping quotes intelligently. 189 | * Mostly a support function for toJSON. 190 | * Examples: 191 | * >>> jQuery.quoteString('apple') 192 | * "apple" 193 | * 194 | * >>> jQuery.quoteString('"Where are we going?", she asked.') 195 | * "\"Where are we going?\", she asked." 196 | */ 197 | $.quoteString = function (str) { 198 | if (str.match(escape)) { 199 | return '"' + str.replace(escape, function (a) { 200 | var c = meta[a]; 201 | if (typeof c === 'string') { 202 | return c; 203 | } 204 | c = a.charCodeAt(); 205 | return '\\u00' + Math.floor(c / 16).toString(16) + (c % 16).toString(16); 206 | }) + '"'; 207 | } 208 | return '"' + str + '"'; 209 | }; 210 | 211 | })); 212 | -------------------------------------------------------------------------------- /test/jquery.json.test.js: -------------------------------------------------------------------------------- 1 | /** 2 | * Test suite for the jQuery JSON plugin. 3 | */ 4 | /*jshint freeze:false */ 5 | /*global QUnit */ 6 | 7 | // Utility function 8 | QUnit.assert.toJSON = function (obj, string, description) { 9 | QUnit.assert.equal(jQuery.toJSON(obj), string, description || ''); 10 | }; 11 | 12 | QUnit.module('jQuery.toJSON'); 13 | 14 | QUnit.test('Basic toJSON usage', function (assert) { 15 | assert.toJSON( 16 | 'hi', 17 | '"hi"', 18 | 'Strings should be wrapped in double quotes' 19 | ); 20 | assert.toJSON( 21 | { apple: 2 }, 22 | '{"apple":2}', 23 | 'Objects' 24 | ); 25 | assert.toJSON( 26 | { apple: { apple: 2 } }, 27 | '{"apple":{"apple":2}}', 28 | 'Objects inside objects' 29 | ); 30 | assert.toJSON( 31 | { apple: 7, pear: 5 }, 32 | '{"apple":7,"pear":5}', 33 | 'Objects with multiple members should be separated by a comma' 34 | ); 35 | assert.toJSON( 36 | 2.5, 37 | '2.5', 38 | 'Numbers with a decimal' 39 | ); 40 | assert.toJSON( 41 | 25, 42 | '25', 43 | 'Number' 44 | ); 45 | assert.toJSON( 46 | [2, 5], 47 | '[2,5]', 48 | 'Array of numbers' 49 | ); 50 | assert.toJSON( 51 | function () {}, 52 | undefined, 53 | 'Functions are not supported and should return undefined' 54 | ); 55 | assert.toJSON( 56 | 'C:\\A.TXT', 57 | '"C:\\\\A.TXT"', 58 | 'Slashes should be double escaped' 59 | ); 60 | assert.toJSON( 61 | 'C:\\B.TXT', 62 | '"C:\\\\B.TXT"', 63 | 'Slashes should be double escaped' 64 | ); 65 | assert.toJSON( 66 | ['C:\\A.TXT', 'C:\\B.TXT', 'C:\\C.TXT', 'C:\\D.TXT'], 67 | '["C:\\\\A.TXT","C:\\\\B.TXT","C:\\\\C.TXT","C:\\\\D.TXT"]', 68 | 'Array of strings with slashes' 69 | ); 70 | assert.toJSON( 71 | { dDefault: '1.84467440737E+19' }, 72 | '{"dDefault":"1.84467440737E+19"}', 73 | 'Object with lower case key and value that should not be touched' 74 | ); 75 | assert.toJSON( 76 | [0, false, function () {}], 77 | '[0,false,null]', 78 | 'Resolve unsupported values (like functions) to null when encountered as object member values' 79 | ); 80 | assert.toJSON( 81 | 0, 82 | '0', 83 | 'Zero is zero' 84 | ); 85 | assert.toJSON( 86 | false, 87 | 'false', 88 | 'False is false' 89 | ); 90 | assert.toJSON( 91 | null, 92 | 'null', 93 | 'null is null' 94 | ); 95 | assert.toJSON( 96 | undefined, 97 | undefined, 98 | 'undefined is not valid and should not return a string "undefined" but literally undefined' 99 | ); 100 | }); 101 | 102 | QUnit.test('Dates', function (assert) { 103 | // '1224892800000' is the Epoch timestamp of midnight October 25, 2008. 104 | // Using that instead of Date(2008,10,25) to avoid errors when the user 105 | // running the tests is not in a UTC +00:00 timezone (which is very likely) 106 | assert.toJSON( 107 | new Date(1224892800000), 108 | '"2008-10-25T00:00:00.000Z"', 109 | 'Check date handling, likely the browser itself' 110 | ); 111 | 112 | // Test without the native version (if available) 113 | // So that we can test the fallback in jQuery.toJSON 114 | var dateToJson = Date.prototype.toJSON; // Keep a reference to the native one 115 | if (dateToJson) { 116 | Date.prototype.toJSON = undefined; 117 | } 118 | 119 | assert.toJSON( 120 | new Date(1224892800000), 121 | '"2008-10-25T00:00:00.000Z"', 122 | 'Testing fallback, any native browser handling disabled' 123 | ); 124 | 125 | // Restore 126 | if (dateToJson) { 127 | Date.prototype.toJSON = dateToJson; 128 | } 129 | 130 | assert.toJSON( 131 | new Date(1224892800000), 132 | '"2008-10-25T00:00:00.000Z"', 133 | 'Sanity check in case something screwed up' 134 | ); 135 | }); 136 | 137 | QUnit.test('RegExp', function (assert) { 138 | // We don't really care what RegExp objects end up like, 139 | // but we want to match browser behavior. 140 | assert.toJSON( 141 | new RegExp('hello'), 142 | '{}', 143 | 'Instantiated RegExp (simple) ' 144 | ); 145 | assert.toJSON( 146 | new RegExp('hello', 'gi'), 147 | '{}', 148 | 'Instantiated RegExp (with options)' 149 | ); 150 | assert.toJSON( 151 | /hello/, 152 | '{}', 153 | 'RegExp literal (simple)' 154 | ); 155 | assert.toJSON( 156 | /hello/gi, 157 | '{}', 158 | 'RegExp literal (with options)' 159 | ); 160 | }); 161 | 162 | QUnit.test('Primitive constructors', function (assert) { 163 | // Nobody should be using new Number(), new Boolean(), or new String() 164 | // but they are an interesting edge case, because they are typeof 'object'. 165 | // Workaround for jshint: 166 | var N = Number, B = Boolean, S = String; 167 | 168 | assert.toJSON( 169 | new N(7), 170 | '7', 171 | 'Instantiated Number' 172 | ); 173 | assert.toJSON( 174 | new B(true), 175 | 'true', 176 | 'Instantiated Boolean (true)' 177 | ); 178 | assert.toJSON( 179 | new B(false), 180 | 'false', 181 | 'Instantiated Boolean (false)' 182 | ); 183 | assert.toJSON( 184 | new S('hello'), 185 | '"hello"', 186 | 'Instantiated String' 187 | ); 188 | }); 189 | 190 | if (navigator.userAgent.indexOf('PhantomJS') === -1) { 191 | // https://github.com/ariya/phantomjs/issues/10315 192 | QUnit.test('Function arguments object', function (assert) { 193 | function argTest() { 194 | assert.toJSON( 195 | arguments, 196 | '{"0":"foo","1":"bar","2":"baz"}', 197 | 'arguments, as instance of Arguments, should be treated as an object' 198 | ); 199 | } 200 | 201 | argTest('foo', 'bar', 'baz'); 202 | }); 203 | } 204 | 205 | QUnit.test('Undefined and null', function (assert) { 206 | assert.toJSON( 207 | { apple: undefined, pear: 5 }, 208 | '{"pear":5}', 209 | 'Objects with a member with value of type undefined should be removed' 210 | ); 211 | assert.toJSON( 212 | [undefined, undefined, 1, 2], 213 | '[null,null,1,2]', 214 | 'Resolve undefined to null when encountered as object member values' 215 | ); 216 | }); 217 | 218 | QUnit.test('Prototype inheritance', function (assert) { 219 | 220 | Object.prototype.AWESOME = 7; 221 | 222 | assert.toJSON( 223 | { apple: 2, key: 'value' }, 224 | '{"apple":2,"key":"value"}', 225 | 'Prototype values should not be included in the string' 226 | ); 227 | 228 | // Since prototypes are highly dangerous, 229 | // make sure to remove it as soon as possible 230 | // Lots of code in jQuery will fail as it is 231 | // in the policy of jQuery that Object prototypes 232 | // are not supported. 233 | try { 234 | // Might fail in IE. Make sure to not let any exception 235 | // get out. 236 | delete Object.prototype.AWESOME; 237 | } catch (e) {} 238 | }); 239 | 240 | QUnit.test('"hasOwnProperty" mixup', function (assert) { 241 | assert.toJSON( 242 | /*jshint -W001 */ 243 | { isAwesome: true, hasOwnProperty: false }, 244 | '{"isAwesome":true,"hasOwnProperty":false}', 245 | 'Guard against inherited prototypes should not depend on prototype inheritance itself' 246 | ); 247 | }); 248 | --------------------------------------------------------------------------------