uncool 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,14 @@
1
+ #if conf = Dir['{,.}config/uncool.yml'].first
2
+ # require 'yaml'
3
+ # opts = YAML.load(File.new(conf))
4
+ # output = opts['output'] || opts['out']
5
+ # namespaces = opts['spaces'] || opts['namespaces'] || opts['ns']
6
+ #else
7
+ output = ENV['out']
8
+ namespaces = ENV['ns'].split(',')
9
+ #end
10
+
11
+ require 'uncool/log'
12
+
13
+ Uncool.log(:output=>output, :namespaces=>namespaces)
14
+
@@ -0,0 +1,168 @@
1
+ module Uncool
2
+
3
+ require 'optparse'
4
+
5
+ # CLI Interface handle all lemon sub-commands.
6
+ class CLI
7
+
8
+ COMMANDS = ['coverage', 'generate']
9
+
10
+ #
11
+ def self.run(argv=ARGV)
12
+ new.run(argv)
13
+ end
14
+
15
+ #
16
+ def initialize(argv=ARGV)
17
+ @options = {}
18
+ end
19
+
20
+ #
21
+ def options
22
+ @options
23
+ end
24
+
25
+ #
26
+ def run(argv)
27
+ if argv.include?('-g') or argv.include?('--generate')
28
+ cmd = 'generate'
29
+ else
30
+ cmd = 'coverage'
31
+ end
32
+ cmd = COMMANDS.find{ |c| /^#{cmd}/ =~ c }
33
+ __send__("#{cmd}_parse", argv)
34
+ __send__("#{cmd}", argv)
35
+ end
36
+
37
+ # C O V E R A G E
38
+
39
+ #
40
+ def coverage(scripts)
41
+ require 'uncool/app'
42
+
43
+ app = App.new(options)
44
+
45
+ app.log
46
+
47
+ scripts.each do |file|
48
+ require(file)
49
+ end
50
+ end
51
+
52
+ #
53
+ def coverage_parse(argv)
54
+ option_namespaces
55
+ option_private
56
+ option_output
57
+ option_format
58
+ #option_uncovered
59
+ option_loadpath
60
+ option_requires
61
+
62
+ option_parser.parse!(argv)
63
+ end
64
+
65
+ # G E N E R A T E
66
+
67
+ #
68
+ def generate(scripts)
69
+ require 'uncool/app'
70
+
71
+ app = App.new(options)
72
+
73
+ output = app.generate(scripts)
74
+
75
+ $stdout.puts(output)
76
+ end
77
+
78
+ #
79
+ def generate_parse(argv)
80
+ option_generate
81
+ option_namespaces
82
+ option_framework
83
+ option_private
84
+ option_loadpath
85
+ option_requires
86
+
87
+ option_parser.parse!(argv)
88
+ end
89
+
90
+ # P A R S E R O P T I O N S
91
+
92
+ def option_namespaces
93
+ option_parser.on('-n', '--namespace NAME', 'add a namespace to output') do |name|
94
+ options[:namespaces] ||= []
95
+ options[:namespaces] << name
96
+ end
97
+ end
98
+
99
+ def option_framework
100
+ option_parser.on('-f', '--framework NAME', 'framework syntax to output') do |name|
101
+ options[:framework] = name.to_sym
102
+ end
103
+ end
104
+
105
+ # TODO: How feasible is it to parse tests of various frameworks to check "writ" coverage?
106
+ #def option_uncovered
107
+ # option_parser.on('-u', '--uncovered', 'include only uncovered tests') do
108
+ # options[:uncovered] = true
109
+ # end
110
+ #end
111
+
112
+ def option_private
113
+ option_parser.on('-p', '--private', 'include private and protected methods') do
114
+ options[:private] = true
115
+ end
116
+ end
117
+
118
+ def option_output
119
+ option_parser.on('-o', '--output DIRECTORY', 'log directory') do |dir|
120
+ options[:output] = dir
121
+ end
122
+ end
123
+
124
+ def option_format
125
+ option_parser.on('--format', '-f NAME', 'output format') do |name|
126
+ options[:format] = name
127
+ end
128
+ end
129
+
130
+ def option_loadpath
131
+ option_parser.on("-I PATH" , 'add directory to $LOAD_PATH') do |path|
132
+ paths = path.split(/[:;]/)
133
+ options[:loadpath] ||= []
134
+ options[:loadpath].concat(paths)
135
+ end
136
+ end
137
+
138
+ def option_requires
139
+ option_parser.on("-r FILE" , 'require file(s) (before doing anything else)') do |files|
140
+ files = files.split(/[:;]/)
141
+ options[:requires] ||= []
142
+ options[:requires].concat(files)
143
+ end
144
+ end
145
+
146
+ def option_generate
147
+ option_parser.on('-g' , '--generate', 'code generation mode') do
148
+ end
149
+ end
150
+
151
+ def option_parser
152
+ @option_parser ||= (
153
+ OptionParser.new do |opt|
154
+ opt.on_tail("--debug" , 'turn on debugging mode') do
155
+ $DEBUG = true
156
+ end
157
+ opt.on_tail('-h', '--help', 'display this help messae') do
158
+ puts opt
159
+ exit 0
160
+ end
161
+ end
162
+ )
163
+ end
164
+
165
+ end
166
+
167
+ end
168
+
@@ -0,0 +1,95 @@
1
+ require 'uncool/unit'
2
+
3
+ module Uncool
4
+
5
+ # Generator base class.
6
+ class GeneratorAbstract
7
+
8
+ def initialize(options={})
9
+ @namespaces = options[:namespaces] || []
10
+ @checklist = options[:checklist]
11
+ @options = options || {}
12
+ end
13
+
14
+ #
15
+ def namespaces
16
+ @namespaces
17
+ end
18
+
19
+ #
20
+ def checklist
21
+ @checklist ||= default_checklist
22
+ end
23
+
24
+ #
25
+ def targets
26
+ @targets ||= namespaces.map{ |ns| eval(ns, TOPLEVEL_BINDING) }
27
+ end
28
+
29
+ #
30
+ def options
31
+ @options
32
+ end
33
+
34
+ # Include already covered methods.
35
+ def covered?
36
+ options[:covered]
37
+ end
38
+
39
+ # Include private and protected methods?
40
+ def private?
41
+ options[:private]
42
+ end
43
+
44
+ #
45
+ def mapping
46
+ checklist.sort.group_by{ |mp, yes| mp.target }
47
+ end
48
+
49
+ # Override this method in subclasses.
50
+ def generate
51
+ end
52
+
53
+ #
54
+ def default_checklist
55
+ list = []
56
+ targets.each do |target|
57
+ target.public_instance_methods(false).each do |meth|
58
+ list << Unit.new(target, meth)
59
+ end
60
+ if private?
61
+ target.protected_instance_methods(false).each do |meth|
62
+ list << Unit.new(target, meth, :access=>:protected)
63
+ end
64
+ target.private_instance_methods(false).each do |meth|
65
+ list << Unit.new(target, meth, :access=>:private)
66
+ end
67
+ end
68
+ end
69
+ list
70
+ end
71
+
72
+ end
73
+
74
+ end
75
+
76
+
77
+ #
78
+ # # Generate code template.
79
+ # #
80
+ # def generate
81
+ # code = []
82
+ # system.each do |ofmod|
83
+ # next if ofmod.base.is_a?(Lemon::Test::Suite)
84
+ # code << "TestCase #{ofmod.base} do"
85
+ # ofmod.class_methods(public_only?).each do |meth|
86
+ # code << "\n MetaUnit :#{meth} => '' do\n raise Pending\n end"
87
+ # end
88
+ # ofmod.instance_methods(public_only?).each do |meth|
89
+ # code << "\n Unit :#{meth} => '' do\n raise Pending\n end"
90
+ # end
91
+ # code << "\nend\n"
92
+ # end
93
+ # code.join("\n")
94
+ # end
95
+
@@ -0,0 +1,32 @@
1
+ require 'uncool/generator/abstract'
2
+
3
+ module Uncool
4
+
5
+ # KO test generator.
6
+ class GeneratorKO < GeneratorAbstract
7
+
8
+ #
9
+ def generate
10
+ code = []
11
+ mapping.each do |target, units|
12
+ #next if /Lemon::Test::Suite/ =~ target.to_s
13
+ code << "require 'lemon/syntax/ko'\n"
14
+ code << "testcase #{target} do"
15
+ units.each do |(unit, yes)|
16
+ next if unit.covered? and !covered?
17
+ next if unit.private? and !private?
18
+ if unit.function?
19
+ code << "\n metaunit :#{unit.method} do\n\n end"
20
+ else
21
+ code << "\n unit :#{unit.method} do\n\n end"
22
+ end
23
+ end
24
+ code << "\nend\n"
25
+ end
26
+ code.join("\n")
27
+ end
28
+
29
+ end
30
+
31
+ end
32
+
@@ -0,0 +1,31 @@
1
+ require 'uncool/generator/abstract'
2
+
3
+ module Uncool
4
+
5
+ # Lemon test generator.
6
+ class GeneratorLemon < GeneratorAbstract
7
+
8
+ #
9
+ def generate
10
+ code = []
11
+ mapping.each do |target, units|
12
+ #next if /Lemon::Test::Suite/ =~ target.to_s
13
+ code << "TestCase #{target} do"
14
+ units.each do |unit|
15
+ next if unit.covered? and !covered?
16
+ next if unit.private? and !private?
17
+ if unit.function?
18
+ code << "\n MetaUnit :#{unit.method} => '' do\n\n end"
19
+ else
20
+ code << "\n Unit :#{unit.method} => '' do\n\n end"
21
+ end
22
+ end
23
+ code << "\nend\n"
24
+ end
25
+ code.join("\n")
26
+ end
27
+
28
+ end
29
+
30
+ end
31
+
@@ -0,0 +1,30 @@
1
+ require 'uncool/generator/abstract'
2
+
3
+ module Uncool
4
+
5
+ # QED test generator.
6
+ class GeneratorQED < GeneratorAbstract
7
+
8
+ #
9
+ def generate
10
+ code = []
11
+ mapping.each do |target, units|
12
+ #next if /Lemon::Test::Suite/ =~ target.to_s
13
+ code << "= #{target}\n"
14
+ units.each do |(unit, yes)|
15
+ next if unit.covered? and !covered?
16
+ next if unit.private? and !private?
17
+ if unit.function?
18
+ code << "== ::#{unit.method}\n\n"
19
+ else
20
+ code << "== ##{unit.method}\n\n"
21
+ end
22
+ end
23
+ end
24
+ code.join("\n")
25
+ end
26
+
27
+ end
28
+
29
+ end
30
+
@@ -0,0 +1,39 @@
1
+ <?xml version="1.0" encoding="UTF-8" standalone="no"?>
2
+ <!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN" "http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
3
+ <!-- Created with Inkscape (http://www.inkscape.org/) -->
4
+ <svg id="svg1" sodipodi:version="0.32" inkscape:version="0.38.1" width="400.00000pt" height="400.00000pt" sodipodi:docbase="/var/www/html/svg_gallery/svg/fruits" sodipodi:docname="lemon.svg" xmlns="http://www.w3.org/2000/svg" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:xlink="http://www.w3.org/1999/xlink">
5
+ <defs id="defs3">
6
+ <linearGradient id="linearGradient831">
7
+ <stop style="stop-color: rgb(255, 255, 0); stop-opacity: 1;" offset="0.0000000" id="stop832"/>
8
+ <stop style="stop-color: rgb(255, 227, 0); stop-opacity: 1;" offset="1.0000000" id="stop833"/>
9
+ </linearGradient>
10
+ <radialGradient xlink:href="#linearGradient831" id="radialGradient834" cx="0.33703703" cy="0.28358209" r="0.38183698" fx="0.33703703" fy="0.28358209"/>
11
+ </defs>
12
+ <sodipodi:namedview id="base" pagecolor="#ffffff" bordercolor="#666666" borderopacity="1.0" inkscape:pageopacity="0.0" inkscape:pageshadow="2" inkscape:zoom="1.3195079" inkscape:cx="120.13018" inkscape:cy="204.09312" inkscape:window-width="910" inkscape:window-height="775" inkscape:window-x="119" inkscape:window-y="24"/>
13
+ <g id="g838">
14
+ <path style="fill: url(#radialGradient834) rgb(0, 0, 0); fill-rule: evenodd; stroke: rgb(0, 0, 0); stroke-width: 10; stroke-linejoin: round; stroke-dasharray: none;" d="M 68.708186,148.12939 C 228.69852,9.5810597 474.45687,146.15839 471.15810,289.65487 C 497.54826,315.22034 467.85933,343.25988 451.36548,350.68211 C 309.51838,525.51691 17.577254,382.02043 34.895796,237.69925 C 12.847026,174.32754 32.421718,155.55162 68.708186,148.12939 z " id="path827" sodipodi:nodetypes="ccccc"/>
15
+ <path style="fill-opacity: 0.133333; fill-rule: evenodd; stroke-width: 1pt;" d="M 44.330330,267.99099 C 65.580330,246.74099 68.080330,411.74099 378.08033,350.49099 C 371.83033,344.24099 338.08033,201.74099 458.08033,249.24099 C 504.95533,263.61599 358.70533,239.55349 410.58033,339.24099 C 418.62433,352.33698 416.20533,352.36599 438.08033,357.99099 C 305.58033,500.49099 46.830330,390.49099 44.330330,267.99099 z " id="path828" sodipodi:nodetypes="cccccc"/>
16
+ <path style="fill: rgb(255, 255, 255); fill-opacity: 0.7; fill-rule: evenodd; stroke-width: 1pt;" d="M 68.080330,155.83295 C 124.36962,90.490990 313.68568,43.977604 438.08033,203.33295 C 395.58033,249.58295 275.58033,49.582958 68.080330,155.83295 z " id="path829" sodipodi:nodetypes="ccc"/>
17
+ <path style="fill: rgb(255, 255, 255); fill-opacity: 0.7; fill-rule: evenodd; stroke-width: 1pt;" d="M 469.33033,295.49099 C 483.64639,312.99099 470.58033,332.99099 460.58033,330.49099 C 381.83033,309.24099 424.33033,287.99099 469.33033,295.49099 z " id="path830" sodipodi:nodetypes="ccc"/>
18
+ </g>
19
+
20
+ <rdf:RDF xmlns="http://web.resource.org/cc/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#">
21
+ <Work rdf:about="">
22
+ <dc:title>Clipart by Nicu Buculei - pear</dc:title>
23
+ <dc:rights>
24
+ <Agent>
25
+ <dc:title>Nicu Buculei</dc:title>
26
+ </Agent>
27
+ </dc:rights>
28
+ <dc:type rdf:resource="http://purl.org/dc/dcmitype/StillImage"/>
29
+ <license rdf:resource="http://web.resource.org/cc/PublicDomain"/>
30
+ </Work>
31
+
32
+ <License rdf:about="http://web.resource.org/cc/PublicDomain">
33
+ <permits rdf:resource="http://web.resource.org/cc/Reproduction"/>
34
+ <permits rdf:resource="http://web.resource.org/cc/Distribution"/>
35
+ <permits rdf:resource="http://web.resource.org/cc/DerivativeWorks"/>
36
+ </License>
37
+
38
+ </rdf:RDF>
39
+ </svg>
@@ -0,0 +1,17 @@
1
+ require 'uncool/app'
2
+
3
+ module Uncool
4
+
5
+ # Run coverage trace and log results.
6
+ #
7
+ # targets = ENV['squeeze'].split(',')
8
+ # Lemon.log(targets, :output=>'log')
9
+ #
10
+ # NOTE: This sets up an at_exit routine.
11
+ def self.log(options={})
12
+ app = App.new(options)
13
+ app.log
14
+ end
15
+
16
+ end
17
+
@@ -0,0 +1,29 @@
1
+ Object.__send__(:remove_const, :VERSION) if Object.const_defined?(:VERSION) # becuase Ruby 1.8~ gets in the way
2
+
3
+ module Uncool
4
+
5
+ def self.__DIR__
6
+ File.dirname(__FILE__)
7
+ end
8
+
9
+ def self.gemfile
10
+ @gemfile ||= (
11
+ require 'yaml'
12
+ YAML.load(File.new(__DIR__ + '/gemfile.yml'))
13
+ )
14
+ end
15
+
16
+ def self.profile
17
+ @profile ||= (
18
+ require 'yaml'
19
+ YAML.load(File.new(__DIR__ + '/profile.yml'))
20
+ )
21
+ end
22
+
23
+ def self.const_missing(name)
24
+ name = name.to_s.downcase
25
+ gemfile[name] || profile[name]
26
+ end
27
+
28
+ end
29
+