uncool 1.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.
@@ -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
+