second_curtain 0.1.5 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +8 -8
- data/bin/second_curtain +35 -40
- data/lib/second_curtain.rb +4 -0
- data/lib/second_curtain/kaleidoscope_command.rb +18 -0
- data/lib/second_curtain/parser.rb +51 -0
- data/lib/second_curtain/template.mustache.html +176 -0
- data/lib/second_curtain/test_suite.rb +22 -0
- data/lib/second_curtain/upload.rb +0 -4
- data/lib/second_curtain/upload_manager.rb +3 -5
- data/lib/second_curtain/web_preview.rb +16 -0
- data/lib/second_curtain/xcode_test_case.rb +46 -0
- metadata +23 -2
checksums.yaml
CHANGED
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
---
|
|
2
2
|
!binary "U0hBMQ==":
|
|
3
3
|
metadata.gz: !binary |-
|
|
4
|
-
|
|
4
|
+
ZmUyZjgyMzZjMWNmMzE2NDY3ZDk2NWIyYmQwOWJkNTFjYWFlNDYwNw==
|
|
5
5
|
data.tar.gz: !binary |-
|
|
6
|
-
|
|
6
|
+
ZjYyZTc1NDRiOTA5NzAzOGUzMzU5ZjBhZWZlNzEzOGNkNDRlMTg0YQ==
|
|
7
7
|
SHA512:
|
|
8
8
|
metadata.gz: !binary |-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
N2RjOWMyMDc0MjE3NjJiZmI3MTgzOGNjM2I4N2FhZTRhZjRiNDMwMDJmNzlm
|
|
10
|
+
Y2M0MTcwZDkxYjhkZTk4MGZiYjdhYjNmMGM0N2Q1MWZlYWExM2FhNTgwYTE0
|
|
11
|
+
ZGM0YzIxNjFmOGRlNjEzZmMwYjc4N2Y5ZWQ2YjJiZmViYTNhNmM=
|
|
12
12
|
data.tar.gz: !binary |-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
13
|
+
YTFhOGJhOTExOWFmY2I4NzE5YmU3M2M0ODZjYzRkMjY0MmRkODM2YjRmZWZl
|
|
14
|
+
Y2VlNTRkZDUxYTc1OWQ4OTFjYzZkYTY2NmNhOWZjOWE5Zjk3OWUyM2YzZDk3
|
|
15
|
+
MTMxNjM3Yzk2YmRhYTA2ZjZlNGZhNjkzMGIyZjhjOGMzZWFhZDQ=
|
data/bin/second_curtain
CHANGED
|
@@ -2,56 +2,51 @@
|
|
|
2
2
|
|
|
3
3
|
require 'second_curtain'
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
parser = Parser.new()
|
|
6
6
|
|
|
7
7
|
ARGF.each_line do |line|
|
|
8
|
-
|
|
8
|
+
parser.parse_line(line)
|
|
9
9
|
print line
|
|
10
10
|
end
|
|
11
11
|
|
|
12
|
-
|
|
12
|
+
if parser.has_failing_commands
|
|
13
|
+
bucket_name = ENV['UPLOAD_IOS_SNAPSHOT_BUCKET_NAME']
|
|
13
14
|
|
|
14
|
-
if bucket_name == nil
|
|
15
|
-
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
aws_key = ENV['AWS_ACCESS_KEY_ID']
|
|
19
|
-
aws_secret = ENV['AWS_SECRET_ACCESS_KEY']
|
|
20
|
-
if aws_key == nil || aws_secret == nil
|
|
21
|
-
abort "error: Second Curtain AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY must be defined as environment variables"
|
|
22
|
-
end
|
|
15
|
+
if bucket_name == nil
|
|
16
|
+
abort "error: Second Curtain bucket name must be specified in environment UPLOAD_IOS_SNAPSHOT_BUCKET_NAME variable"
|
|
17
|
+
end
|
|
23
18
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
19
|
+
aws_key = ENV['AWS_ACCESS_KEY_ID']
|
|
20
|
+
aws_secret = ENV['AWS_SECRET_ACCESS_KEY']
|
|
21
|
+
if aws_key == nil || aws_secret == nil
|
|
22
|
+
abort "error: Second Curtain AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY must be defined as environment variables"
|
|
23
|
+
end
|
|
28
24
|
|
|
29
|
-
|
|
30
|
-
if !
|
|
31
|
-
|
|
32
|
-
end
|
|
25
|
+
path_prefix = ENV['UPLOAD_IOS_SNAPSHOT_BUCKET_PREFIX'] || '/'
|
|
26
|
+
if !path_prefix.end_with?('/')
|
|
27
|
+
path_prefix += '/'
|
|
28
|
+
end
|
|
33
29
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
end
|
|
30
|
+
folder_name = ENV['UPLOAD_IOS_SNAPSHOT_FOLDER_NAME']
|
|
31
|
+
if !folder_name
|
|
32
|
+
folder_name = ENV['TRAVIS_JOB_ID']
|
|
33
|
+
end
|
|
38
34
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
input.each do |line|
|
|
44
|
-
if line.start_with?('ksdiff')
|
|
45
|
-
parts = line.split(/"/)
|
|
46
|
-
if (parts.count >= 4)
|
|
47
|
-
expected_path = parts[1]
|
|
48
|
-
actual_path = parts[3]
|
|
49
|
-
manager.enqueue_upload(expected_path, actual_path)
|
|
50
|
-
end
|
|
35
|
+
if !folder_name
|
|
36
|
+
now = DateTime.now()
|
|
37
|
+
folder_name = now.strftime('%Y-%m-%d--%H-%M')
|
|
51
38
|
end
|
|
52
|
-
end
|
|
53
39
|
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
40
|
+
s3 = AWS::S3.new
|
|
41
|
+
bucket = s3.buckets[bucket_name]
|
|
42
|
+
manager = UploadManager.new(bucket, path_prefix)
|
|
43
|
+
|
|
44
|
+
parser.failing_commands.each do |command|
|
|
45
|
+
manager.enqueue_upload(command.before_path, command.after_path)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
failures_address = manager.upload(folder_name)
|
|
49
|
+
if failures_address
|
|
50
|
+
$stderr.puts ("Failures: " + failures_address)
|
|
51
|
+
end
|
|
57
52
|
end
|
data/lib/second_curtain.rb
CHANGED
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class KaleidoscopeCommand
|
|
2
|
+
attr_accessor :fails
|
|
3
|
+
attr_accessor :before_path
|
|
4
|
+
attr_accessor :after_path
|
|
5
|
+
|
|
6
|
+
def self.command_from_line(line)
|
|
7
|
+
components = line.split("\"")
|
|
8
|
+
if components.count >= 4
|
|
9
|
+
KaleidoscopeCommand.new(components[1], components[3])
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def initialize(before_path, after_path)
|
|
14
|
+
@before_path = before_path
|
|
15
|
+
@after_path = after_path
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
require 'second_curtain/xcode_test_case'
|
|
2
|
+
require 'second_curtain/test_suite'
|
|
3
|
+
require 'second_curtain/kaleidoscope_command'
|
|
4
|
+
|
|
5
|
+
# Lifted from https://github.com/orta/Snapshots/blob/master/SnapshotDiffs/ORLogReader.m
|
|
6
|
+
|
|
7
|
+
class Parser
|
|
8
|
+
def initialize
|
|
9
|
+
@test_suites = []
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def parse_line(line)
|
|
13
|
+
if line.include?("Test Suite")
|
|
14
|
+
test_suite = TestSuite.suite_from_line(line)
|
|
15
|
+
@test_suites.push test_suite unless test_suite == nil
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
if line.include?("Test Case") && latest_test_suite
|
|
19
|
+
if line.include?("started.")
|
|
20
|
+
test_case = XcodeTestCase.test_case_from_line(line)
|
|
21
|
+
latest_test_suite.test_cases.push test_case unless test_case == nil
|
|
22
|
+
elsif line.include?("' failed (")
|
|
23
|
+
latest_test_suite.latest_test_case.latest_command.fails = true
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
if line.include?("ksdiff") && latest_test_suite
|
|
28
|
+
command_string = extract_command_string_from_line(line)
|
|
29
|
+
command = KaleidoscopeCommand.command_from_line(command_string)
|
|
30
|
+
if command != nil
|
|
31
|
+
latest_test_suite.latest_test_case.add_command command
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def latest_test_suite
|
|
37
|
+
@test_suites.last
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def extract_command_string_from_line(line)
|
|
41
|
+
return line.split("diff:\n").last
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def failing_commands
|
|
45
|
+
@test_suites.map { |e| e.test_cases }.flatten.map { |e| e.commands }.flatten.select { |e| e.fails }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def has_failing_commands
|
|
49
|
+
failing_commands.count > 0
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
<html>
|
|
2
|
+
<head>
|
|
3
|
+
<style>
|
|
4
|
+
html {
|
|
5
|
+
background-color:#FFFAFC;
|
|
6
|
+
font-family: 'Josefin Sans', sans-serif;
|
|
7
|
+
color:#BE99CC;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
nav {
|
|
11
|
+
height:60px;
|
|
12
|
+
background-color:white;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
nav h1 {
|
|
16
|
+
display:inline-block;
|
|
17
|
+
margin-top:6px;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
nav ul {
|
|
21
|
+
margin-top:18px;
|
|
22
|
+
display:inline-block;
|
|
23
|
+
float:right;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
nav ul li {
|
|
27
|
+
float:right;
|
|
28
|
+
margin-left:30px;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
nav ul li a {
|
|
32
|
+
text-decoration: none;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
h1 {
|
|
36
|
+
font-weight: 400;
|
|
37
|
+
font-size:48px;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
h2, nav ul, h3 {
|
|
41
|
+
font-weight: 300;
|
|
42
|
+
font-size:24px;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
.content {
|
|
46
|
+
width:1200px;
|
|
47
|
+
margin:0 auto;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
img.before {
|
|
51
|
+
border: 2px solid #9FCC99;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
img.after {
|
|
55
|
+
border: 2px solid #CC7B7B;
|
|
56
|
+
background-color:green;
|
|
57
|
+
pointer-events:none;
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
article.content {
|
|
61
|
+
margin:36px auto;
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
section img {
|
|
65
|
+
background-repeat: repeat-x repeat-y;
|
|
66
|
+
background-image: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACgAAAAoCAYAAACM/rhtAAAAeUlEQVRYCe3TIQ7AIBBE0QXRut7/mlSVGorE/22C+KtAzIa8DKW3Z0TiHNeZuC2ipm77YZkPpKgKKkgFaN4OKkgFaN4OKkgFaN4OKkgFaL6MOXTJmn/vvl7x2U9CCRVUkArQvB1UkArQvB1UkArQvB1UkArQ/PYd/AC9pgss8BZEQAAAAABJRU5ErkJggg==);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
section div.onion {
|
|
70
|
+
position: relative;
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
section div.onion p {
|
|
74
|
+
text-align:center;
|
|
75
|
+
position:absolute;
|
|
76
|
+
top:600px;
|
|
77
|
+
left:0px;
|
|
78
|
+
width:100%;
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
section div.onion img {
|
|
82
|
+
position:absolute;
|
|
83
|
+
top:1px;
|
|
84
|
+
left:1;
|
|
85
|
+
max-height:520px;
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
section {
|
|
89
|
+
background-color:white;
|
|
90
|
+
height:660px;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
</style>
|
|
94
|
+
<link href='http://fonts.googleapis.com/css?family=Josefin+Sans:300,400' rel='stylesheet' type='text/css'>
|
|
95
|
+
<script src="http://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script>
|
|
96
|
+
</head>
|
|
97
|
+
|
|
98
|
+
<body>
|
|
99
|
+
<nav>
|
|
100
|
+
<div class="content">
|
|
101
|
+
<h1>Second Curtain</h1>
|
|
102
|
+
<ul>
|
|
103
|
+
<!-- <li><a href="file:///Users/orta/dev/ruby/second_curtain/lib/second_curtain/template.mustache.html">artsy/eigen#1112</a></li>
|
|
104
|
+
<li><a href="file:///Users/orta/dev/ruby/second_curtain/lib/second_curtain/template.mustache.html">travis#5240812</a></li> -->
|
|
105
|
+
</ul>
|
|
106
|
+
</div>
|
|
107
|
+
</nav>
|
|
108
|
+
|
|
109
|
+
<!-- <article class="content">
|
|
110
|
+
<h1>ARAmbiguousSplitStackViewSpec</h1>
|
|
111
|
+
<h3>Single Stack With Two Views</h3>
|
|
112
|
+
<section >
|
|
113
|
+
<div class="onion">
|
|
114
|
+
<img class="before" src="https://github.com/artsy/energy/raw/2c1b4d2eb35bba900c697a11e7e65f22024e7d0a/ArtsyFolio%20Tests/ReferenceImages/ARAmbiguousSplitStackViewSpec/single_stack_with_two_views%402x.png?raw=true">
|
|
115
|
+
<img class="after" src="https://github.com/orta/energy/raw/5978c5bfa0dfdd0317f2b68e855efad7d7dc7df2/ArtsyFolio%20Tests/ReferenceImages/ARAmbiguousSplitStackViewSpec/single_stack_with_two_views%402x.png?raw=true">
|
|
116
|
+
<p>320 x 280</p>
|
|
117
|
+
</div>
|
|
118
|
+
</section>
|
|
119
|
+
</article> -->
|
|
120
|
+
|
|
121
|
+
{{#uploads}}
|
|
122
|
+
<article class="content">
|
|
123
|
+
<section>
|
|
124
|
+
<div class="onion">
|
|
125
|
+
<img class="before" src="{{ uploaded_expected_url }}">
|
|
126
|
+
<img class="after" src="{{ uploaded_actual_url }}">
|
|
127
|
+
</div>
|
|
128
|
+
</section>
|
|
129
|
+
</article>
|
|
130
|
+
{{/uploads}}
|
|
131
|
+
|
|
132
|
+
|
|
133
|
+
<script>
|
|
134
|
+
|
|
135
|
+
/*!
|
|
136
|
+
* imagesLoaded PACKAGED v3.1.8
|
|
137
|
+
* JavaScript is all like "You images are done yet or what?"
|
|
138
|
+
* MIT License
|
|
139
|
+
*/
|
|
140
|
+
|
|
141
|
+
(function(){function e(){}function t(e,t){for(var n=e.length;n--;)if(e[n].listener===t)return n;return-1}function n(e){return function(){return this[e].apply(this,arguments)}}var i=e.prototype,r=this,o=r.EventEmitter;i.getListeners=function(e){var t,n,i=this._getEvents();if("object"==typeof e){t={};for(n in i)i.hasOwnProperty(n)&&e.test(n)&&(t[n]=i[n])}else t=i[e]||(i[e]=[]);return t},i.flattenListeners=function(e){var t,n=[];for(t=0;e.length>t;t+=1)n.push(e[t].listener);return n},i.getListenersAsObject=function(e){var t,n=this.getListeners(e);return n instanceof Array&&(t={},t[e]=n),t||n},i.addListener=function(e,n){var i,r=this.getListenersAsObject(e),o="object"==typeof n;for(i in r)r.hasOwnProperty(i)&&-1===t(r[i],n)&&r[i].push(o?n:{listener:n,once:!1});return this},i.on=n("addListener"),i.addOnceListener=function(e,t){return this.addListener(e,{listener:t,once:!0})},i.once=n("addOnceListener"),i.defineEvent=function(e){return this.getListeners(e),this},i.defineEvents=function(e){for(var t=0;e.length>t;t+=1)this.defineEvent(e[t]);return this},i.removeListener=function(e,n){var i,r,o=this.getListenersAsObject(e);for(r in o)o.hasOwnProperty(r)&&(i=t(o[r],n),-1!==i&&o[r].splice(i,1));return this},i.off=n("removeListener"),i.addListeners=function(e,t){return this.manipulateListeners(!1,e,t)},i.removeListeners=function(e,t){return this.manipulateListeners(!0,e,t)},i.manipulateListeners=function(e,t,n){var i,r,o=e?this.removeListener:this.addListener,s=e?this.removeListeners:this.addListeners;if("object"!=typeof t||t instanceof RegExp)for(i=n.length;i--;)o.call(this,t,n[i]);else for(i in t)t.hasOwnProperty(i)&&(r=t[i])&&("function"==typeof r?o.call(this,i,r):s.call(this,i,r));return this},i.removeEvent=function(e){var t,n=typeof e,i=this._getEvents();if("string"===n)delete i[e];else if("object"===n)for(t in i)i.hasOwnProperty(t)&&e.test(t)&&delete i[t];else delete this._events;return this},i.removeAllListeners=n("removeEvent"),i.emitEvent=function(e,t){var n,i,r,o,s=this.getListenersAsObject(e);for(r in s)if(s.hasOwnProperty(r))for(i=s[r].length;i--;)n=s[r][i],n.once===!0&&this.removeListener(e,n.listener),o=n.listener.apply(this,t||[]),o===this._getOnceReturnValue()&&this.removeListener(e,n.listener);return this},i.trigger=n("emitEvent"),i.emit=function(e){var t=Array.prototype.slice.call(arguments,1);return this.emitEvent(e,t)},i.setOnceReturnValue=function(e){return this._onceReturnValue=e,this},i._getOnceReturnValue=function(){return this.hasOwnProperty("_onceReturnValue")?this._onceReturnValue:!0},i._getEvents=function(){return this._events||(this._events={})},e.noConflict=function(){return r.EventEmitter=o,e},"function"==typeof define&&define.amd?define("eventEmitter/EventEmitter",[],function(){return e}):"object"==typeof module&&module.exports?module.exports=e:this.EventEmitter=e}).call(this),function(e){function t(t){var n=e.event;return n.target=n.target||n.srcElement||t,n}var n=document.documentElement,i=function(){};n.addEventListener?i=function(e,t,n){e.addEventListener(t,n,!1)}:n.attachEvent&&(i=function(e,n,i){e[n+i]=i.handleEvent?function(){var n=t(e);i.handleEvent.call(i,n)}:function(){var n=t(e);i.call(e,n)},e.attachEvent("on"+n,e[n+i])});var r=function(){};n.removeEventListener?r=function(e,t,n){e.removeEventListener(t,n,!1)}:n.detachEvent&&(r=function(e,t,n){e.detachEvent("on"+t,e[t+n]);try{delete e[t+n]}catch(i){e[t+n]=void 0}});var o={bind:i,unbind:r};"function"==typeof define&&define.amd?define("eventie/eventie",o):e.eventie=o}(this),function(e,t){"function"==typeof define&&define.amd?define(["eventEmitter/EventEmitter","eventie/eventie"],function(n,i){return t(e,n,i)}):"object"==typeof exports?module.exports=t(e,require("wolfy87-eventemitter"),require("eventie")):e.imagesLoaded=t(e,e.EventEmitter,e.eventie)}(window,function(e,t,n){function i(e,t){for(var n in t)e[n]=t[n];return e}function r(e){return"[object Array]"===d.call(e)}function o(e){var t=[];if(r(e))t=e;else if("number"==typeof e.length)for(var n=0,i=e.length;i>n;n++)t.push(e[n]);else t.push(e);return t}function s(e,t,n){if(!(this instanceof s))return new s(e,t);"string"==typeof e&&(e=document.querySelectorAll(e)),this.elements=o(e),this.options=i({},this.options),"function"==typeof t?n=t:i(this.options,t),n&&this.on("always",n),this.getImages(),a&&(this.jqDeferred=new a.Deferred);var r=this;setTimeout(function(){r.check()})}function f(e){this.img=e}function c(e){this.src=e,v[e]=this}var a=e.jQuery,u=e.console,h=u!==void 0,d=Object.prototype.toString;s.prototype=new t,s.prototype.options={},s.prototype.getImages=function(){this.images=[];for(var e=0,t=this.elements.length;t>e;e++){var n=this.elements[e];"IMG"===n.nodeName&&this.addImage(n);var i=n.nodeType;if(i&&(1===i||9===i||11===i))for(var r=n.querySelectorAll("img"),o=0,s=r.length;s>o;o++){var f=r[o];this.addImage(f)}}},s.prototype.addImage=function(e){var t=new f(e);this.images.push(t)},s.prototype.check=function(){function e(e,r){return t.options.debug&&h&&u.log("confirm",e,r),t.progress(e),n++,n===i&&t.complete(),!0}var t=this,n=0,i=this.images.length;if(this.hasAnyBroken=!1,!i)return this.complete(),void 0;for(var r=0;i>r;r++){var o=this.images[r];o.on("confirm",e),o.check()}},s.prototype.progress=function(e){this.hasAnyBroken=this.hasAnyBroken||!e.isLoaded;var t=this;setTimeout(function(){t.emit("progress",t,e),t.jqDeferred&&t.jqDeferred.notify&&t.jqDeferred.notify(t,e)})},s.prototype.complete=function(){var e=this.hasAnyBroken?"fail":"done";this.isComplete=!0;var t=this;setTimeout(function(){if(t.emit(e,t),t.emit("always",t),t.jqDeferred){var n=t.hasAnyBroken?"reject":"resolve";t.jqDeferred[n](t)}})},a&&(a.fn.imagesLoaded=function(e,t){var n=new s(this,e,t);return n.jqDeferred.promise(a(this))}),f.prototype=new t,f.prototype.check=function(){var e=v[this.img.src]||new c(this.img.src);if(e.isConfirmed)return this.confirm(e.isLoaded,"cached was confirmed"),void 0;if(this.img.complete&&void 0!==this.img.naturalWidth)return this.confirm(0!==this.img.naturalWidth,"naturalWidth"),void 0;var t=this;e.on("confirm",function(e,n){return t.confirm(e.isLoaded,n),!0}),e.check()},f.prototype.confirm=function(e,t){this.isLoaded=e,this.emit("confirm",this,t)};var v={};return c.prototype=new t,c.prototype.check=function(){if(!this.isChecked){var e=new Image;n.bind(e,"load",this),n.bind(e,"error",this),e.src=this.src,this.isChecked=!0}},c.prototype.handleEvent=function(e){var t="on"+e.type;this[t]&&this[t](e)},c.prototype.onload=function(e){this.confirm(!0,"onload"),this.unbindProxyEvents(e)},c.prototype.onerror=function(e){this.confirm(!1,"onerror"),this.unbindProxyEvents(e)},c.prototype.confirm=function(e,t){this.isConfirmed=!0,this.isLoaded=e,this.emit("confirm",this,t)},c.prototype.unbindProxyEvents=function(e){n.unbind(e.target,"load",this),n.unbind(e.target,"error",this)},s});
|
|
142
|
+
|
|
143
|
+
/* Second Curtain JS */
|
|
144
|
+
|
|
145
|
+
$(".onion").each(function(index, element) {
|
|
146
|
+
|
|
147
|
+
var $before = $($(element).find(".before"))[0]
|
|
148
|
+
var $after = $($(element).find(".after"))[0]
|
|
149
|
+
|
|
150
|
+
// position once we have the images
|
|
151
|
+
|
|
152
|
+
imagesLoaded( element, function( instance ) {
|
|
153
|
+
|
|
154
|
+
var left = ((1200 - $($before).width()) / 2) + "px"
|
|
155
|
+
var top = ((660 - $($before).height()) / 2) + "px"
|
|
156
|
+
|
|
157
|
+
$($before).css("top", top)
|
|
158
|
+
$($before).css("left", left)
|
|
159
|
+
|
|
160
|
+
$($after).css("top", top)
|
|
161
|
+
$($after).css("left", left)
|
|
162
|
+
});
|
|
163
|
+
|
|
164
|
+
// allow mouse drag to change the clip on the after
|
|
165
|
+
|
|
166
|
+
$( $before ).mousemove(function( event ) {
|
|
167
|
+
var x = event.pageX - element.offsetLeft - ((1200 - $(this).width() ) / 2)
|
|
168
|
+
var css = "rect( 0px, " + x + "px, " + $(this).height() + "px, 0px)"
|
|
169
|
+
$after.style.clip = css
|
|
170
|
+
});
|
|
171
|
+
|
|
172
|
+
});
|
|
173
|
+
</script>
|
|
174
|
+
|
|
175
|
+
</body>
|
|
176
|
+
</html>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
class TestSuite
|
|
2
|
+
attr_accessor :test_cases
|
|
3
|
+
attr_accessor :name
|
|
4
|
+
|
|
5
|
+
def self.suite_from_line(line)
|
|
6
|
+
components = line.split("Test Suite '")
|
|
7
|
+
end_components = line.split("' started at")
|
|
8
|
+
|
|
9
|
+
if components.count == 2 && end_components.count == 2
|
|
10
|
+
TestSuite.new(components.last.split("'").first)
|
|
11
|
+
end
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def initialize (name)
|
|
15
|
+
@name = name
|
|
16
|
+
@test_cases = []
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def latest_test_case
|
|
20
|
+
@test_cases.last
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -28,8 +28,4 @@ class Upload
|
|
|
28
28
|
actual_object.write(:file => @actual_path)
|
|
29
29
|
@uploaded_actual_url = actual_object.public_url
|
|
30
30
|
end
|
|
31
|
-
|
|
32
|
-
def to_html
|
|
33
|
-
"<li><a href='#{ @uploaded_expected_url.to_s }'>Expected</a>, <a href='#{ @uploaded_actual_url.to_s }'>Actual</li>"
|
|
34
|
-
end
|
|
35
31
|
end
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
require 'aws-sdk'
|
|
2
2
|
require 'second_curtain/upload'
|
|
3
|
+
require 'second_curtain/web_preview'
|
|
3
4
|
|
|
4
5
|
class UploadManager
|
|
5
6
|
def initialize (bucket, path_prefix)
|
|
@@ -22,12 +23,9 @@ class UploadManager
|
|
|
22
23
|
upload.upload(@bucket, @path_prefix)
|
|
23
24
|
end
|
|
24
25
|
|
|
26
|
+
preview = WebPreview.new(@uploads)
|
|
25
27
|
index_object = @bucket.objects[@path_prefix + folder_name + "/index.html"]
|
|
26
|
-
index_object.write(
|
|
28
|
+
index_object.write(preview.generate_html)
|
|
27
29
|
index_object.public_url.to_s
|
|
28
30
|
end
|
|
29
|
-
|
|
30
|
-
def to_html
|
|
31
|
-
"<html><body>#{@uploads.map(&:to_html).join}</body></html>"
|
|
32
|
-
end
|
|
33
31
|
end
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'mustache'
|
|
2
|
+
|
|
3
|
+
class WebPreview
|
|
4
|
+
attr_reader :uploads
|
|
5
|
+
|
|
6
|
+
def initialize(uploads)
|
|
7
|
+
@uploads = uploads
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def generate_html
|
|
11
|
+
lib_path = File.expand_path(File.dirname(__FILE__))
|
|
12
|
+
template = File.read(lib_path + "/template.mustache.html")
|
|
13
|
+
|
|
14
|
+
Mustache.render(template, :uploads => @uploads, :travis_id => ENV['TRAVIS_JOB_ID'])
|
|
15
|
+
end
|
|
16
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
class XcodeTestCase
|
|
2
|
+
attr_accessor :commands
|
|
3
|
+
attr_accessor :name
|
|
4
|
+
|
|
5
|
+
def self.test_case_from_line(line)
|
|
6
|
+
components = line.split("Test Case '-[")
|
|
7
|
+
|
|
8
|
+
if components.count == 2 && line.include?("]' started.")
|
|
9
|
+
# Let's make it readable
|
|
10
|
+
name = components.last.split("'").first
|
|
11
|
+
name = name.split(" ").last
|
|
12
|
+
name = name.split("]").first
|
|
13
|
+
name = name.gsub("_", " ")
|
|
14
|
+
|
|
15
|
+
# We avoid hitting ends of words by addng the space, but that potentially misses the first one
|
|
16
|
+
name += " "
|
|
17
|
+
|
|
18
|
+
name.gsub!(" hasnt ", " hasn't")
|
|
19
|
+
name.gsub!(" isn t", " isn't")
|
|
20
|
+
name.gsub!(" won t", " won't")
|
|
21
|
+
name.gsub!(" don t", " don't")
|
|
22
|
+
name.gsub!(" doesn t", " doesn't")
|
|
23
|
+
name.gsub!(" shouldn t", " shouldn't")
|
|
24
|
+
name.gsub!(" can t", " can't")
|
|
25
|
+
|
|
26
|
+
first_char_upper = name[0].upcase
|
|
27
|
+
name[0] = first_char_upper
|
|
28
|
+
name.strip!
|
|
29
|
+
XcodeTestCase.new(name)
|
|
30
|
+
end
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def initialize (name)
|
|
34
|
+
@commands = []
|
|
35
|
+
@name = name
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def add_command(command)
|
|
39
|
+
@commands.push(command)
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def latest_command
|
|
43
|
+
@commands.last
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
|
metadata
CHANGED
|
@@ -1,14 +1,15 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: second_curtain
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.2.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Ash Furrow
|
|
8
|
+
- Orta Therox
|
|
8
9
|
autorequire:
|
|
9
10
|
bindir: bin
|
|
10
11
|
cert_chain: []
|
|
11
|
-
date: 2014-08-
|
|
12
|
+
date: 2014-08-05 00:00:00.000000000 Z
|
|
12
13
|
dependencies:
|
|
13
14
|
- !ruby/object:Gem::Dependency
|
|
14
15
|
name: aws-sdk
|
|
@@ -24,6 +25,20 @@ dependencies:
|
|
|
24
25
|
- - ~>
|
|
25
26
|
- !ruby/object:Gem::Version
|
|
26
27
|
version: '1.48'
|
|
28
|
+
- !ruby/object:Gem::Dependency
|
|
29
|
+
name: mustache
|
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
|
31
|
+
requirements:
|
|
32
|
+
- - ~>
|
|
33
|
+
- !ruby/object:Gem::Version
|
|
34
|
+
version: '0.99'
|
|
35
|
+
type: :runtime
|
|
36
|
+
prerelease: false
|
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
38
|
+
requirements:
|
|
39
|
+
- - ~>
|
|
40
|
+
- !ruby/object:Gem::Version
|
|
41
|
+
version: '0.99'
|
|
27
42
|
description: ! "\n If you're using the cool FBSnapshotTestCase to test your iOS view
|
|
28
43
|
logic, awesome! Even better if you have continuous integration, like on Travis,
|
|
29
44
|
to automate running those tests!\n\n Wouldn't it be awesome if we could upload
|
|
@@ -37,8 +52,14 @@ extra_rdoc_files: []
|
|
|
37
52
|
files:
|
|
38
53
|
- bin/second_curtain
|
|
39
54
|
- lib/second_curtain.rb
|
|
55
|
+
- lib/second_curtain/kaleidoscope_command.rb
|
|
56
|
+
- lib/second_curtain/parser.rb
|
|
57
|
+
- lib/second_curtain/template.mustache.html
|
|
58
|
+
- lib/second_curtain/test_suite.rb
|
|
40
59
|
- lib/second_curtain/upload.rb
|
|
41
60
|
- lib/second_curtain/upload_manager.rb
|
|
61
|
+
- lib/second_curtain/web_preview.rb
|
|
62
|
+
- lib/second_curtain/xcode_test_case.rb
|
|
42
63
|
homepage: https://github.com/AshFurrow/second_curtain
|
|
43
64
|
licenses:
|
|
44
65
|
- MIT
|