coderetreat 0.0.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.
Files changed (4) hide show
  1. checksums.yaml +15 -0
  2. data/bin/cr +15 -0
  3. data/lib/coderetreat.rb +159 -0
  4. metadata +47 -0
checksums.yaml ADDED
@@ -0,0 +1,15 @@
1
+ ---
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ ODVjZmI1ZjY0ZjBkMmNkNmMyMTA2ZGY3ZGVkOWQzNjRhZGRiMDI0Yw==
5
+ data.tar.gz: !binary |-
6
+ MjgwNjBmZjc3NTNhZWNkMDkxMmM3MDI2NTg5ZTA1ZjY3YmY1NzhhMQ==
7
+ SHA512:
8
+ metadata.gz: !binary |-
9
+ OWIyMzRlOGNlMmY5MTQwOWMxOGQ3NGJhZjU3Nzk5MjBmMDdjNWM2NmJhOTE2
10
+ YzFiNjU0Y2VmMzRmNWE5Y2FhODk0ZjY1NzcwMjQ2N2ZjOWVjM2I3MGQ3OWFj
11
+ ZWRkNmNlMTgzMWZmYjg5ODE2OTdiNDYyMjAwNDMyZDA2NzgxYWI=
12
+ data.tar.gz: !binary |-
13
+ MjYxODMyYWE4YmRmOWE5ODljMTgzZWM5YzgyN2YyMjNkMDgxNGViNTUwMWZl
14
+ YTAzODkyOWVlZTkzN2U4MDMzMjA5MDFhZTIyMjk3ZjM1ZmZmOTVmYzU2Zjc1
15
+ NGI4MjQyNDgyOWM5MjI4ZTc4MDQ4MzA3OTJjNGIzMThjMjhmN2Y=
data/bin/cr ADDED
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+ if ARGV.length > 0
3
+ file = ARGV[0]
4
+
5
+ else
6
+ STDOUT.puts 'You need to tell me what to watch!'
7
+ STDOUT.puts 'Usage:'
8
+ STDOUT.puts 'bin/cr somefile.rb'
9
+ Kernel.exit(true)
10
+ end
11
+
12
+ configFile = 'http://jsoxford.com/cr.json'
13
+ require_relative('../lib/coderetreat.rb')
14
+ config = ARGV.length >= 3 ? {host: ARGV[1], port: ARGV[2]} : CodeRetreatRunner.config(configFile)
15
+ CodeRetreatRunner.new.run(file, config)
@@ -0,0 +1,159 @@
1
+ # encoding: UTF-8
2
+ require 'socket'
3
+ require 'json'
4
+ require 'digest'
5
+ require 'active_support/core_ext/hash/indifferent_access'
6
+ require 'net/http'
7
+ require 'rspec'
8
+
9
+ class CodeRetreatRunner
10
+
11
+ def self.config(url)
12
+ JSON.parse(Net::HTTP.get(URI(url)))['endpoint'].with_indifferent_access
13
+ end
14
+
15
+ # Runs the runner
16
+ def run(filename, config)
17
+ STDOUT.puts "Watching #{filename}"
18
+
19
+ unless File.exists?(filename)
20
+ return STDOUT.puts 'Something went pretty badly wrong. Does that file exist?'
21
+ end
22
+
23
+ STDOUT.puts "Connecting to #{config[:host]}:#{config[:port]}"
24
+ connect(config)
25
+
26
+ # Receive data and check the test file indefinitely
27
+ loop do
28
+ test(filename) if changed(filename)
29
+ receive
30
+ end
31
+ end
32
+
33
+ # Runs the tests in the test file
34
+ def test(filename)
35
+ begin
36
+ RSpec.reset
37
+ config = RSpec.configuration
38
+ config.color = true
39
+
40
+ json_formatter = RSpec::Core::Formatters::JsonFormatter.new(config.output_stream)
41
+ reporter = RSpec::Core::Reporter.new(config)
42
+ reporter.register_listener(json_formatter, :message, :dump_summary, :stop)
43
+ config.instance_variable_set(:@reporter, reporter)
44
+
45
+ RSpec::Core::Runner.run([filename])
46
+ data = json_formatter.output_hash
47
+
48
+ setInterrupt
49
+
50
+ symbols = {passed: '✓', pending: '.', failed: '✖'}
51
+ STDOUT.puts data[:examples].map{ |example| ' ' + symbols[example[:status].to_sym] }.join('')
52
+
53
+ data[:examples].select{ |example| example[:status] == 'failed' }.map do |example|
54
+ STDOUT.puts "fail: #{example[:full_description]} -- error: #{example[:exception][:message]}"
55
+ end
56
+
57
+ send({
58
+ action: 'consumeTestResults',
59
+ payload: {
60
+ testsRun: data[:summary][:example_count],
61
+ testsFailed: data[:summary][:failure_count],
62
+ testsIgnored: data[:summary][:pending_count]
63
+ }
64
+ })
65
+
66
+ rescue Exception => e
67
+ STDOUT.puts "Failed to load your code, do you have errors in your Ruby? Exception: [#{e}]"
68
+ end
69
+ end
70
+
71
+ # Connects the TCP socket
72
+ def connect(config)
73
+ @client = TCPSocket.open config[:host], config[:port]
74
+ setInterrupt
75
+ end
76
+
77
+ # Disconnects the TCP socket
78
+ def disconnect
79
+ @client.close if @client
80
+ end
81
+
82
+ # Disable rspec interrupt, and disconnect our socket on close
83
+ def setInterrupt
84
+ Signal.trap('INT') do
85
+ disconnect
86
+ Kernel.exit(0)
87
+ end
88
+ end
89
+
90
+ # Sends JSON through the TCP socket
91
+ def send(data)
92
+ @client.write JSON.generate(data)
93
+ end
94
+
95
+ # Checks if the test file has changed (no more than once a second)
96
+ def changed(filename)
97
+ changed = false
98
+ now = Time.now.to_f
99
+
100
+ @timestamp ||= now
101
+ @fileHash ||= ''
102
+
103
+ if now - @timestamp > 1
104
+ File.open(filename, "r") do |file|
105
+ fileHash = Digest::SHA1.hexdigest(File.read(filename))
106
+ changed = fileHash != @fileHash
107
+ @fileHash = fileHash
108
+ end
109
+
110
+ @timestamp = now
111
+ end
112
+
113
+ changed
114
+ end
115
+
116
+ # Responds to a request
117
+ def respond(data)
118
+ payload = data[:payload]
119
+ success = false
120
+ message = nil
121
+
122
+ begin
123
+ case data[:action]
124
+ when 'tickBoard'
125
+ # CodeRetreat.tickBoard(payload[:result])
126
+ payload = {}
127
+ success = false
128
+ when 'tickCell'
129
+ payload[:generation]++
130
+ payload[:lives] = CodeRetreat.tickCell(payload[:result])
131
+ payload[:from] = payload[:result]
132
+ payload.delete(:result)
133
+ success = true
134
+ else
135
+ message = "I don't understand the action requested: #{data[:action]}"
136
+ end
137
+ rescue Exception => e
138
+ message = "Requested action had an error: #{data[:action]}"
139
+ end
140
+
141
+ send({ respondingTo: data[:action], success: success, message: message, payload: payload })
142
+ end
143
+
144
+ # Recieve data from the TCP socket and buffers into JSON objects
145
+ def receive
146
+ @buffer ||= ''
147
+ data = @client.recv(128)
148
+ unless data.nil?
149
+ @buffer += data
150
+
151
+ jsons = @buffer.split("\n")
152
+ jsons.each do |json|
153
+ respond(JSON.parse(json).with_indifferent_access) rescue nil
154
+ end
155
+
156
+ @buffer = jsons.last unless @buffer.match(/\n$/)
157
+ end
158
+ end
159
+ end
metadata ADDED
@@ -0,0 +1,47 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: coderetreat
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Pete West
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2014-07-06 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Automatically run your tests, and connect to the Code Retreat Game of
14
+ Life server to be part of the bigger picture
15
+ email: peterjwest3@gmail.com
16
+ executables:
17
+ - cr
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - bin/cr
22
+ - lib/coderetreat.rb
23
+ homepage: https://github.com/jsoxford/code-retreat-rb
24
+ licenses:
25
+ - MIT
26
+ metadata: {}
27
+ post_install_message:
28
+ rdoc_options: []
29
+ require_paths:
30
+ - lib
31
+ required_ruby_version: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - ! '>='
34
+ - !ruby/object:Gem::Version
35
+ version: '0'
36
+ required_rubygems_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ! '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ requirements: []
42
+ rubyforge_project:
43
+ rubygems_version: 2.2.2
44
+ signing_key:
45
+ specification_version: 4
46
+ summary: Code Retreat Game of Life runner
47
+ test_files: []