semilla 0.0.2

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.
@@ -0,0 +1,153 @@
1
+ require "socket"
2
+ require "timeout"
3
+
4
+ module Semilla
5
+
6
+ class FlexUnitReportServer
7
+
8
+ attr_accessor :results
9
+ attr_reader :error
10
+
11
+ START_ACK = "<startOfTestRunAck/>"
12
+ END_TEST = "<endOfTestRun/>"
13
+ END_TEST_ACK = "<endOfTestRunAck/>"
14
+ POLICY_REQUEST = "<policy-file-request/>"
15
+ EOF = "\0"
16
+ SOCKET_POLICY_FILE = <<EOS
17
+ <?xml version="1.0"?>
18
+ <!DOCTYPE cross-domain-policy SYSTEM "http://www.macromedia.com/xml/dtds/cross-domain-policy.dtd">
19
+ <cross-domain-policy>
20
+ <allow-access-from domain="*" to-ports="@@@"/>
21
+ </cross-domain-policy>
22
+ EOS
23
+
24
+
25
+ def initialize(port=1026)
26
+ @port = port
27
+ @addr = "127.0.0.1"
28
+ @server = nil #This will be our socket server
29
+ @error = false
30
+ end
31
+
32
+
33
+ def start(timeout=10)
34
+ @server = TCPServer.new(@addr, @port)
35
+ #view server data
36
+ puts @server.addr
37
+
38
+ #open the socket
39
+ puts "Opening server at port #{@port}"
40
+
41
+ #--------------------------------------------------------------
42
+ #the report result will be here
43
+ report = ""
44
+
45
+ loop {
46
+ puts "Waiting for client..."
47
+
48
+ begin
49
+ #Wait with a timeout
50
+ client = Timeout::timeout timeout do
51
+ @server.accept
52
+ end
53
+ #No client connected within the time limit, bail out
54
+ rescue Timeout::Error
55
+ puts "Timeout!!, no client connected!!!"
56
+ @error = true
57
+ break
58
+ end
59
+ puts "Client connected..."
60
+ puts "Receiving data"
61
+ #Tell FlexUnit to start sending stuff
62
+ client.puts START_ACK + EOF
63
+ #puts "[OUT] #{START_ACK}"
64
+ report = "<report>"
65
+ error = false
66
+ while received = receiveWithTimeout(client, timeout)
67
+ unless received != ""
68
+ finished = true
69
+ puts "empty data!!"
70
+ error = true
71
+ break
72
+ end
73
+ #puts received
74
+ putc '.'
75
+ #clean up the text
76
+ received.rstrip!
77
+ received.chomp!
78
+
79
+ #print out for debug
80
+ #puts "[IN] #{received}"
81
+
82
+ #check for policy file
83
+ if received.include? POLICY_REQUEST
84
+ self.sendPolicyFile client
85
+ client.close
86
+ puts "[OUT] Sending policy File"
87
+ break
88
+ end
89
+
90
+ if received.include? END_TEST
91
+
92
+ #the last message may contain some data as well
93
+ report = report + received.sub(END_TEST, "")
94
+
95
+ puts
96
+ puts "Closing connection"
97
+ #Test ended, send ACK to client
98
+ client.puts END_TEST_ACK + EOF
99
+ client.flush
100
+ client.close
101
+ finished = true
102
+ report = report + "</report>"
103
+ break
104
+ end
105
+
106
+ report = report + received
107
+
108
+ end
109
+
110
+ if error
111
+ report = nil
112
+ end
113
+ break if finished
114
+
115
+
116
+ }
117
+ #Parse the xml from flexunit and generate the report files.
118
+ puts "bye bye"
119
+ #sanitize the results string
120
+ @results = report.delete "\000" unless report.nil?
121
+ #---------------------------------------------------------------
122
+
123
+ end
124
+
125
+
126
+ def policyFile
127
+ return SOCKET_POLICY_FILE.sub "@@@", @port #replace the @@@ for the port number
128
+ end
129
+
130
+
131
+ def sendPolicyFile(client)
132
+ puts "Sending policy file."
133
+ #Send policy stuff
134
+ client.puts self.policyFile
135
+ client.flush
136
+ end
137
+
138
+
139
+ def receiveWithTimeout(client, timeout)
140
+
141
+ begin
142
+ r = Timeout::timeout timeout do
143
+ client.recv(1024)
144
+ end
145
+ rescue Timeout::Error
146
+ "" #Timed out, return an empty string
147
+ end
148
+
149
+ end
150
+
151
+ end
152
+
153
+ end
@@ -0,0 +1,203 @@
1
+ require 'rexml/document'
2
+ require 'rexml/formatters/default'
3
+ require 'socket'
4
+ require 'time'
5
+
6
+
7
+ module Semilla
8
+
9
+ #Define a test case
10
+ class FlexUnitTestCase
11
+
12
+ attr_accessor :classname, :name, :time, :status, :msg
13
+
14
+
15
+ def initWith(xml)
16
+ #parse tag
17
+ if xml.is_a? String
18
+ doc = REXML::Document.new xml
19
+ else
20
+ doc = REXML::Document.new
21
+ doc.add_element xml
22
+ end
23
+
24
+
25
+ @classname = doc.root.attribute("classname").value.sub "::", "." #Change the :: to .
26
+ @name = doc.root.attribute("name").value #method name
27
+ @time = doc.root.attribute("time").value.to_i / 1000.0 #time to milliseconds
28
+ @status = doc.root.attribute("status").value #status
29
+ @msg = doc.root.elements[1] if doc.root.elements.count > 0
30
+
31
+
32
+ #If time is reported as 0 by flex unit, set to 1 millisecond
33
+ #@time = 1/1000.0 if @time == 0
34
+ end
35
+
36
+
37
+ def toXml
38
+ element = REXML::Element.new "testcase"
39
+ element.add_attribute "classname", @classname
40
+ element.add_attribute "name", @name
41
+ element.add_attribute "time", @time
42
+ element.add_attribute "status", @status
43
+ element.add_element @msg unless @msg.nil?
44
+
45
+ return element
46
+ end
47
+ end
48
+
49
+ #Defin a test suite
50
+ class FlexUnitTestSuite
51
+
52
+ def initialize
53
+ @testCases = Array.new
54
+ @classname = ""
55
+ @totalTime = 0.0
56
+ @id = 0
57
+ end
58
+
59
+
60
+ attr_reader :totalTime, :classname
61
+ attr_accessor :id
62
+
63
+
64
+ def addCase(tc)
65
+ if tc.is_a? FlexUnitTestCase
66
+ @classname = tc.classname
67
+ @testCases << tc
68
+ @totalTime = @totalTime + tc.time
69
+ end
70
+ end
71
+
72
+
73
+ def testCount
74
+ @testCases.count
75
+ end
76
+
77
+
78
+ def name
79
+ return @classname[/[^\.]*$/] #Get the text at the end of the line after the last dot
80
+ end
81
+
82
+
83
+ def package
84
+ if @classname.include? "."
85
+ @classname[/(?<package>.*)([\.])/, "package"]
86
+ #using named captures check: "?<package>"
87
+ else
88
+ ""
89
+ end
90
+ end
91
+
92
+
93
+ def failures
94
+ return @testCases.count { |tc| tc.status == "failure" }
95
+ end
96
+
97
+
98
+ def errors
99
+ return @testCases.count { |tc| tc.status == "error" }
100
+ end
101
+
102
+
103
+ def ignores
104
+ return @testCases.count { |tc| tc.status == "ignore" }
105
+ end
106
+
107
+
108
+ def toXml
109
+ element = REXML::Element.new "testsuite"
110
+ element.add_attribute "hostname", Socket.gethostname
111
+ element.add_attribute "id", self.id
112
+ #element.add_attribute "package", self.package
113
+ element.add_attribute "name", self.classname
114
+ element.add_attribute "tests", self.testCount
115
+ element.add_attribute "failures", self.failures
116
+ element.add_attribute "errors", self.errors
117
+ element.add_attribute "skipped", self.ignores
118
+ element.add_attribute "time", self.totalTime
119
+ element.add_attribute "timestamp", Time.now.utc.iso8601
120
+
121
+ @testCases.each do |tc|
122
+ element.add_element tc.toXml
123
+ end
124
+
125
+ return element
126
+ end
127
+
128
+ end
129
+
130
+
131
+ def self.writePrettyXml(element, filename)
132
+ #create anew xml document
133
+ outdoc = REXML::Document.new
134
+
135
+ #Create the xml declaration
136
+ xmldeclaration = REXML::XMLDecl.new
137
+ xmldeclaration.dowrite
138
+ xmldeclaration.encoding = "UTF-8"
139
+ outdoc << xmldeclaration
140
+
141
+ #Add the element
142
+ outdoc << element
143
+
144
+ #Write to a file
145
+ f = File.new filename, "w"
146
+ formatter = REXML::Formatters::Pretty.new
147
+ formatter.write(outdoc, f)
148
+ f.close
149
+ end
150
+
151
+
152
+ #converts an xml report from flash, into an array of FlexUnitTestSuite
153
+ def self.processReports(xmlresults)
154
+
155
+ testResults = REXML::Document.new xmlresults
156
+
157
+ suites = Hash.new
158
+
159
+ testResults.elements.each "report/testcase" do |element|
160
+
161
+ #Create the testcase
162
+ tc = FlexUnitTestCase.new
163
+ tc.initWith element
164
+
165
+ #Check if we dont have a suite for the classname
166
+ unless suites.has_key? tc.classname
167
+ #make a new suite
168
+ s = FlexUnitTestSuite.new
169
+ suites[tc.classname] = s
170
+ end
171
+
172
+ suite = suites[tc.classname]
173
+ suite.addCase tc
174
+ puts " [TestCase] #{tc.classname} => #{tc.name}, #{tc.status}"
175
+ end
176
+
177
+ return suites
178
+ end
179
+
180
+
181
+ #writes junit xml files for each item in the suites hash
182
+ def self.createReports(suites, outfolder = "test-report")
183
+
184
+ testcount = 0
185
+ testfails = 0
186
+ testerr = 0
187
+ testignores = 0
188
+ suites.each do |name, suite|
189
+ #write individual report file
190
+ writePrettyXml suite.toXml, "#{outfolder}/TEST-#{suite.classname}.xml"
191
+ testcount += suite.testCount
192
+ testfails += suite.failures
193
+ testerr += suite.errors
194
+ testignores += suite.ignores
195
+ end
196
+
197
+ testPassed = testcount - testfails - testerr - testignores
198
+ testok = testPassed.to_f / testcount.to_f * 100.0
199
+ puts "Success [#{testPassed}/#{testcount}] #{sprintf('%.1f', testok)}%, Fails [#{testfails}], Errors [#{testerr}], Ignored [#{testignores}]"
200
+ return testfails + testerr
201
+ end
202
+
203
+ end
@@ -0,0 +1,95 @@
1
+
2
+ require "rexml/document"
3
+ require "rake"
4
+ require 'timeout'
5
+ require 'flashplayer/trust'
6
+
7
+ require_relative "reports"
8
+ require_relative "report_server"
9
+
10
+
11
+ module Semilla
12
+ class FlexUnitTestTask < Rake::Task
13
+
14
+ attr_accessor :serverPort, :player, :swf, :reportpath, :timeout
15
+
16
+
17
+ def initialize(task_name, app)
18
+ super task_name, app
19
+
20
+ @serverPort = 1024
21
+ @player = ENV['FLASH_PLAYER']
22
+ @reportpath = "test-report"
23
+ @timeout = 10 #seconds
24
+ end
25
+
26
+
27
+ def execute(arg = nil)
28
+ super arg
29
+
30
+ ##Check the parameters
31
+ if @serverPort.nil?
32
+ fail "Server port not specified."
33
+ end
34
+
35
+ if @swf.nil?
36
+ fail "No swf path specified."
37
+ end
38
+
39
+ if @reportpath.nil?
40
+ fail "No report path specified."
41
+ end
42
+
43
+ #Writeout the FlashPlayerTrust file
44
+ trust = FlashPlayer::Trust.new
45
+ trust.add File.dirname(@swf)
46
+
47
+ puts "[TEST] Start"
48
+ server = FlexUnitReportServer.new @serverPort
49
+ serverThread = Thread.new {
50
+ #Start the server for getting the flex unit results
51
+ server.start @timeout
52
+ }
53
+ sleep 0.5
54
+
55
+ #launch flash
56
+ clientThread = Thread.new {
57
+
58
+ begin
59
+ status = Timeout::timeout @timeout do
60
+ flashbin = ENV['FLASH_PLAYER']
61
+ #Run the flash player
62
+ puts "Running flash..."
63
+ command = "\"#{flashbin}\" \"#{@swf}\""
64
+ puts command
65
+ fr = %x[#{command}]
66
+ end
67
+ rescue Timeout::Error
68
+ fail "Flash player timeout!!!"
69
+ end
70
+ }
71
+
72
+
73
+ #Wait until finished
74
+ serverThread.join
75
+ clientThread.join
76
+
77
+ #parse the reports
78
+ suites = Semilla::processReports server.results
79
+ #generate junit report
80
+ failcount = Semilla::createReports suites, @reportpath
81
+ puts "[TEST] Done"
82
+
83
+ fail "Unit tests failed." if failcount > 0
84
+
85
+ end
86
+
87
+ end
88
+
89
+
90
+ def self.flex_unit(*args, &body)
91
+ FlexUnitTestTask.define_task(*args, &body)
92
+ end
93
+
94
+
95
+ end
@@ -0,0 +1,87 @@
1
+ require "rake"
2
+
3
+ module Semilla
4
+
5
+ class TestCaseFile
6
+ attr_accessor :path
7
+
8
+ #Constructor. The parameter should be a string from rake
9
+ def initialize(fpath)
10
+ @path = fpath
11
+ end
12
+
13
+
14
+ #The file name without extension
15
+ def name
16
+ @path.pathmap '%n'
17
+ end
18
+
19
+
20
+ #Get the package name from the contents of the file
21
+ def package
22
+ if !@_package
23
+ #Open the file
24
+ File.open @path do |io|
25
+ io.each do |line|
26
+ #Search for the package name
27
+ if line =~ /^package (.*)/
28
+ @_package = $1.rstrip
29
+ end
30
+ end
31
+ #no package name found, set to empty string
32
+ @_package = "" if !@_package
33
+ end
34
+ end
35
+ return @_package
36
+ end
37
+
38
+
39
+ #The import statement for this class
40
+ def import
41
+ if self.package != ""
42
+ return "#{self.package}.#{self.name}"
43
+ else
44
+ return self.name
45
+ end
46
+ end
47
+ end
48
+
49
+
50
+ ######################################################################
51
+ #Define a rake task for auto generating the TestRunner code
52
+ def self.test_runner(output, files, port=1026, template="test-src/TestRunner.template")
53
+ #Prepare arguments for the FileTask
54
+ files.include template
55
+ args = Array.new
56
+ args << {output => files} #target file => dependencies
57
+
58
+ body = proc {
59
+ #create the test case generators
60
+ generators = Array.new
61
+ files.each do |f|
62
+ tc = TestCaseFile.new f
63
+ puts "[testRunner] Adding: #{tc.import}"
64
+ generators << tc
65
+ end
66
+ #open the template and insert the import statements and class list
67
+ File.open template do |io|
68
+ txt = io.read
69
+ #insert import list
70
+ txt.sub! "@@IMPORTS@@", generators.map { |t| "\timport #{t.import};" }.join("\n")
71
+ #insert class names
72
+ txt.sub! "@@CLASSES@@", generators.map { |t| t.name }.join(",")
73
+ #insert port number
74
+ txt.sub! "@@PORT@@", port.to_s
75
+
76
+ #write the generated code
77
+ generated = File.new output, "w"
78
+ generated.write txt
79
+ generated.close
80
+ end
81
+ }
82
+
83
+ #Create the file task (checks for dependency updates for us)
84
+ Rake::FileTask.define_task(*args, &body)
85
+ end
86
+
87
+ end
@@ -0,0 +1,3 @@
1
+ module Semilla
2
+ VERSION = '0.0.2'
3
+ end
data/lib/semilla.rb ADDED
@@ -0,0 +1,36 @@
1
+
2
+
3
+ require 'semilla/report_server'
4
+ require 'semilla/reports'
5
+ require 'semilla/test'
6
+ require 'semilla/test_runner'
7
+
8
+
9
+ ## Rake usage
10
+
11
+ =begin
12
+
13
+ #################################################################
14
+ # Rake task to create the test runner actionscript
15
+ #
16
+ # @param output file
17
+ # @param test classes file list
18
+ # @param report server port
19
+ Semilla::test_runner "outputfile.as", FileList["test-src/**/*Test.as"], 1026
20
+
21
+ #################################################################
22
+ # Rake task to test a swf and get a report in junit xml format.
23
+ #
24
+ # @param task id
25
+ # @param dependencies
26
+ Semilla::flex_unit :taskname => [dependencies]] do |t|
27
+ #Configuration options
28
+ # serverPort :player, :swf, :reportpath, :timeout
29
+ # serverPort :player, :swf, :reportpath, :timeout
30
+ t.serverPort = 1026
31
+ t.swf = "app.swf"
32
+ t.reportpath = "reports"
33
+ t.timeout = 10
34
+ end
35
+
36
+ =end
data/rakefile.rb ADDED
@@ -0,0 +1,39 @@
1
+ require 'rubygems'
2
+ require 'rake/clean'
3
+ require 'rake'
4
+ require_relative "lib/semilla/version"
5
+
6
+
7
+ version = Semilla::VERSION
8
+ gemfile = "semilla-#{version}.gem"
9
+ gemspecfile = "semilla.gemspec"
10
+ ########################################################################################################################
11
+
12
+ #####################################
13
+ #Clean
14
+ CLEAN << FileList["*.gem"]
15
+
16
+
17
+ #####################################
18
+ #Build the gem file
19
+ file gemfile => [gemspecfile] do |t|
20
+ sh "gem build #{gemspecfile}"
21
+ end
22
+
23
+ desc "Builds the gem"
24
+ task :build => gemfile
25
+
26
+ ####################################
27
+ desc "Uninstall the gem"
28
+ task :uninstall do |t|
29
+ sh "gem uninstall semilla"
30
+ end
31
+
32
+ ##################################
33
+ desc "Install the gem"
34
+ task :install => :build do |t|
35
+ sh "gem install #{gemfile}"
36
+ end
37
+
38
+ ##################################
39
+ task :default => [:clean, :build, :install]
data/semilla.gemspec ADDED
@@ -0,0 +1,45 @@
1
+
2
+ # -*- encoding: utf-8 -*-
3
+ #$:.push('lib')
4
+ require "semilla/version"
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = "semilla"
8
+ s.version = Semilla::VERSION.dup
9
+ s.date = "2011-12-26"
10
+ s.summary = "Rake tasks for flexunit4"
11
+ s.email = "support@semilla.com"
12
+ s.homepage = "http://todo.project.com/"
13
+ s.authors = ['Victor G. Rosales']
14
+
15
+ s.description = <<-EOF
16
+ Rake tasks for executing flex unit 4 tests.
17
+ It should be used in addition to the sprout gem.
18
+ EOF
19
+
20
+ dependencies = [
21
+ # Examples:
22
+ # [:runtime, "rack", "~> 1.1"],
23
+ # [:development, "rspec", "~> 2.1"],
24
+ [:sprout_flashsdk, "flashsdk", "~> 1.0"]
25
+ ]
26
+
27
+ s.files = Dir['**/*']
28
+ s.test_files = Dir['test/**/*'] + Dir['spec/**/*']
29
+ s.executables = Dir['bin/*'].map { |f| File.basename(f) }
30
+ s.require_paths = ["lib"]
31
+
32
+
33
+ ## Make sure you can build the gem on older versions of RubyGems too:
34
+ s.rubygems_version = "1.8.13"
35
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
36
+ s.specification_version = 3 if s.respond_to? :specification_version
37
+
38
+ dependencies.each do |type, name, version|
39
+ if s.respond_to?("add_#{type}_dependency")
40
+ s.send("add_#{type}_dependency", name, version)
41
+ else
42
+ s.add_dependency(name, version)
43
+ end
44
+ end
45
+ end
metadata ADDED
@@ -0,0 +1,67 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: semilla
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.2
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Victor G. Rosales
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-12-26 00:00:00.000000000Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: flashsdk
16
+ requirement: &21744840 !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: '1.0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: *21744840
25
+ description: ! 'Rake tasks for executing flex unit 4 tests.
26
+
27
+ It should be used in addition to the sprout gem.
28
+
29
+ '
30
+ email: support@semilla.com
31
+ executables: []
32
+ extensions: []
33
+ extra_rdoc_files: []
34
+ files:
35
+ - lib/semilla/reports.rb
36
+ - lib/semilla/report_server.rb
37
+ - lib/semilla/test.rb
38
+ - lib/semilla/test_runner.rb
39
+ - lib/semilla/version.rb
40
+ - lib/semilla.rb
41
+ - rakefile.rb
42
+ - semilla.gemspec
43
+ homepage: http://todo.project.com/
44
+ licenses: []
45
+ post_install_message:
46
+ rdoc_options: []
47
+ require_paths:
48
+ - lib
49
+ required_ruby_version: !ruby/object:Gem::Requirement
50
+ none: false
51
+ requirements:
52
+ - - ! '>='
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ required_rubygems_version: !ruby/object:Gem::Requirement
56
+ none: false
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ requirements: []
62
+ rubyforge_project:
63
+ rubygems_version: 1.8.13
64
+ signing_key:
65
+ specification_version: 3
66
+ summary: Rake tasks for flexunit4
67
+ test_files: []