123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677 |
- /* global require, chai, describe, before, it */
- // 数据模板定义(Data Temaplte Definition,DTD)
- /*
- ## BDD
- 1. 结构
- describe suite
- [ describe ]
- before after beforeEach afterEach
- it test
- done
- 搜索 this.async = fn && fn.length
- 2. 常用 expect
- expect().to
- .equal .deep.equal .not.equal
- .match
- .have.length .with.length
- .have.property .have.deep.property
- .to.be.a .to.be.an
- .that
- .least .most .within
- 3. 速度
- 搜索 test.speed
- slow > 75
- 75 / 2 < medium < 75
- fast < 75 / 2
- */
- var expect = chai.expect
- var Mock, $, _
- describe('DTD', function() {
- before(function(done) {
- require(['mock', 'underscore', 'jquery'], function() {
- Mock = arguments[0]
- _ = arguments[1]
- $ = arguments[2]
- expect(Mock).to.not.equal(undefined)
- expect(_).to.not.equal(undefined)
- expect($).to.not.equal(undefined)
- done()
- })
- })
- describe('Literal', function() {
- it('', function() {
- var data = Mock.mock(this.test.title)
- expect(data).to.equal(this.test.title)
- })
- it('foo', function() {
- var data = Mock.mock(this.test.title)
- expect(data).to.equal(this.test.title)
- })
- it(1, function() {
- var data = Mock.mock(this.test.title)
- expect(data).to.equal(this.test.title)
- })
- it(true, function() {
- var data = Mock.mock(this.test.title)
- expect(data).to.equal(this.test.title)
- })
- it(false, function() {
- var data = Mock.mock(this.test.title)
- expect(data).to.equal(this.test.title)
- })
- it({}, function() {
- var data = Mock.mock(this.test.title)
- expect(data).to.deep.equal(this.test.title)
- })
- it([], function() {
- var data = Mock.mock(this.test.title)
- expect(data).to.deep.equal(this.test.title)
- })
- it(function() {}, function() {
- var data = Mock.mock(this.test.title)
- expect(data).to.equal(undefined)
- })
- })
- describe('String', function() {
- // `'name|min-max': 'value'`
- it('name|min-max', function() {
- var data = Mock.mock({
- 'name|1-10': '★号'
- })
- expect(data.name).to.have.length.within(2, 20)
- })
- // `'name|count': 'value'`
- it('name|count', function() {
- var data = Mock.mock({
- 'name|10': '★号'
- })
- expect(data.name).to.be.a('string')
- .that.have.length(20)
- })
- })
- describe('Number', function() {
- // `'name|+step': value`
- it('name|+step', function() {
- var data = Mock.mock({
- 'list|10': [{
- 'name|+1': 100
- }]
- })
- expect(data.list).to.be.an('array').with.length(10)
- _.each(data.list, function(item, index) {
- expect(item).to.have.property('name')
- .that.be.a('number')
- if (index === 0) expect(item.name).to.equal(100)
- else expect(item.name).to.equal(
- data.list[index - 1].name + 1
- )
- })
- })
- // `'name|min-max': value`
- it('name|min-max', function() {
- var data = Mock.mock({
- 'name|1-100': 100
- })
- expect(data).to.have.property('name')
- .that.be.a('number').within(1, 100)
- })
- it('name|max-min', function() {
- var data = Mock.mock({
- 'name|100-1': 100
- })
- expect(data).to.have.property('name')
- .that.be.a('number').within(1, 100)
- })
- it('name|-min--max', function() {
- var data = Mock.mock({
- 'name|-100--1': 100
- })
- expect(data).to.have.property('name')
- .that.be.a('number').within(-100, -1)
- })
- it('name|-max--min', function() {
- var data = Mock.mock({
- 'name|-1--100': 100
- })
- expect(data).to.have.property('name')
- .that.be.a('number').within(-100, -1)
- })
- it('name|min-min', function() {
- var data = Mock.mock({
- 'name|10-10': 100
- })
- expect(data).to.have.property('name')
- .that.be.a('number').equal(10)
- })
- it('name|count', function() {
- var data = Mock.mock({
- 'name|10': 100
- })
- expect(data).to.have.property('name')
- .that.be.a('number').equal(10)
- })
- // `'name|min-max.dmin-dmax': value`
- // 1 整数部分 2 小数部分
- var RE_FLOAT = /([\+\-]?\d+)\.?(\d+)?/
- function validNumber(number, min, max, dmin, dmax) {
- expect(number).to.be.a('number')
- RE_FLOAT.lastIndex = 0
- var parts = RE_FLOAT.exec('' + number)
- expect(+parts[1]).to.be.a('number').within(min, max)
- expect(parts[2]).to.have.length.within(dmin, dmax)
- }
- it('name|min-max.dmin-dmax', function() {
- var data = Mock.mock({
- 'name|1-10.1-10': 123.456
- })
- validNumber(data.name, 1, 10, 1, 10)
- })
- it('name|min-max.dcount', function() {
- var data = Mock.mock({
- 'name|1-10.10': 123.456
- })
- validNumber(data.name, 1, 10, 10, 10)
- })
- it('name|count.dmin-dmax', function() {
- var data = Mock.mock({
- 'name|10.1-10': 123.456
- })
- validNumber(data.name, 10, 10, 1, 10)
- })
- it('name|count.dcount', function() {
- var data = Mock.mock({
- 'name|10.10': 123.456
- })
- validNumber(data.name, 10, 10, 10, 10)
- })
- it('name|.dmin-dmax', function() {
- var data = Mock.mock({
- 'name|.1-10': 123.456
- })
- validNumber(data.name, 123, 123, 1, 10)
- })
- it('name|.dcount', function() {
- var data = Mock.mock({
- 'name|.10': 123.456
- })
- validNumber(data.name, 123, 123, 10, 10)
- })
- })
- describe('Boolean', function() {
- // `'name|1': value`
- it('name|1', function() {
- var data = Mock.mock({
- 'name|1': true
- })
- expect(data).to.have.property('name')
- .that.be.a('boolean')
- })
- // `'name|min-max': value`
- it('name|min-max', function() {
- var data = Mock.mock({
- 'name|8-2': true
- })
- expect(data).to.have.property('name')
- .that.be.a('boolean')
- })
- })
- describe('Object', function() {
- var methods = {
- GET: '@URL',
- POST: '@URL',
- HEAD: '@URL',
- PUT: '@URL',
- DELETE: '@URL'
- }
- var methodCount, tpl, data
- // `'name|min-max': {}`
- it('name|min-max', function() {
- methodCount = _.keys(methods).length // 5
- for (var min = 0, max; min <= methodCount + 1; min++) {
- tpl = {}
- max = Mock.Random.integer(0, methodCount)
- // methods|0-? |1-? |2-? |3-? |4-? |5-? |6-?
- tpl['methods|' + min + '-' + max] = methods
- data = Mock.mock(tpl)
- expect(_.keys(data.methods)).to.have.length
- .that.within(Math.min(min, max), Math.max(min, max))
- }
- })
- // `'name|count': {}`
- it('name|count', function() {
- methodCount = _.keys(methods).length // 5
- for (var count = 0; count <= methodCount + 1; count++) {
- tpl = {}
- tpl['methods|' + count] = methods
- data = Mock.mock(tpl)
- expect(_.keys(data.methods)).to.have.length(
- Math.min(count, methodCount)
- )
- }
- })
- })
- describe('Array', function() {
- // `'name': [{}, {} ...]`
- it('name', function() {
- var value = [{
- foo: 'foo'
- }, {
- bar: 'bar'
- }, {
- foobar: 'foobar'
- }]
- var data = Mock.mock({
- name: value
- })
- expect(data).to.have.property('name')
- .that.be.an('array').with.length(3)
- .that.not.equal(value)
- expect(data).to.have.property('name')
- for (var i = 0; i < data.name.length; i++) {
- expect(data.name[i]).to.not.equal(value[i])
- expect(data.name[i]).to.deep.equal(value[i])
- }
- })
- // `'name|1': [{}, {} ...]`
- it('name|1: [1, 2, 4, 8]', function() {
- // number array
- var value = [1, 2, 4, 8]
- var data = Mock.mock({
- 'name|1': value
- })
- expect(data).to.have.property('name')
- .that.be.a('number')
- expect(value).to.include(data.name)
- })
- it('name|1: ["GET", "POST", "HEAD", "DELETE"]', function() {
- // string array
- var value = ['GET', 'POST', 'HEAD', 'DELETE']
- var data = Mock.mock({
- 'name|1': value
- })
- expect(data).to.have.property('name')
- .that.be.a('string')
- expect(value).to.include(data.name)
- })
- it('name|1 [{}]', function() {
- // object array
- var value = [{}]
- var data = Mock.mock({
- 'name|1': value
- })
- expect(data).to.have.property('name')
- .that.be.a('object')
- .that.deep.equal({})
- expect(data.name).to.not.equal(value[0])
- })
- it('name|1 [{}, {}, {}]', function() {
- // object array
- var data = Mock.mock({
- 'name|1': [{}, {}, {}]
- })
- expect(data).to.have.property('name')
- .that.be.a('object')
- .that.deep.equal({})
- })
- it('name|1 [{}, {}, {}]', function() {
- // object array
- var value = [{
- method: 'GET'
- }, {
- method: 'POST'
- }, {
- method: 'HEAD'
- }, {
- method: 'DELETE'
- }]
- var data = Mock.mock({
- 'name|1': value
- })
- expect(data).to.have.property('name')
- .that.be.a('object')
- .that.have.property('method')
- .that.be.a('string')
- expect(_.pluck(value, 'method')).include(data.name.method)
- })
- // `'name|+1': [{}, {} ...]`
- it('name|+1: ["a", "b", "c"]', function() {
- var data = Mock.mock({
- 'list|5': [{
- 'name|+1': ['a', 'b', 'c']
- }]
- })
- expect(data).to.have.property('list')
- .that.be.an('array').with.length(5)
- expect(data.list[0].name).to.equal('a')
- expect(data.list[1].name).to.equal('b')
- expect(data.list[2].name).to.equal('c')
- expect(data.list[3].name).to.equal('a')
- expect(data.list[4].name).to.equal('b')
- })
- it('name|+1: ["@integer", "@email", "@boolean"]', function() {
- var data = Mock.mock({
- 'list|5-10': [{
- 'name|+1': ['@integer', '@email', '@boolean']
- }]
- })
- expect(data).to.have.property('list')
- .that.be.an('array').have.length.within(5, 10)
- expect(data.list[0].name).to.be.a('number')
- expect(data.list[1].name).to.be.a('string')
- expect(data.list[2].name).to.be.a('boolean')
- expect(data.list[3].name).to.be.a('number')
- expect(data.list[4].name).to.be.a('string')
- })
- // `'name|min-max': [{}, {} ...]`
- it('name|min-min', function() {
- var data = Mock.mock({
- 'name|1-1': [{}]
- })
- expect(data.name).to.be.an('array').with.length(1)
- _.each(data.name, function(item /*, index*/ ) {
- expect(item).to.deep.equal({})
- })
- })
- it('name|min-max [{}]', function() {
- var data = Mock.mock({
- 'name|1-10': [{}]
- })
- expect(data.name).to.be.an('array').with.length.within(1, 10)
- _.each(data.name, function(item /*, index*/ ) {
- expect(item).to.deep.equal({})
- })
- })
- it('name|max-min [{}]', function() {
- var data = Mock.mock({
- 'name|10-1': [{}]
- })
- expect(data.name).to.be.an('array').with.length.within(1, 10)
- _.each(data.name, function(item /*, index*/ ) {
- expect(item).to.deep.equal({})
- })
- })
- it('name|min-max [{}, {}]', function() {
- var data = Mock.mock({
- 'name|1-10': [{}, {}]
- })
- expect(data.name).to.be.an('array').with.length.within(2, 20)
- _.each(data.name, function(item /*, index*/ ) {
- expect(item).to.deep.equal({})
- })
- })
- it('name|max-min [{}, {}]', function() {
- var data = Mock.mock({
- 'name|10-1': [{}, {}]
- })
- expect(data.name).to.be.an('array').with.length.within(2, 20)
- _.each(data.name, function(item /*, index*/ ) {
- expect(item).to.deep.equal({})
- })
- })
- // `'name|count': [{}, {} ...]`
- it('name|count [{}]', function() {
- var data = Mock.mock({
- 'name|10': [{}]
- })
- expect(data.name).to.be.an('array').with.length(10)
- _.each(data.name, function(item /*, index*/ ) {
- expect(item).to.deep.equal({})
- })
- })
- it('name|count [{}, {}]', function() {
- var data = Mock.mock({
- 'name|10': [{}, {}]
- })
- expect(data.name).to.be.an('array').with.length(20)
- _.each(data.name, function(item /*, index*/ ) {
- expect(item).to.deep.equal({})
- })
- })
- })
- describe('Function', function() {
- // `'name': function(){}`
- it('name: function', function() {
- var data = Mock.mock({
- prop: 'hello',
- name: function( /*root, path*/ ) {
- return this.prop
- }
- })
- expect(data).to.have.property('name')
- .that.be.a('string').equal('hello')
- })
- // 无序的 function
- it('name: function', function() {
- var data = Mock.mock({
- name2: function() {
- return this.prop * 2
- },
- prop: 1,
- name4: function() {
- return this.prop * 4
- }
- })
- expect(data.name2).to.equal(2)
- expect(data.name4).to.equal(4)
- })
- // #25 改变了非函数属性的顺序,查找起来不方便
- it('name: function', function() {
- var data = Mock.mock({
- name: function() {},
- first: '',
- second: '',
- third: ''
- })
- var keys = _.keys(data)
- expect(keys[0]).equal('first')
- expect(keys[1]).equal('second')
- expect(keys[2]).equal('third')
- expect(keys[3]).equal('name')
- })
- })
- /*
- 按照 http://www.regexr.com/ 的 Reference 设计测试用例。
- https://github.com/nuysoft/Mock/blob/7c1e3a686bcc515855f1f583d70ae0ee89acc65e/test/regexp.js#L120
- */
- describe('RegExp', function() {
- function validRegExp(regexp) {
- if (arguments.length > 1) {
- for (var i = 0; i < arguments.length; i++) {
- validRegExp(arguments[i])
- }
- }
- it(regexp, function() {
- var data = Mock.mock(regexp)
- this.test.title += ' => ' + data
- expect(regexp.test(data)).to.be.true
- })
- }
- describe('Character Classes', function() {
- validRegExp(/./)
- validRegExp(
- /[a-z]/,
- /[A-Z]/,
- /[0-9]/
- )
- validRegExp(
- /\w/,
- /\W/,
- /\s/,
- /\S/,
- /\d/,
- /\D/
- )
- validRegExp(
- /[.]/,
- /[\w]/,
- /[\W]/,
- /[\s]/,
- /[\S]/,
- /[\d]/,
- /[\D]/
- )
- validRegExp(
- /[^.]/,
- /[^\w]/,
- /[^\W]/,
- /[^\s]/,
- /[^\S]/,
- /[^\d]/,
- /[^\D]/
- )
- })
- describe('Quantifiers', function() {
- validRegExp(
- /\d?/,
- /\d+/,
- /\d*/
- )
- // {n}, {n,}, {n,m}, {0,1} ?, {1,0} +, {0,} *
- validRegExp(
- /\d{5}/,
- /\d{5,}/,
- /\d{5,10}/,
- /\d{0,1}/,
- /\d{0,}/
- )
- validRegExp(/[\u4E00-\u9FA5]+/) // 汉字
- })
- describe('Anchors', function() {
- validRegExp(/^/)
- validRegExp(/$/)
- validRegExp(/^foo/)
- validRegExp(/foo$/)
- validRegExp(/\bfoo/)
- validRegExp(/\Bfoo/)
- })
- describe('Escaped Characters', function() {
- validRegExp(/\000/)
- validRegExp(/\xFF/)
- validRegExp(/\uFFFF/)
- validRegExp(/\cI/)
- })
- describe('Groups & Lookaround', function() {
- validRegExp(/(ABC)/)
- validRegExp(/(ABC)\1/)
- validRegExp(/(?:ABC)/)
- validRegExp(/(?=ABC)/)
- validRegExp(/(?!ABC)/)
- // validRegExp(/(?<=ABC)/)
- // validRegExp(/(?<!ABC)/)
- validRegExp(/(\d{5,10})|([a-zA-Z]{5,10})/)
- validRegExp(/(?:\d{5,10})|(?:[a-zA-Z]{5,10})/)
- validRegExp(/(.)(\w)(\W)(\s)(\S)(\d)(\D),\1\2\3\4\5\6\7,\1\2\3\4\5\6\7/)
- })
- describe('Quantifiers & Alternation', function() {
- validRegExp(/.+/)
- validRegExp(/.*/)
- validRegExp(/.{1,3}/)
- validRegExp(/.?/)
- validRegExp(/a|bc/)
- validRegExp(/\d{5,10}|[a-zA-Z]{5,10}/)
- })
- describe('Flags', function() {
- // ignoreCase
- // multiline
- // global
- })
- })
- describe('Complex', function() {
- var tpl = {
- 'title': 'Syntax Demo',
- 'string1|1-10': '★',
- 'string2|3': 'value',
- 'number1|+1': 100,
- 'number2|1-100': 100,
- 'number3|1-100.1-10': 1,
- 'number4|123.1-10': 1,
- 'number5|123.3': 1,
- 'number6|123.10': 1.123,
- 'boolean1|1': true,
- 'boolean2|1-2': true,
- 'object1|2-4': {
- '110000': '北京市',
- '120000': '天津市',
- '130000': '河北省',
- '140000': '山西省'
- },
- 'object2|2': {
- '310000': '上海市',
- '320000': '江苏省',
- '330000': '浙江省',
- '340000': '安徽省'
- },
- 'array1|1': ['AMD', 'CMD', 'KMD', 'UMD'],
- 'array2|1-10': ['Mock.js'],
- 'array3|3': ['Mock.js'],
- 'array4|1-10': [{
- 'name|+1': ['Hello', 'Mock.js', '!']
- }],
- 'function': function() {
- return this.title
- },
- 'regexp1': /[a-z][A-Z][0-9]/,
- 'regexp2': /\w\W\s\S\d\D/,
- 'regexp3': /\d{5,10}/,
- 'nested': {
- a: {
- b: {
- c: 'Mock.js'
- }
- }
- },
- 'absolutePath': '@/title @/nested/a/b/c',
- 'relativePath': {
- a: {
- b: {
- c: '@../../../nested/a/b/c'
- }
- }
- },
- }
- it('', function() {
- var data = Mock.mock(tpl)
- this.test.title += JSON.stringify(data /*, null, 4*/ )
- expect(data).to.be.a('object')
- })
- })
- })
|