teabag 0.5.2 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. data/README.md +6 -4
  2. data/app/assets/javascripts/teabag-jasmine.js +2 -2
  3. data/app/assets/javascripts/teabag-mocha.js +348 -21
  4. data/app/assets/javascripts/teabag-qunit.js +2 -2
  5. data/app/assets/javascripts/teabag/mocha.coffee +1 -1
  6. data/app/controllers/teabag/spec_controller.rb +1 -1
  7. data/lib/teabag/console.rb +15 -15
  8. data/lib/teabag/formatters/base_formatter.rb +1 -0
  9. data/lib/teabag/formatters/clean_formatter.rb +13 -0
  10. data/lib/teabag/server.rb +1 -0
  11. data/lib/teabag/suite.rb +22 -1
  12. data/lib/teabag/version.rb +1 -1
  13. data/spec/dummy/log/development.log +4342 -0
  14. data/spec/dummy/log/test.log +1760 -0
  15. data/spec/dummy/tmp/cache/assets/C35/A30/sprockets%2F29906bf540f7d2e081088494b2554989 +0 -0
  16. data/spec/dummy/tmp/cache/assets/C4E/9B0/sprockets%2Fa807397434c9262c3d62da3e91152184 +0 -0
  17. data/spec/dummy/tmp/cache/assets/C59/250/sprockets%2Fa80d3fe493d2476e58c4323996064512 +0 -0
  18. data/spec/dummy/tmp/cache/assets/C75/D50/sprockets%2F5302968a40e08d2c011aa38666d273f6 +0 -0
  19. data/spec/dummy/tmp/cache/assets/C78/F80/sprockets%2F9161622ddd251097a4ab816b8220984c +0 -0
  20. data/spec/dummy/tmp/cache/assets/C7A/EC0/sprockets%2F5c16e4214f5662e1b27932a57c43491b +0 -0
  21. data/spec/dummy/tmp/cache/assets/C89/700/sprockets%2F259935a7704fef0069303ea63fa89408 +0 -0
  22. data/spec/dummy/tmp/cache/assets/C8A/460/sprockets%2F77bffd9959420103906722b404ae8d59 +0 -0
  23. data/spec/dummy/tmp/cache/assets/C91/FA0/sprockets%2F2eb81283f5789ae91a69344552db3856 +0 -0
  24. data/spec/dummy/tmp/cache/assets/C9D/E90/sprockets%2F3045c9533f179d3e1c805d163ed002a0 +0 -0
  25. data/spec/dummy/tmp/cache/assets/CA6/DF0/sprockets%2F7da83747ce56e49393b6b8726587f846 +0 -0
  26. data/spec/dummy/tmp/cache/assets/CA9/C40/sprockets%2F932b7e2cd1e067289ab51190800814df +0 -0
  27. data/spec/dummy/tmp/cache/assets/CAA/0C0/sprockets%2F057b0ce384f16d9202ae84473436cc35 +0 -0
  28. data/spec/dummy/tmp/cache/assets/CAD/410/sprockets%2F651414e5c7e86f05c5108dc71626b25c +0 -0
  29. data/spec/dummy/tmp/cache/assets/CAF/0F0/sprockets%2F6000e67cf3f2377f860c24da7c819701 +0 -0
  30. data/spec/dummy/tmp/cache/assets/CB0/700/sprockets%2F006af6bf0f6b55777b03c4615c853881 +0 -0
  31. data/spec/dummy/tmp/cache/assets/CBB/FA0/sprockets%2F74922109263bdc965b2e9567eec6d154 +0 -0
  32. data/spec/dummy/tmp/cache/assets/CBD/AF0/sprockets%2Fd687ec33822256e9444e8cd04f1b4873 +0 -0
  33. data/spec/dummy/tmp/cache/assets/CBF/630/sprockets%2F707d2db81468088470d476abff35388d +0 -0
  34. data/spec/dummy/tmp/cache/assets/CC2/EC0/sprockets%2F76bf80cb571ca530357f78db78167866 +0 -0
  35. data/spec/dummy/tmp/cache/assets/CCE/C50/sprockets%2Fe12774c2fea852112414bb379a71f31a +0 -0
  36. data/spec/dummy/tmp/cache/assets/CD3/460/sprockets%2F7f3f6802b0b309ed142d0b671c9640c4 +0 -0
  37. data/spec/dummy/tmp/cache/assets/CD9/DD0/sprockets%2Fe5774759168a731da1c1149ecf0e1b03 +0 -0
  38. data/spec/dummy/tmp/cache/assets/CE0/090/sprockets%2F48d5d35ae87d0723318b8bc257fa2237 +0 -0
  39. data/spec/dummy/tmp/cache/assets/CE3/1F0/sprockets%2Fe69a515d3a9d14c669be8871012a7d07 +0 -0
  40. data/spec/dummy/tmp/cache/assets/CE6/270/sprockets%2F2c98152560d18470fec8cf4c6829b4d0 +0 -0
  41. data/spec/dummy/tmp/cache/assets/CE6/7C0/sprockets%2Fa03a2c86ce6724be8542295e1cf24798 +0 -0
  42. data/spec/dummy/tmp/cache/assets/CE7/A60/sprockets%2Ff58eee249aa167d23f8220087bb46684 +0 -0
  43. data/spec/dummy/tmp/cache/assets/CE9/9E0/sprockets%2F135480d497ed7e4884462dc0ef0b80d7 +0 -0
  44. data/spec/dummy/tmp/cache/assets/CEB/680/sprockets%2F67f0794ef8c0576d5c7da34f4437305a +0 -0
  45. data/spec/dummy/tmp/cache/assets/CEB/B40/sprockets%2F1150bf8d912aa100a132251eefaf6045 +0 -0
  46. data/spec/dummy/tmp/cache/assets/CEE/930/sprockets%2Fe196521e15fd8d33e3261d5538fe8f92 +0 -0
  47. data/spec/dummy/tmp/cache/assets/CF4/6F0/sprockets%2Fed96f92571224b862b84d7078b86ded3 +0 -0
  48. data/spec/dummy/tmp/cache/assets/CF8/780/sprockets%2F8845b81ff27cdb57c835836c9f91a265 +0 -0
  49. data/spec/dummy/tmp/cache/assets/CFA/D20/sprockets%2Fb26796b39b3c5d6ed70be7989637a493 +0 -0
  50. data/spec/dummy/tmp/cache/assets/CFB/210/sprockets%2F9104695bfbf9a9d4b94382e6e90487a9 +0 -0
  51. data/spec/dummy/tmp/cache/assets/CFC/380/sprockets%2Fa7443cbd671446a589867dd5f4a4f989 +0 -0
  52. data/spec/dummy/tmp/cache/assets/D00/110/sprockets%2F6a6353b7723a8b21708e0fbfe04bd422 +0 -0
  53. data/spec/dummy/tmp/cache/assets/D03/630/sprockets%2F5d8da32dba6a7be70426a1d554773701 +0 -0
  54. data/spec/dummy/tmp/cache/assets/D04/170/sprockets%2F76ab1dc02e6c7618852708a1e05a2df3 +0 -0
  55. data/spec/dummy/tmp/cache/assets/D04/480/sprockets%2F8bd8f10500b21d2f9d94e4cd1401c936 +0 -0
  56. data/spec/dummy/tmp/cache/assets/D05/8D0/sprockets%2F319f8f235f452343f1ebf03cb262d23d +0 -0
  57. data/spec/dummy/tmp/cache/assets/D09/BF0/sprockets%2F9e6bca5d26f50d9484385d51ba04312c +0 -0
  58. data/spec/dummy/tmp/cache/assets/D0E/570/sprockets%2F90fe371bf8091e88a712124d9cdae260 +0 -0
  59. data/spec/dummy/tmp/cache/assets/D15/4D0/sprockets%2Fdf269dd57c774b930679e00131ca9ae4 +0 -0
  60. data/spec/dummy/tmp/cache/assets/D15/750/sprockets%2F8effdd3e668a4036260a3e370f3b6657 +0 -0
  61. data/spec/dummy/tmp/cache/assets/D17/710/sprockets%2Ffa49fb6823d466e79a195e0cd71340c5 +0 -0
  62. data/spec/dummy/tmp/cache/assets/D1A/D30/sprockets%2F815a5177e9edba0c5c996182ef1b3675 +0 -0
  63. data/spec/dummy/tmp/cache/assets/D1D/560/sprockets%2F1ca784ee7ba1922465147e7f8963eae5 +0 -0
  64. data/spec/dummy/tmp/cache/assets/D1E/AA0/sprockets%2F5c8741a556bc955cd36e61c88582b6dc +0 -0
  65. data/spec/dummy/tmp/cache/assets/D31/9C0/sprockets%2Fbd102a4f5a4985c3519dd6ab0295a1c6 +0 -0
  66. data/spec/dummy/tmp/cache/assets/D35/7C0/sprockets%2Ff536a2606eaf7d542c0985104cb62baf +0 -0
  67. data/spec/dummy/tmp/cache/assets/D37/FF0/sprockets%2F96841ca4cfae32c515077f3f5fc303b2 +0 -0
  68. data/spec/dummy/tmp/cache/assets/D3C/840/sprockets%2Fc6202ec91d567a85bd3d46dc43ea9108 +0 -0
  69. data/spec/dummy/tmp/cache/assets/D44/E90/sprockets%2F05cfc0bf7c9938963d1d1c63248db80d +0 -0
  70. data/spec/dummy/tmp/cache/assets/D45/C30/sprockets%2Fcc744877558178a3adb77c441cadce70 +0 -0
  71. data/spec/dummy/tmp/cache/assets/D47/A90/sprockets%2Fe7ca382b607c595ea6505853f7fb63da +0 -0
  72. data/spec/dummy/tmp/cache/assets/D49/1F0/sprockets%2F773b56f87127c6605e7d1d3faf2b6af6 +0 -0
  73. data/spec/dummy/tmp/cache/assets/D49/A10/sprockets%2Fc4656bd995a6f297c26d19b13aadb963 +0 -0
  74. data/spec/dummy/tmp/cache/assets/D50/D70/sprockets%2Fe2a3e6c95b11e0801a4eebae3a026026 +0 -0
  75. data/spec/dummy/tmp/cache/assets/D51/400/sprockets%2Ff5e433d8a31e80985b75ce598de236be +0 -0
  76. data/spec/dummy/tmp/cache/assets/D54/D80/sprockets%2F631327e25ec20edc723046cdec3bb1c0 +0 -0
  77. data/spec/dummy/tmp/cache/assets/D5A/140/sprockets%2F01f728f33e9bd12104d3b0b1dc7df0a9 +0 -0
  78. data/spec/dummy/tmp/cache/assets/D5C/710/sprockets%2F9427d05cee2caa721241a25a9af1d08f +0 -0
  79. data/spec/dummy/tmp/cache/assets/D5C/CC0/sprockets%2Faa8bf6de211f2765b0a26f112b971f0c +0 -0
  80. data/spec/dummy/tmp/cache/assets/D5E/FA0/sprockets%2Fc81c371ae2d61a6aa1708262fba79e0d +0 -0
  81. data/spec/dummy/tmp/cache/assets/D61/1F0/sprockets%2F0c7a6176d2fc4db00bb9a74d36380fe1 +0 -0
  82. data/spec/dummy/tmp/cache/assets/D67/BC0/sprockets%2F35d2c2b45981ade5a2db2a9c7f37a615 +0 -0
  83. data/spec/dummy/tmp/cache/assets/D69/F90/sprockets%2F6a0795b7b38bd7e6142cd1b88211dade +0 -0
  84. data/spec/dummy/tmp/cache/assets/D6A/950/sprockets%2F429b1806cb7580ebf29f9a12c33cbea6 +0 -0
  85. data/spec/dummy/tmp/cache/assets/D6D/DA0/sprockets%2Fac936bf40b42227a2bf9d474ae9ec149 +0 -0
  86. data/spec/dummy/tmp/cache/assets/D77/B30/sprockets%2F946cf2f17c7eb41037f9ee08ad67ec40 +0 -0
  87. data/spec/dummy/tmp/cache/assets/D78/2F0/sprockets%2F3c61f8915b8f717b1de788e6ecad122c +0 -0
  88. data/spec/dummy/tmp/cache/assets/D7E/C10/sprockets%2F747c98c3cc7494a62dd882752adffb2b +0 -0
  89. data/spec/dummy/tmp/cache/assets/D8C/520/sprockets%2F221cd58a042baac534d27e4cfedc1188 +0 -0
  90. data/spec/dummy/tmp/cache/assets/D8D/370/sprockets%2Fc8ecf0a54ad40917d2607b0d5a6bbb27 +0 -0
  91. data/spec/dummy/tmp/cache/assets/D93/BD0/sprockets%2Ff5e1b60201e08e3ddf8d3de5211f3d5e +0 -0
  92. data/spec/dummy/tmp/cache/assets/DA0/330/sprockets%2Fcbbb4de706387d50f48a72ee6c9c1b80 +0 -0
  93. data/spec/dummy/tmp/cache/assets/DA5/0A0/sprockets%2F7a4b5928cec69ab65afff309a04d6b47 +0 -0
  94. data/spec/dummy/tmp/cache/assets/DAE/6C0/sprockets%2F77c7a8676aeefa73156c55dfcf51cc46 +0 -0
  95. data/spec/dummy/tmp/cache/assets/DB5/040/sprockets%2F9a9da5df88713663b9fbc945facca891 +0 -0
  96. data/spec/dummy/tmp/cache/assets/DC3/230/sprockets%2Fdf52e72eb73be91eccc60182191aed0b +0 -0
  97. data/spec/dummy/tmp/cache/assets/DC7/A10/sprockets%2F84a8af0fcbf401864e1ae5bf092cba94 +0 -0
  98. data/spec/dummy/tmp/cache/assets/DCD/EB0/sprockets%2F4f77f509126ecbced7ea2a5ab290c8d4 +0 -0
  99. data/spec/dummy/tmp/cache/assets/DDB/EF0/sprockets%2Fe790bb18b64df8aa0a9fe94642a9edd8 +0 -0
  100. data/spec/dummy/tmp/cache/assets/DDF/2A0/sprockets%2Fbdb1c7e9d59fd44828d498bee2e1da91 +0 -0
  101. data/spec/dummy/tmp/cache/assets/DE4/140/sprockets%2F139e4ab85d1aacb22c115fa136afdc8a +0 -0
  102. data/spec/dummy/tmp/cache/assets/DEB/110/sprockets%2F2dbdab0ce5babca645cdb5780004f875 +0 -0
  103. data/spec/dummy/tmp/cache/assets/DF6/0E0/sprockets%2F85b10db6e1afe643aba6d396abdd77f0 +0 -0
  104. data/spec/dummy/tmp/cache/assets/DF7/E10/sprockets%2F25e4253aba9a9adcefb72552fb1ff0c8 +0 -0
  105. data/spec/dummy/tmp/cache/assets/DFC/C20/sprockets%2Fd9178ad7e3b401c9fceafd64ea2b50d6 +0 -0
  106. data/spec/dummy/tmp/cache/assets/DFC/C30/sprockets%2Fb50a07cb30b0bd0eec8e98e5de79d65d +0 -0
  107. data/spec/dummy/tmp/cache/assets/E02/6E0/sprockets%2F63d6a5cdb8cefa64ef76b5c6e0fd3720 +0 -0
  108. data/spec/dummy/tmp/cache/assets/E08/BB0/sprockets%2Fefac99af1af28543aef6fb607faa4973 +0 -0
  109. data/spec/dummy/tmp/cache/assets/E08/F20/sprockets%2F4fc5cdcd6974efe7adfe809b30bd6513 +0 -0
  110. data/spec/dummy/tmp/cache/assets/E16/D30/sprockets%2Fd69469e6e7439baacd8df989c0fdacc2 +0 -0
  111. data/spec/dummy/tmp/cache/assets/E17/EF0/sprockets%2Fa291ad64a26afd055dfadabbdf03f154 +0 -0
  112. data/spec/dummy/tmp/cache/assets/E2F/790/sprockets%2F7fac280deaa7ef20a77d5c9b5b9cfc34 +0 -0
  113. data/spec/dummy/tmp/cache/assets/E36/A40/sprockets%2Ff3477eebd69a4f1b8fbdd3f9ef2ba242 +0 -0
  114. data/spec/dummy/tmp/cache/assets/E41/250/sprockets%2F97cf8fe3d7ffaff076f655aefb36da03 +0 -0
  115. data/spec/dummy/tmp/cache/assets/E64/1E0/sprockets%2F81ab4c863fbbdec8dd66afc97ebf034d +0 -0
  116. data/spec/dummy/tmp/cache/assets/E6E/260/sprockets%2Fd9f8ab8b91ef582cc6c99a3ba0dedfe6 +0 -0
  117. data/spec/dummy/tmp/cache/assets/F79/360/sprockets%2F0ce035fefee5ebdabc8efabfbdbd6ee4 +0 -0
  118. data/spec/teabag/console_spec.rb +36 -28
  119. data/spec/teabag/server_spec.rb +4 -2
  120. data/spec/teabag/suite_spec.rb +40 -1
  121. data/vendor/assets/javascripts/{mocha-1.7.4.MIT.LICENSE → mocha-1.8.1.MIT.LICENSE} +0 -0
  122. data/vendor/assets/javascripts/{mocha-1.7.4.js → mocha-1.8.1.js} +346 -19
  123. data/vendor/assets/javascripts/support/chai.MIT.LICENSE +22 -0
  124. data/vendor/assets/javascripts/support/chai.js +3809 -0
  125. data/vendor/assets/javascripts/support/jasmine-jquery.js +13 -10
  126. metadata +17 -6
@@ -4,20 +4,21 @@ require "teabag/console"
4
4
  describe Teabag::Console do
5
5
 
6
6
  let(:server) { mock(start: nil, url: "http://url.com") }
7
+ subject {
8
+ Teabag::Console.any_instance.stub(:start_server)
9
+ instance = Teabag::Console.new
10
+ instance.instance_variable_set(:@server, server)
11
+ instance
12
+ }
7
13
 
8
14
  before do
9
15
  subject.instance_variable_set(:@server, server)
10
- subject.instance_variable_set(:@suites, [:default, :foo])
16
+ subject.stub(:suites).and_return([:default, :foo])
11
17
  Teabag::Environment.stub(:load)
12
18
  end
13
19
 
14
20
  describe "#initialize" do
15
21
 
16
- it "loads the environment" do
17
- Teabag::Environment.should_receive(:load).once
18
- Teabag::Console.new()
19
- end
20
-
21
22
  it "assigns @options" do
22
23
  options = {foo: "bar"}
23
24
  instance = Teabag::Console.new(options)
@@ -30,11 +31,17 @@ describe Teabag::Console do
30
31
  expect(instance.instance_variable_get(:@files)).to eql(files)
31
32
  end
32
33
 
33
- it "assigns @suites" do
34
- instance = Teabag::Console.new({suite: "foo"})
35
- expect(instance.instance_variable_get(:@suites)).to eql(["foo"])
36
- instance = Teabag::Console.new()
37
- expect(instance.instance_variable_get(:@suites)).to eql(Teabag.configuration.suites.keys)
34
+ it "loads the environment" do
35
+ Teabag::Environment.should_receive(:load).once
36
+ Teabag::Console.new()
37
+ end
38
+
39
+ it "starts the server" do
40
+ Teabag::Console.any_instance.should_receive(:start_server).and_call_original
41
+ Teabag::Server.should_receive(:new).and_return(server)
42
+ server.should_receive(:start)
43
+ subject.start_server
44
+ Teabag::Console.new()
38
45
  end
39
46
 
40
47
  end
@@ -43,20 +50,31 @@ describe Teabag::Console do
43
50
 
44
51
  before do
45
52
  STDOUT.stub(:print)
53
+ subject.stub(:run_specs).and_return(0)
54
+ end
55
+
56
+ it "assigns @options" do
57
+ options = {foo: "bar"}
58
+ instance = Teabag::Console.new(options)
59
+ expect(instance.instance_variable_get(:@options)).to eql(options)
46
60
  end
47
61
 
48
- it "starts the server and calls run" do
49
- STDOUT.should_receive(:print).with("Starting server...\n")
50
- subject.should_receive(:start_server)
51
- STDOUT.should_receive(:print).with("Teabag running default suite at http://url.com/teabag/default...\n")
52
- STDOUT.should_receive(:print).with("Teabag running foo suite at http://url.com/teabag/foo...\n")
62
+ it "assigns @files" do
63
+ subject.instance_variable_set(:@files, ["file2"])
64
+ files = ["file1"]
65
+ subject.execute({}, files)
66
+ expect(subject.instance_variable_get(:@files)).to eql(files)
67
+ end
68
+
69
+ it "runs the tests" do
70
+ STDOUT.should_receive(:print).with("Teabag running default suite at http://url.com/teabag/default\n")
71
+ STDOUT.should_receive(:print).with("Teabag running foo suite at http://url.com/teabag/foo\n")
53
72
  subject.should_receive(:run_specs).twice.and_return(2)
54
73
  result = subject.execute
55
74
  expect(result).to be(true)
56
75
  end
57
76
 
58
- it "starts the server and calls run" do
59
- subject.should_receive(:start_server)
77
+ it "tracks the failure count" do
60
78
  subject.should_receive(:run_specs).twice.and_return(0)
61
79
  result = subject.execute
62
80
  expect(result).to be(false)
@@ -64,16 +82,6 @@ describe Teabag::Console do
64
82
 
65
83
  end
66
84
 
67
- describe "#start_server" do
68
-
69
- it "starts the server" do
70
- Teabag::Server.should_receive(:new).and_return(server)
71
- server.should_receive(:start)
72
- subject.start_server
73
- end
74
-
75
- end
76
-
77
85
  describe "#run_specs" do
78
86
 
79
87
  it "calls run_specs on the driver" do
@@ -8,6 +8,7 @@ describe Teabag::Server do
8
8
 
9
9
  before do
10
10
  Teabag::Server.any_instance.stub(find_available_port: 31337)
11
+ STDOUT.stub(:print)
11
12
  end
12
13
 
13
14
  describe "#start" do
@@ -22,6 +23,7 @@ describe Teabag::Server do
22
23
  end
23
24
 
24
25
  it "starts a rack server" do
26
+ STDOUT.should_receive(:print).with("Starting server...\n")
25
27
  server = mock(start: nil)
26
28
  Thread.stub(:new) { |&b| @block = b }
27
29
 
@@ -33,8 +35,8 @@ describe Teabag::Server do
33
35
  end
34
36
 
35
37
  it "rescues errors" do
36
- Thread.should_receive(:new).and_raise("OMG TEABAGGERS!")
37
- expect { subject.start }.to raise_error("Cannot start server: OMG TEABAGGERS!")
38
+ Thread.should_receive(:new).and_raise("OMG!")
39
+ expect { subject.start }.to raise_error("Cannot start server: OMG!")
38
40
  end
39
41
 
40
42
  end
@@ -10,7 +10,28 @@ describe Teabag::Suite do
10
10
  Teabag.configuration.suites = {}
11
11
  end
12
12
 
13
- describe ".new" do
13
+ describe ".all" do
14
+
15
+ it "returns all the suites" do
16
+ Teabag.configuration.suite(:foo) {}
17
+ results = Teabag::Suite.all
18
+ expect(results.first).to be_a(Teabag::Suite)
19
+ expect(results.length).to be(2)
20
+ end
21
+
22
+ end
23
+
24
+ describe ".resolve_spec_for" do
25
+
26
+ it "return a hash with the suite name and path" do
27
+ results = Teabag::Suite.resolve_spec_for("fixture_spec")
28
+ expect(results[:suite]).to eq("default")
29
+ expect(results[:path]).to include("base/fixture_spec.")
30
+ end
31
+
32
+ end
33
+
34
+ describe "#initialize" do
14
35
 
15
36
  it "uses default suite configuration" do
16
37
  expect(subject.config.helper).to eq("spec_helper")
@@ -105,6 +126,24 @@ describe Teabag::Suite do
105
126
 
106
127
  end
107
128
 
129
+ describe "#include_spec_for?" do
130
+
131
+ it "returns the spec if an exact match was found" do
132
+ files = subject.send(:glob)
133
+ expect(subject.include_spec_for?(files.first)).to eq(files.first)
134
+ end
135
+
136
+ it "returns the spec when the file name looks like it could be a match" do
137
+ files = subject.send(:glob)
138
+ expect(subject.include_spec_for?('fixture_spec')).to eq(files.first)
139
+ end
140
+
141
+ it "returns false if a matching spec isn't found" do
142
+ expect(subject.include_spec_for?('_not_a_match_')).to eq(false)
143
+ end
144
+
145
+ end
146
+
108
147
  describe "#specs" do
109
148
 
110
149
  it "converts file names that are in registered asset paths into usable asset urls" do
@@ -58,6 +58,293 @@
58
58
  }); // module: browser/debug.js
59
59
 
60
60
  require.register("browser/diff.js", function(module, exports, require){
61
+ /* See license.txt for terms of usage */
62
+
63
+ /*
64
+ * Text diff implementation.
65
+ *
66
+ * This library supports the following APIS:
67
+ * JsDiff.diffChars: Character by character diff
68
+ * JsDiff.diffWords: Word (as defined by \b regex) diff which ignores whitespace
69
+ * JsDiff.diffLines: Line based diff
70
+ *
71
+ * JsDiff.diffCss: Diff targeted at CSS content
72
+ *
73
+ * These methods are based on the implementation proposed in
74
+ * "An O(ND) Difference Algorithm and its Variations" (Myers, 1986).
75
+ * http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.4.6927
76
+ */
77
+ var JsDiff = (function() {
78
+ function clonePath(path) {
79
+ return { newPos: path.newPos, components: path.components.slice(0) };
80
+ }
81
+ function removeEmpty(array) {
82
+ var ret = [];
83
+ for (var i = 0; i < array.length; i++) {
84
+ if (array[i]) {
85
+ ret.push(array[i]);
86
+ }
87
+ }
88
+ return ret;
89
+ }
90
+ function escapeHTML(s) {
91
+ var n = s;
92
+ n = n.replace(/&/g, "&amp;");
93
+ n = n.replace(/</g, "&lt;");
94
+ n = n.replace(/>/g, "&gt;");
95
+ n = n.replace(/"/g, "&quot;");
96
+
97
+ return n;
98
+ }
99
+
100
+
101
+ var fbDiff = function(ignoreWhitespace) {
102
+ this.ignoreWhitespace = ignoreWhitespace;
103
+ };
104
+ fbDiff.prototype = {
105
+ diff: function(oldString, newString) {
106
+ // Handle the identity case (this is due to unrolling editLength == 0
107
+ if (newString == oldString) {
108
+ return [{ value: newString }];
109
+ }
110
+ if (!newString) {
111
+ return [{ value: oldString, removed: true }];
112
+ }
113
+ if (!oldString) {
114
+ return [{ value: newString, added: true }];
115
+ }
116
+
117
+ newString = this.tokenize(newString);
118
+ oldString = this.tokenize(oldString);
119
+
120
+ var newLen = newString.length, oldLen = oldString.length;
121
+ var maxEditLength = newLen + oldLen;
122
+ var bestPath = [{ newPos: -1, components: [] }];
123
+
124
+ // Seed editLength = 0
125
+ var oldPos = this.extractCommon(bestPath[0], newString, oldString, 0);
126
+ if (bestPath[0].newPos+1 >= newLen && oldPos+1 >= oldLen) {
127
+ return bestPath[0].components;
128
+ }
129
+
130
+ for (var editLength = 1; editLength <= maxEditLength; editLength++) {
131
+ for (var diagonalPath = -1*editLength; diagonalPath <= editLength; diagonalPath+=2) {
132
+ var basePath;
133
+ var addPath = bestPath[diagonalPath-1],
134
+ removePath = bestPath[diagonalPath+1];
135
+ oldPos = (removePath ? removePath.newPos : 0) - diagonalPath;
136
+ if (addPath) {
137
+ // No one else is going to attempt to use this value, clear it
138
+ bestPath[diagonalPath-1] = undefined;
139
+ }
140
+
141
+ var canAdd = addPath && addPath.newPos+1 < newLen;
142
+ var canRemove = removePath && 0 <= oldPos && oldPos < oldLen;
143
+ if (!canAdd && !canRemove) {
144
+ bestPath[diagonalPath] = undefined;
145
+ continue;
146
+ }
147
+
148
+ // Select the diagonal that we want to branch from. We select the prior
149
+ // path whose position in the new string is the farthest from the origin
150
+ // and does not pass the bounds of the diff graph
151
+ if (!canAdd || (canRemove && addPath.newPos < removePath.newPos)) {
152
+ basePath = clonePath(removePath);
153
+ this.pushComponent(basePath.components, oldString[oldPos], undefined, true);
154
+ } else {
155
+ basePath = clonePath(addPath);
156
+ basePath.newPos++;
157
+ this.pushComponent(basePath.components, newString[basePath.newPos], true, undefined);
158
+ }
159
+
160
+ var oldPos = this.extractCommon(basePath, newString, oldString, diagonalPath);
161
+
162
+ if (basePath.newPos+1 >= newLen && oldPos+1 >= oldLen) {
163
+ return basePath.components;
164
+ } else {
165
+ bestPath[diagonalPath] = basePath;
166
+ }
167
+ }
168
+ }
169
+ },
170
+
171
+ pushComponent: function(components, value, added, removed) {
172
+ var last = components[components.length-1];
173
+ if (last && last.added === added && last.removed === removed) {
174
+ // We need to clone here as the component clone operation is just
175
+ // as shallow array clone
176
+ components[components.length-1] =
177
+ {value: this.join(last.value, value), added: added, removed: removed };
178
+ } else {
179
+ components.push({value: value, added: added, removed: removed });
180
+ }
181
+ },
182
+ extractCommon: function(basePath, newString, oldString, diagonalPath) {
183
+ var newLen = newString.length,
184
+ oldLen = oldString.length,
185
+ newPos = basePath.newPos,
186
+ oldPos = newPos - diagonalPath;
187
+ while (newPos+1 < newLen && oldPos+1 < oldLen && this.equals(newString[newPos+1], oldString[oldPos+1])) {
188
+ newPos++;
189
+ oldPos++;
190
+
191
+ this.pushComponent(basePath.components, newString[newPos], undefined, undefined);
192
+ }
193
+ basePath.newPos = newPos;
194
+ return oldPos;
195
+ },
196
+
197
+ equals: function(left, right) {
198
+ var reWhitespace = /\S/;
199
+ if (this.ignoreWhitespace && !reWhitespace.test(left) && !reWhitespace.test(right)) {
200
+ return true;
201
+ } else {
202
+ return left == right;
203
+ }
204
+ },
205
+ join: function(left, right) {
206
+ return left + right;
207
+ },
208
+ tokenize: function(value) {
209
+ return value;
210
+ }
211
+ };
212
+
213
+ var CharDiff = new fbDiff();
214
+
215
+ var WordDiff = new fbDiff(true);
216
+ WordDiff.tokenize = function(value) {
217
+ return removeEmpty(value.split(/(\s+|\b)/));
218
+ };
219
+
220
+ var CssDiff = new fbDiff(true);
221
+ CssDiff.tokenize = function(value) {
222
+ return removeEmpty(value.split(/([{}:;,]|\s+)/));
223
+ };
224
+
225
+ var LineDiff = new fbDiff();
226
+ LineDiff.tokenize = function(value) {
227
+ return value.split(/^/m);
228
+ };
229
+
230
+ return {
231
+ diffChars: function(oldStr, newStr) { return CharDiff.diff(oldStr, newStr); },
232
+ diffWords: function(oldStr, newStr) { return WordDiff.diff(oldStr, newStr); },
233
+ diffLines: function(oldStr, newStr) { return LineDiff.diff(oldStr, newStr); },
234
+
235
+ diffCss: function(oldStr, newStr) { return CssDiff.diff(oldStr, newStr); },
236
+
237
+ createPatch: function(fileName, oldStr, newStr, oldHeader, newHeader) {
238
+ var ret = [];
239
+
240
+ ret.push("Index: " + fileName);
241
+ ret.push("===================================================================");
242
+ ret.push("--- " + fileName + (typeof oldHeader === "undefined" ? "" : "\t" + oldHeader));
243
+ ret.push("+++ " + fileName + (typeof newHeader === "undefined" ? "" : "\t" + newHeader));
244
+
245
+ var diff = LineDiff.diff(oldStr, newStr);
246
+ if (!diff[diff.length-1].value) {
247
+ diff.pop(); // Remove trailing newline add
248
+ }
249
+ diff.push({value: "", lines: []}); // Append an empty value to make cleanup easier
250
+
251
+ function contextLines(lines) {
252
+ return lines.map(function(entry) { return ' ' + entry; });
253
+ }
254
+ function eofNL(curRange, i, current) {
255
+ var last = diff[diff.length-2],
256
+ isLast = i === diff.length-2,
257
+ isLastOfType = i === diff.length-3 && (current.added === !last.added || current.removed === !last.removed);
258
+
259
+ // Figure out if this is the last line for the given file and missing NL
260
+ if (!/\n$/.test(current.value) && (isLast || isLastOfType)) {
261
+ curRange.push('\');
262
+ }
263
+ }
264
+
265
+ var oldRangeStart = 0, newRangeStart = 0, curRange = [],
266
+ oldLine = 1, newLine = 1;
267
+ for (var i = 0; i < diff.length; i++) {
268
+ var current = diff[i],
269
+ lines = current.lines || current.value.replace(/\n$/, "").split("\n");
270
+ current.lines = lines;
271
+
272
+ if (current.added || current.removed) {
273
+ if (!oldRangeStart) {
274
+ var prev = diff[i-1];
275
+ oldRangeStart = oldLine;
276
+ newRangeStart = newLine;
277
+
278
+ if (prev) {
279
+ curRange = contextLines(prev.lines.slice(-4));
280
+ oldRangeStart -= curRange.length;
281
+ newRangeStart -= curRange.length;
282
+ }
283
+ }
284
+ curRange.push.apply(curRange, lines.map(function(entry) { return (current.added?"+":"-") + entry; }));
285
+ eofNL(curRange, i, current);
286
+
287
+ if (current.added) {
288
+ newLine += lines.length;
289
+ } else {
290
+ oldLine += lines.length;
291
+ }
292
+ } else {
293
+ if (oldRangeStart) {
294
+ // Close out any changes that have been output (or join overlapping)
295
+ if (lines.length <= 8 && i < diff.length-2) {
296
+ // Overlapping
297
+ curRange.push.apply(curRange, contextLines(lines));
298
+ } else {
299
+ // end the range and output
300
+ var contextSize = Math.min(lines.length, 4);
301
+ ret.push(
302
+ "@@ -" + oldRangeStart + "," + (oldLine-oldRangeStart+contextSize)
303
+ + " +" + newRangeStart + "," + (newLine-newRangeStart+contextSize)
304
+ + " @@");
305
+ ret.push.apply(ret, curRange);
306
+ ret.push.apply(ret, contextLines(lines.slice(0, contextSize)));
307
+ if (lines.length <= 4) {
308
+ eofNL(ret, i, current);
309
+ }
310
+
311
+ oldRangeStart = 0; newRangeStart = 0; curRange = [];
312
+ }
313
+ }
314
+ oldLine += lines.length;
315
+ newLine += lines.length;
316
+ }
317
+ }
318
+
319
+ return ret.join('\n') + '\n';
320
+ },
321
+
322
+ convertChangesToXML: function(changes){
323
+ var ret = [];
324
+ for ( var i = 0; i < changes.length; i++) {
325
+ var change = changes[i];
326
+ if (change.added) {
327
+ ret.push("<ins>");
328
+ } else if (change.removed) {
329
+ ret.push("<del>");
330
+ }
331
+
332
+ ret.push(escapeHTML(change.value));
333
+
334
+ if (change.added) {
335
+ ret.push("</ins>");
336
+ } else if (change.removed) {
337
+ ret.push("</del>");
338
+ }
339
+ }
340
+ return ret.join("");
341
+ }
342
+ };
343
+ })();
344
+
345
+ if (typeof module !== "undefined") {
346
+ module.exports = JsDiff;
347
+ }
61
348
 
62
349
  }); // module: browser/diff.js
63
350
 
@@ -494,7 +781,9 @@
494
781
  * Inherit from `Runnable.prototype`.
495
782
  */
496
783
 
497
- Hook.prototype = new Runnable;
784
+ function F(){};
785
+ F.prototype = Runnable.prototype;
786
+ Hook.prototype = new F;
498
787
  Hook.prototype.constructor = Hook;
499
788
 
500
789
 
@@ -1005,6 +1294,7 @@
1005
1294
  * - `reporter` reporter instance, defaults to `mocha.reporters.Dot`
1006
1295
  * - `globals` array of accepted globals
1007
1296
  * - `timeout` timeout in milliseconds
1297
+ * - `bail` bail on the first test failure
1008
1298
  * - `slow` milliseconds to wait before considering a test slow
1009
1299
  * - `ignoreLeaks` ignore global leaks
1010
1300
  * - `grep` string or regexp to filter tests with
@@ -1020,11 +1310,25 @@
1020
1310
  this.grep(options.grep);
1021
1311
  this.suite = new exports.Suite('', new exports.Context);
1022
1312
  this.ui(options.ui);
1313
+ this.bail(options.bail);
1023
1314
  this.reporter(options.reporter);
1024
1315
  if (options.timeout) this.timeout(options.timeout);
1025
1316
  if (options.slow) this.slow(options.slow);
1026
1317
  }
1027
1318
 
1319
+ /**
1320
+ * Enable or disable bailing on the first failure.
1321
+ *
1322
+ * @param {Boolean} [bail]
1323
+ * @api public
1324
+ */
1325
+
1326
+ Mocha.prototype.bail = function(bail){
1327
+ if (0 == arguments.length) bail = true;
1328
+ this.suite.bail(bail);
1329
+ return this;
1330
+ };
1331
+
1028
1332
  /**
1029
1333
  * Add test `file`.
1030
1334
  *
@@ -1040,7 +1344,7 @@
1040
1344
  /**
1041
1345
  * Set reporter to `reporter`, defaults to "dot".
1042
1346
  *
1043
- * @param {String|Function} reporter name of a reporter or a reporter constructor
1347
+ * @param {String|Function} reporter name or constructor
1044
1348
  * @api public
1045
1349
  */
1046
1350
 
@@ -1846,7 +2150,9 @@
1846
2150
  * Inherit from `Base.prototype`.
1847
2151
  */
1848
2152
 
1849
- Dot.prototype = new Base;
2153
+ function F(){};
2154
+ F.prototype = Base.prototype;
2155
+ Dot.prototype = new F;
1850
2156
  Dot.prototype.constructor = Dot;
1851
2157
 
1852
2158
  }); // module: reporters/dot.js
@@ -2073,7 +2379,7 @@
2073
2379
 
2074
2380
  on(h2, 'click', function(){
2075
2381
  pre.style.display = 'none' == pre.style.display
2076
- ? 'inline-block'
2382
+ ? 'block'
2077
2383
  : 'none';
2078
2384
  });
2079
2385
 
@@ -2578,7 +2884,9 @@
2578
2884
  * Inherit from `Base.prototype`.
2579
2885
  */
2580
2886
 
2581
- Landing.prototype = new Base;
2887
+ function F(){};
2888
+ F.prototype = Base.prototype;
2889
+ Landing.prototype = new F;
2582
2890
  Landing.prototype.constructor = Landing;
2583
2891
 
2584
2892
  }); // module: reporters/landing.js
@@ -2647,7 +2955,9 @@
2647
2955
  * Inherit from `Base.prototype`.
2648
2956
  */
2649
2957
 
2650
- List.prototype = new Base;
2958
+ function F(){};
2959
+ F.prototype = Base.prototype;
2960
+ List.prototype = new F;
2651
2961
  List.prototype.constructor = List;
2652
2962
 
2653
2963
 
@@ -2679,7 +2989,6 @@
2679
2989
 
2680
2990
  var self = this
2681
2991
  , stats = this.stats
2682
- , total = runner.total
2683
2992
  , level = 0
2684
2993
  , buf = '';
2685
2994
 
@@ -2786,7 +3095,9 @@
2786
3095
  * Inherit from `Base.prototype`.
2787
3096
  */
2788
3097
 
2789
- Min.prototype = new Base;
3098
+ function F(){};
3099
+ F.prototype = Base.prototype;
3100
+ Min.prototype = new F;
2790
3101
  Min.prototype.constructor = Min;
2791
3102
 
2792
3103
  }); // module: reporters/min.js
@@ -3050,7 +3361,9 @@
3050
3361
  * Inherit from `Base.prototype`.
3051
3362
  */
3052
3363
 
3053
- NyanCat.prototype = new Base;
3364
+ function F(){};
3365
+ F.prototype = Base.prototype;
3366
+ NyanCat.prototype = new F;
3054
3367
  NyanCat.prototype.constructor = NyanCat;
3055
3368
 
3056
3369
 
@@ -3142,7 +3455,9 @@
3142
3455
  * Inherit from `Base.prototype`.
3143
3456
  */
3144
3457
 
3145
- Progress.prototype = new Base;
3458
+ function F(){};
3459
+ F.prototype = Base.prototype;
3460
+ Progress.prototype = new F;
3146
3461
  Progress.prototype.constructor = Progress;
3147
3462
 
3148
3463
 
@@ -3235,7 +3550,9 @@
3235
3550
  * Inherit from `Base.prototype`.
3236
3551
  */
3237
3552
 
3238
- Spec.prototype = new Base;
3553
+ function F(){};
3554
+ F.prototype = Base.prototype;
3555
+ Spec.prototype = new F;
3239
3556
  Spec.prototype.constructor = Spec;
3240
3557
 
3241
3558
 
@@ -3271,7 +3588,7 @@
3271
3588
  , stats = this.stats
3272
3589
  , n = 1
3273
3590
  , passes = 0
3274
- , failures = 1;
3591
+ , failures = 0;
3275
3592
 
3276
3593
  runner.on('start', function(){
3277
3594
  var total = runner.grepTotal(runner.suite);
@@ -3294,7 +3611,7 @@
3294
3611
  runner.on('fail', function(test, err){
3295
3612
  failures++;
3296
3613
  console.log('not ok %d %s', n, title(test));
3297
- console.log(err.stack.replace(/^/gm, ' '));
3614
+ if (err.stack) console.log(err.stack.replace(/^/gm, ' '));
3298
3615
  });
3299
3616
 
3300
3617
  runner.on('end', function(){
@@ -3454,7 +3771,9 @@
3454
3771
  * Inherit from `Base.prototype`.
3455
3772
  */
3456
3773
 
3457
- XUnit.prototype = new Base;
3774
+ function F(){};
3775
+ F.prototype = Base.prototype;
3776
+ XUnit.prototype = new F;
3458
3777
  XUnit.prototype.constructor = XUnit;
3459
3778
 
3460
3779
 
@@ -3562,7 +3881,9 @@
3562
3881
  * Inherit from `EventEmitter.prototype`.
3563
3882
  */
3564
3883
 
3565
- Runnable.prototype = new EventEmitter;
3884
+ function F(){};
3885
+ F.prototype = EventEmitter.prototype;
3886
+ Runnable.prototype = new F;
3566
3887
  Runnable.prototype.constructor = Runnable;
3567
3888
 
3568
3889
 
@@ -3707,7 +4028,7 @@
3707
4028
  if (this.async) {
3708
4029
  try {
3709
4030
  this.fn.call(ctx, function(err){
3710
- if (toString.call(err) === "[object Error]") return done(err);
4031
+ if (err instanceof Error || toString.call(err) === "[object Error]") return done(err);
3711
4032
  if (null != err) return done(new Error('done() invoked with non-Error: ' + err));
3712
4033
  done();
3713
4034
  });
@@ -3801,7 +4122,9 @@
3801
4122
  * Inherit from `EventEmitter.prototype`.
3802
4123
  */
3803
4124
 
3804
- Runner.prototype = new EventEmitter;
4125
+ function F(){};
4126
+ F.prototype = EventEmitter.prototype;
4127
+ Runner.prototype = new F;
3805
4128
  Runner.prototype.constructor = Runner;
3806
4129
 
3807
4130
 
@@ -4341,7 +4664,9 @@
4341
4664
  * Inherit from `EventEmitter.prototype`.
4342
4665
  */
4343
4666
 
4344
- Suite.prototype = new EventEmitter;
4667
+ function F(){};
4668
+ F.prototype = EventEmitter.prototype;
4669
+ Suite.prototype = new F;
4345
4670
  Suite.prototype.constructor = Suite;
4346
4671
 
4347
4672
 
@@ -4606,7 +4931,9 @@
4606
4931
  * Inherit from `Runnable.prototype`.
4607
4932
  */
4608
4933
 
4609
- Test.prototype = new Runnable;
4934
+ function F(){};
4935
+ F.prototype = Runnable.prototype;
4936
+ Test.prototype = new F;
4610
4937
  Test.prototype.constructor = Test;
4611
4938
 
4612
4939