activefacts 1.6.0 → 1.7.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (169) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +14 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +4 -0
  5. data/Gemfile +14 -0
  6. data/LICENSE.txt +21 -0
  7. data/README.md +60 -0
  8. data/Rakefile +3 -80
  9. data/activefacts.gemspec +36 -0
  10. data/bin/afgen +4 -2
  11. data/bin/cql +5 -1
  12. data/lib/activefacts.rb +3 -12
  13. data/lib/activefacts/{vocabulary/query_evaluator.rb → query/evaluator.rb} +0 -0
  14. data/lib/activefacts/version.rb +2 -2
  15. metadata +48 -296
  16. data/History.txt +0 -4
  17. data/LICENSE +0 -19
  18. data/Manifest.txt +0 -165
  19. data/README.rdoc +0 -81
  20. data/css/offline.css +0 -3
  21. data/css/orm2.css +0 -124
  22. data/css/print.css +0 -8
  23. data/css/style-print.css +0 -357
  24. data/css/style.css +0 -387
  25. data/download.html +0 -110
  26. data/examples/CQL/Address.cql +0 -44
  27. data/examples/CQL/Blog.cql +0 -54
  28. data/examples/CQL/CompanyDirectorEmployee.cql +0 -56
  29. data/examples/CQL/Death.cql +0 -17
  30. data/examples/CQL/Diplomacy.cql +0 -48
  31. data/examples/CQL/Genealogy.cql +0 -98
  32. data/examples/CQL/Insurance.cql +0 -320
  33. data/examples/CQL/Marriage.cql +0 -18
  34. data/examples/CQL/Metamodel.cql +0 -493
  35. data/examples/CQL/Monogamy.cql +0 -24
  36. data/examples/CQL/MultiInheritance.cql +0 -22
  37. data/examples/CQL/NonRoleId.cql +0 -14
  38. data/examples/CQL/OddIdentifier.cql +0 -18
  39. data/examples/CQL/OilSupply.cql +0 -53
  40. data/examples/CQL/OneToOnes.cql +0 -17
  41. data/examples/CQL/Orienteering.cql +0 -111
  42. data/examples/CQL/PersonPlaysGame.cql +0 -18
  43. data/examples/CQL/RedundantDependency.cql +0 -34
  44. data/examples/CQL/SchoolActivities.cql +0 -33
  45. data/examples/CQL/SeparateSubtype.cql +0 -30
  46. data/examples/CQL/ServiceDirector.cql +0 -276
  47. data/examples/CQL/SimplestUnary.cql +0 -12
  48. data/examples/CQL/Supervision.cql +0 -34
  49. data/examples/CQL/WaiterTips.cql +0 -33
  50. data/examples/CQL/Warehousing.cql +0 -101
  51. data/examples/CQL/WindowInRoomInBldg.cql +0 -28
  52. data/examples/CQL/unit.cql +0 -474
  53. data/examples/index.html +0 -420
  54. data/examples/intro.html +0 -327
  55. data/examples/local.css +0 -24
  56. data/index.html +0 -111
  57. data/lib/activefacts/cql.rb +0 -35
  58. data/lib/activefacts/cql/CQLParser.treetop +0 -158
  59. data/lib/activefacts/cql/Context.treetop +0 -48
  60. data/lib/activefacts/cql/Expressions.treetop +0 -67
  61. data/lib/activefacts/cql/FactTypes.treetop +0 -358
  62. data/lib/activefacts/cql/Language/English.treetop +0 -315
  63. data/lib/activefacts/cql/LexicalRules.treetop +0 -253
  64. data/lib/activefacts/cql/ObjectTypes.treetop +0 -210
  65. data/lib/activefacts/cql/Rakefile +0 -14
  66. data/lib/activefacts/cql/Terms.treetop +0 -183
  67. data/lib/activefacts/cql/ValueTypes.treetop +0 -202
  68. data/lib/activefacts/cql/compiler.rb +0 -156
  69. data/lib/activefacts/cql/compiler/clause.rb +0 -1137
  70. data/lib/activefacts/cql/compiler/constraint.rb +0 -581
  71. data/lib/activefacts/cql/compiler/entity_type.rb +0 -457
  72. data/lib/activefacts/cql/compiler/expression.rb +0 -443
  73. data/lib/activefacts/cql/compiler/fact.rb +0 -390
  74. data/lib/activefacts/cql/compiler/fact_type.rb +0 -421
  75. data/lib/activefacts/cql/compiler/query.rb +0 -106
  76. data/lib/activefacts/cql/compiler/shared.rb +0 -161
  77. data/lib/activefacts/cql/compiler/value_type.rb +0 -174
  78. data/lib/activefacts/cql/nodes.rb +0 -49
  79. data/lib/activefacts/cql/parser.rb +0 -241
  80. data/lib/activefacts/dependency_analyser.rb +0 -182
  81. data/lib/activefacts/generate/absorption.rb +0 -70
  82. data/lib/activefacts/generate/composition.rb +0 -118
  83. data/lib/activefacts/generate/cql.rb +0 -714
  84. data/lib/activefacts/generate/dm.rb +0 -279
  85. data/lib/activefacts/generate/help.rb +0 -64
  86. data/lib/activefacts/generate/helpers/inject.rb +0 -16
  87. data/lib/activefacts/generate/helpers/oo.rb +0 -162
  88. data/lib/activefacts/generate/helpers/ordered.rb +0 -605
  89. data/lib/activefacts/generate/helpers/rails.rb +0 -57
  90. data/lib/activefacts/generate/html/glossary.rb +0 -461
  91. data/lib/activefacts/generate/json.rb +0 -337
  92. data/lib/activefacts/generate/null.rb +0 -32
  93. data/lib/activefacts/generate/rails/models.rb +0 -246
  94. data/lib/activefacts/generate/rails/schema.rb +0 -216
  95. data/lib/activefacts/generate/records.rb +0 -46
  96. data/lib/activefacts/generate/ruby.rb +0 -133
  97. data/lib/activefacts/generate/sql/mysql.rb +0 -280
  98. data/lib/activefacts/generate/sql/server.rb +0 -273
  99. data/lib/activefacts/generate/stats.rb +0 -69
  100. data/lib/activefacts/generate/text.rb +0 -27
  101. data/lib/activefacts/generate/topics.rb +0 -265
  102. data/lib/activefacts/generate/traits/datavault.rb +0 -241
  103. data/lib/activefacts/generate/traits/oo.rb +0 -73
  104. data/lib/activefacts/generate/traits/ordered.rb +0 -33
  105. data/lib/activefacts/generate/traits/ruby.rb +0 -210
  106. data/lib/activefacts/generate/transform/datavault.rb +0 -266
  107. data/lib/activefacts/generate/transform/surrogate.rb +0 -214
  108. data/lib/activefacts/generate/version.rb +0 -26
  109. data/lib/activefacts/input/cql.rb +0 -43
  110. data/lib/activefacts/input/orm.rb +0 -1636
  111. data/lib/activefacts/mapping/rails.rb +0 -132
  112. data/lib/activefacts/persistence.rb +0 -15
  113. data/lib/activefacts/persistence/columns.rb +0 -446
  114. data/lib/activefacts/persistence/foreignkey.rb +0 -187
  115. data/lib/activefacts/persistence/index.rb +0 -240
  116. data/lib/activefacts/persistence/object_type.rb +0 -198
  117. data/lib/activefacts/persistence/reference.rb +0 -434
  118. data/lib/activefacts/persistence/tables.rb +0 -380
  119. data/lib/activefacts/registry.rb +0 -11
  120. data/lib/activefacts/support.rb +0 -132
  121. data/lib/activefacts/vocabulary.rb +0 -9
  122. data/lib/activefacts/vocabulary/extensions.rb +0 -1348
  123. data/lib/activefacts/vocabulary/metamodel.rb +0 -570
  124. data/lib/activefacts/vocabulary/verbaliser.rb +0 -804
  125. data/script/txt2html +0 -71
  126. data/spec/absorption_spec.rb +0 -95
  127. data/spec/cql/comparison_spec.rb +0 -89
  128. data/spec/cql/context_spec.rb +0 -94
  129. data/spec/cql/contractions_spec.rb +0 -224
  130. data/spec/cql/deontic_spec.rb +0 -88
  131. data/spec/cql/entity_type_spec.rb +0 -320
  132. data/spec/cql/expressions_spec.rb +0 -66
  133. data/spec/cql/fact_type_matching_spec.rb +0 -338
  134. data/spec/cql/french_spec.rb +0 -21
  135. data/spec/cql/parser/bad_literals_spec.rb +0 -86
  136. data/spec/cql/parser/constraints_spec.rb +0 -19
  137. data/spec/cql/parser/entity_types_spec.rb +0 -106
  138. data/spec/cql/parser/expressions_spec.rb +0 -199
  139. data/spec/cql/parser/fact_types_spec.rb +0 -44
  140. data/spec/cql/parser/literals_spec.rb +0 -312
  141. data/spec/cql/parser/pragmas_spec.rb +0 -89
  142. data/spec/cql/parser/value_types_spec.rb +0 -42
  143. data/spec/cql/role_matching_spec.rb +0 -148
  144. data/spec/cql/samples_spec.rb +0 -244
  145. data/spec/cql_cql_spec.rb +0 -73
  146. data/spec/cql_dm_spec.rb +0 -136
  147. data/spec/cql_mysql_spec.rb +0 -69
  148. data/spec/cql_parse_spec.rb +0 -34
  149. data/spec/cql_ruby_spec.rb +0 -73
  150. data/spec/cql_sql_spec.rb +0 -72
  151. data/spec/cql_symbol_tables_spec.rb +0 -261
  152. data/spec/cqldump_spec.rb +0 -170
  153. data/spec/helpers/array_matcher.rb +0 -23
  154. data/spec/helpers/ctrl_c_support.rb +0 -52
  155. data/spec/helpers/diff_matcher.rb +0 -39
  156. data/spec/helpers/file_matcher.rb +0 -34
  157. data/spec/helpers/parse_to_ast_matcher.rb +0 -80
  158. data/spec/helpers/string_matcher.rb +0 -30
  159. data/spec/helpers/test_parser.rb +0 -15
  160. data/spec/norma_cql_spec.rb +0 -66
  161. data/spec/norma_ruby_spec.rb +0 -62
  162. data/spec/norma_ruby_sql_spec.rb +0 -107
  163. data/spec/norma_sql_spec.rb +0 -57
  164. data/spec/norma_tables_spec.rb +0 -95
  165. data/spec/ruby_api_spec.rb +0 -23
  166. data/spec/spec_helper.rb +0 -35
  167. data/spec/transform_surrogate_spec.rb +0 -59
  168. data/status.html +0 -138
  169. data/why.html +0 -60
@@ -1,52 +0,0 @@
1
- # Monkey patch in CTRL-C support for rspec from
2
- # http://github.com/dchelimsky/rspec/commit/029f77c5063894cf52af05335b8e1c278411978b
3
- # until it gets released
4
-
5
- module Spec
6
- module Example
7
- module ExampleMethods
8
- def execute(run_options, instance_variables) # :nodoc:
9
- run_options.reporter.example_started(@_proxy)
10
- set_instance_variables_from_hash(instance_variables)
11
-
12
- execution_error = nil
13
- Timeout.timeout(run_options.timeout) do
14
- begin
15
- before_each_example
16
- instance_eval(&@_implementation)
17
- rescue Interrupt
18
- exit 1
19
- rescue Exception => e
20
- execution_error ||= e
21
- end
22
- begin
23
- after_each_example
24
- rescue Interrupt
25
- exit 1
26
- rescue Exception => e
27
- execution_error ||= e
28
- end
29
- end
30
-
31
- run_options.reporter.example_finished(@_proxy.update(description), execution_error)
32
- success = execution_error.nil? || ExamplePendingError === execution_error
33
- end
34
- end
35
- end
36
- end
37
-
38
- module Spec
39
- module Runner
40
- class ExampleGroupRunner
41
- def run
42
- prepare
43
- success = true
44
- example_groups.each do |example_group|
45
- success = success & example_group.run(@options)
46
- end
47
- finish
48
- success
49
- end
50
- end
51
- end
52
- end
@@ -1,39 +0,0 @@
1
- require 'pathname'
2
-
3
- require 'rspec/matchers'
4
-
5
- class RSpec::Matchers::DSL::Matcher
6
- attr_writer :expected
7
- end
8
-
9
- RSpec::Matchers.define :differ_from do |expected|
10
- match do |actual|
11
- case expected
12
- when Pathname
13
- @m = have_different_contents
14
- @m.expected = expected
15
- @m.matches?(actual)
16
- when Array
17
- # If we pass "expected" here, it expects an array.
18
- # Works here, but not for Pathname or String
19
- # Hence the need for the attr_writer hack above.
20
- @m = be_different_array_from
21
- @m.expected = expected
22
- @m.matches?(actual)
23
- when String
24
- @m = have_different_contents
25
- @m.expected = expected
26
- @m.matches?(actual)
27
- else
28
- raise "DiffMatcher doesn't know how to match a #{expected.class}"
29
- end
30
- end
31
-
32
- failure_message_for_should do |actual|
33
- @m.failure_message_for_should
34
- end
35
-
36
- failure_message_for_should_not do |actual|
37
- @m.failure_message_for_should_not
38
- end
39
- end
@@ -1,34 +0,0 @@
1
- require 'diff/lcs'
2
-
3
- RSpec::Matchers.define :have_different_contents do |x|
4
- match do |actual|
5
- perform_match(actual, expected)
6
- end
7
-
8
- def perform_match(actual, expected)
9
- expected = File.open(expected).read if expected.is_a?(Pathname)
10
- expected = expected.scan(/[^\n]+/) unless expected.is_a?(Array)
11
-
12
- actual = File.open(actual).read if actual.is_a?(Pathname)
13
- actual = actual.scan(/[^\n]+/) unless actual.is_a?(Array)
14
-
15
- differences = Diff::LCS::diff(expected, actual)
16
- @diff = differences.map do |chunk|
17
- added_at = (add = chunk.detect{|d| d.action == '+'}) && add.position+1
18
- removed_at = (remove = chunk.detect{|d| d.action == '-'}) && remove.position+1
19
- "Line #{added_at}/#{removed_at}:\n"+
20
- chunk.map do |change|
21
- "#{change.action} #{change.element}"
22
- end*"\n"
23
- end*"\n"
24
- @diff != ''
25
- end
26
-
27
- failure_message_for_should do |actual|
28
- "expected a difference, but got none"
29
- end
30
-
31
- failure_message_for_should_not do |actual|
32
- "expected no difference, but got:\n#{@diff}"
33
- end
34
- end
@@ -1,80 +0,0 @@
1
- require 'rspec/expectations'
2
-
3
- require 'activefacts/cql'
4
- require 'activefacts/support'
5
- require 'activefacts/api/support'
6
- require 'helpers/test_parser'
7
-
8
- RSpec::Matchers.define :parse_to_ast do |*expected_asts|
9
- def canonicalise(s)
10
- if s.is_a?(Array)
11
- s.map{|e| canonicalise(e)}
12
- else
13
- s.to_s.gsub(/\s+/,' ').strip
14
- end
15
- end
16
-
17
- match do |actual|
18
- @parser = TestParser.new
19
- @result = @parser.parse_all(actual, :definition)
20
-
21
- # If the expected_asts is "false", treat this test as pending:
22
- if expected_asts == [false]
23
- if @result
24
- # Unfortunately there's no way to say why the failure was expected here
25
- # RSpec stores it in example.metadata[:execution_result][:pending_message]
26
- raise RSpec::Core::PendingExampleFixedError.new
27
- else
28
- throw :pending_declared_in_example, "Should parse #{actual.strip.inspect}"
29
- end
30
- end
31
-
32
- # If we failed to parse, fail and say why:
33
- next false unless @result
34
-
35
- # Otherwise compare the canonical form of the AST
36
- @canonical_form = @result.map{|d| canonicalise(d.ast)}
37
-
38
- # If we weren't given an AST, this test is pending. Show what result we obtained:
39
- throw :pending_declared_in_example, actual.inspect+' should parse to ['+@canonical_form*', '+']' if expected_asts.empty?
40
-
41
- @canonical_form == canonicalise(expected_asts)
42
- end
43
-
44
- failure_message_for_should do
45
- if !@result
46
- @parser.failure_reason
47
- else
48
- "Expected %q{#{canonicalise(expected_asts)}}\nbut got: %q{#{@canonical_form}}"
49
- end
50
- end
51
- end
52
-
53
- RSpec::Matchers.define :fail_to_parse do |*error_regexp|
54
- match do |actual|
55
- begin
56
- @parser = TestParser.new
57
- @actual = actual
58
- @result = @parser.parse_all(actual, :definition)
59
- rescue => e
60
- @exception = e.message
61
- end
62
- @result.should be_nil
63
- if @re = error_regexp[0]
64
- @parser.failure_reason.should =~ @re
65
- else
66
- throw :pending_declared_in_example, actual.inspect+' fails, please add message pattern to match '+@parser.failure_reason.inspect
67
- end
68
- end
69
-
70
- failure_message_for_should do
71
- if @result
72
- @canonical_form = @result.map{|d| canonicalise(d.ast)}
73
- "Expected not to succeed in parsing #{actual.inspect}\nbut got #{@canonical_form.inspect}"
74
- else
75
- "Failed as expected in parsing #{actual.inspect}\n" +
76
- "but not for the right reason: #{@re.inspect}\n"+
77
- "got #{@parser.failure_reason.inspect}"
78
- end
79
- end
80
- end
@@ -1,30 +0,0 @@
1
- require 'diff/lcs'
2
-
3
- RSpec::Matchers.define :have_different_contents do |x|
4
- match do |actual|
5
- perform_match(actual, expected)
6
- end
7
-
8
- def perform_match(actual, expected)
9
- expected_lines = expected.scan(/[^\n]+/)
10
- actual_lines = actual.scan(/[^\n]+/)
11
- differences = Diff::LCS::diff(expected_lines, actual_lines)
12
- @diff = differences.map do |chunk|
13
- added_at = (add = chunk.detect{|d| d.action == '+'}) && add.position+1
14
- removed_at = (remove = chunk.detect{|d| d.action == '-'}) && remove.position+1
15
- "Line #{added_at}/#{removed_at}:\n"+
16
- chunk.map do |change|
17
- "#{change.action} #{change.element}"
18
- end*"\n"
19
- end*"\n"
20
- @diff != ''
21
- end
22
-
23
- failure_message_for_should do |actual|
24
- "expected a difference, but got none"
25
- end
26
-
27
- failure_message_for_should_not do |actual|
28
- "expected no difference, but got:\n#{@diff}"
29
- end
30
- end
@@ -1,15 +0,0 @@
1
- # The test parser regards any word starting with an upper-case letter as a pre-existing term
2
- require 'activefacts/cql/Language/English'
3
- class TestParser < ActiveFacts::CQL::Parser
4
- include ActiveFacts::CQL::English
5
- def context
6
- @context ||= Context.new(self)
7
- end
8
-
9
- class Context < ActiveFacts::CQL::Parser::Context
10
- # Capitalised words that are otherwise undefined are treated as terms:
11
- def system_term(t)
12
- (first = t[0,1] and first.upcase == first) ? {t=>t} : false
13
- end
14
- end
15
- end
@@ -1,66 +0,0 @@
1
- #
2
- # ActiveFacts tests: Parse all NORMA files and check the generated CQL.
3
- # Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
4
- #
5
-
6
- require 'spec_helper'
7
- require 'stringio'
8
- require 'activefacts/vocabulary'
9
- require 'activefacts/support'
10
- require 'activefacts/input/orm'
11
- require 'activefacts/generate/cql'
12
-
13
- describe "Norma Loader" do
14
- orm_failures = {
15
- "SubtypePI" => "Has an illegal uniqueness constraint",
16
- }
17
- orm_cql_failures = {
18
- # "OddIdentifier" => "Strange identification pattern is incorrectly verbalised to CQL", # Fixed
19
- "UnaryIdentification" => "No PI for VisitStatus",
20
- }
21
- # Generate and return the CQL for the given vocabulary
22
- def cql(vocabulary)
23
- output = StringIO.new
24
- @dumper = ActiveFacts::Generate::CQL.new(vocabulary.constellation)
25
- @dumper.generate(output)
26
- output.rewind
27
- output.read
28
- end
29
-
30
- pattern = ENV["AFTESTS"] || "*"
31
- Dir["examples/norma/#{pattern}.orm"].each do |orm_file|
32
- expected_file = orm_file.sub(%r{/norma/(.*).orm\Z}, '/CQL/\1.cql')
33
- actual_file = orm_file.sub(%r{examples/norma/(.*).orm\Z}, 'spec/actual/\1.cql')
34
- base = File.basename(orm_file, ".orm")
35
-
36
- next unless ENV["AFTESTS"] || File.exists?(expected_file)
37
-
38
- it "should load #{orm_file} and dump CQL matching #{expected_file}" do
39
- begin
40
- vocabulary = ActiveFacts::Input::ORM.readfile(orm_file)
41
- rescue => e
42
- raise unless orm_failures.include?(base)
43
- pending orm_failures[base]
44
- end
45
-
46
- cql_text = cql(vocabulary)
47
- # Save the actual file:
48
- Dir.mkdir "spec/actual" rescue nil
49
- File.open(actual_file, "w") { |f| f.write cql_text }
50
-
51
- pending("expected output file #{expected_file} not found") unless File.exists? expected_file
52
-
53
- expected_text = File.open(expected_file) {|f| f.read }
54
-
55
- broken = orm_cql_failures[base]
56
- if broken
57
- pending(broken) {
58
- cql_text.should_not differ_from(expected_text)
59
- }
60
- else
61
- cql_text.should_not differ_from(expected_text)
62
- File.delete(actual_file)
63
- end
64
- end
65
- end
66
- end
@@ -1,62 +0,0 @@
1
- #
2
- # ActiveFacts tests: Parse all CQL files and check the generated Ruby.
3
- # Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
4
- #
5
-
6
- require 'spec_helper'
7
- require 'stringio'
8
- require 'activefacts/vocabulary'
9
- require 'activefacts/support'
10
- require 'activefacts/input/orm'
11
- require 'activefacts/generate/ruby'
12
-
13
- class String
14
- def strip_comments()
15
- c_comment = %r{/\*((?!\*/).)*\*/}m
16
- gsub(c_comment, '').gsub(%r{\n\n+},"\n")
17
- end
18
- end
19
-
20
- describe "NORMA Loader with Ruby output" do
21
- orm_failures = {
22
- "SubtypePI" => "Has an illegal uniqueness constraint",
23
- }
24
-
25
- # Generate and return the Ruby for the given vocabulary
26
- def ruby(vocabulary)
27
- output = StringIO.new
28
- @dumper = ActiveFacts::Generate::RUBY.new(vocabulary.constellation)
29
- @dumper.generate(output)
30
- output.rewind
31
- output.read
32
- end
33
-
34
- pattern = ENV["AFTESTS"] || "*"
35
- Dir["examples/norma/#{pattern}.orm"].each do |orm_file|
36
- expected_file = orm_file.sub(%r{examples/norma/(.*).orm\Z}, 'examples/ruby/\1.rb')
37
- actual_file = orm_file.sub(%r{examples/norma/(.*).orm\Z}, 'spec/actual/\1.rb')
38
- base = File.basename(orm_file, ".orm")
39
-
40
- next unless ENV["AFTESTS"] || File.exists?(expected_file)
41
-
42
- it "should load #{orm_file} and dump Ruby matching #{expected_file}" do
43
- begin
44
- vocabulary = ActiveFacts::Input::ORM.readfile(orm_file)
45
- rescue => e
46
- raise unless orm_failures.include?(base)
47
- pending orm_failures[base]
48
- end
49
-
50
- # Build and save the actual file:
51
- ruby_text = ruby(vocabulary)
52
- Dir.mkdir "spec/actual" rescue nil
53
- File.open(actual_file, "w") { |f| f.write ruby_text }
54
-
55
- pending("expected output file #{expected_file} not found") unless File.exists? expected_file
56
-
57
- expected_text = File.open(expected_file) {|f| f.read }
58
- ruby_text.should_not differ_from(expected_text)
59
- File.delete(actual_file) # It succeeded, we don't need the file.
60
- end
61
- end
62
- end
@@ -1,107 +0,0 @@
1
- #
2
- # ActiveFacts tests: Compare column lists created by aborption and by generated Ruby.
3
- # Copyright (c) 2008 Clifford Heath. Read the LICENSE file.
4
- #
5
-
6
- require 'spec_helper'
7
- require 'stringio'
8
- require 'activefacts/vocabulary'
9
- require 'activefacts/support'
10
- require 'activefacts/input/orm'
11
- require 'activefacts/persistence'
12
- require 'activefacts/generate/ruby'
13
-
14
- describe "Column lists from absorption compared with Ruby's" do
15
- orm_failures = {
16
- "SubtypePI" => "Has an illegal uniqueness constraint",
17
- }
18
- norma_ruby_failures = {
19
- "UnaryIdentification" => "No PI for VisitStatus",
20
- "BPMN" => "Has duplicate column names",
21
- }
22
-
23
- # Generate and return the Ruby for the given vocabulary
24
- def ruby(vocabulary)
25
- output = StringIO.new
26
- @dumper = ActiveFacts::Generate::RUBY.new(vocabulary.constellation, "mapping=sql")
27
- @dumper.generate(output)
28
- output.rewind
29
- output.read
30
- end
31
-
32
- pattern = ENV["AFTESTS"] || "*"
33
- Dir["examples/norma/#{pattern}.orm"].each do |orm_file|
34
- expected_file = orm_file.sub(%r{examples/norma/(.*).orm\Z}, 'examples/ruby/\1.rb')
35
- actual_file = orm_file.sub(%r{examples/norma/(.*).orm\Z}, 'spec/actual/\1.rb')
36
- base = File.basename(orm_file, ".orm")
37
-
38
- next unless ENV["AFTESTS"] || File.exists?(expected_file)
39
-
40
- it "should load #{orm_file} and generate relational composition and Ruby with matching column names" do
41
- begin
42
- vocabulary = ActiveFacts::Input::ORM.readfile(orm_file)
43
- rescue => e
44
- raise unless orm_failures.include?(base)
45
- pending orm_failures[base]
46
- end
47
-
48
- # Get the list of tables from the relational composition:
49
- absorption_tables = vocabulary.tables.sort_by(&:name)
50
- absorption_table_names = absorption_tables.map{|at| at.name.gsub(/\s/,'')}
51
-
52
- # Build the Ruby and eval it:
53
- ruby_text = ruby(vocabulary)
54
- Dir.mkdir "spec/actual" rescue nil
55
- File.open(actual_file, "w") { |f| f.write ruby_text }
56
-
57
- broken = norma_ruby_failures[base]
58
- eval_it = lambda {
59
- Object.send :eval, ruby_text
60
- }
61
- exception = nil
62
- if broken
63
- pending(broken) {
64
- lambda {
65
- begin
66
- eval_it.call
67
- rescue => exception
68
- if trace :exception
69
- puts exception.to_s+": \n\t"+exception.backtrace*"\n\t"
70
- end
71
- raise
72
- end
73
- }.should_not raise_error
74
- }
75
- else
76
- lambda {
77
- begin
78
- eval_it.call
79
- rescue => exception
80
- if trace :exception
81
- puts exception.to_s+": \n\t"+exception.backtrace*"\n\t"
82
- end
83
- raise
84
- end
85
- }.should_not raise_error
86
- end
87
-
88
- # Get a list of table classes in the new module, sorted by name
89
- mod = eval(vocabulary.name)
90
- ruby_tables = mod.constants.map{|n|
91
- c = mod.const_get(n)
92
- next unless c.class == Class
93
- c.is_table ? c : nil
94
- }.compact.sort_by{|c|
95
- c.basename
96
- }
97
- ruby_table_names = ruby_tables.map{|c| c.basename}
98
-
99
- # Assert that the list of tables is the same:
100
- ruby_table_names.should_not differ_from(absorption_table_names)
101
-
102
- # Clean up:
103
- Object.send :remove_const, vocabulary.name.to_sym
104
- File.delete(actual_file) # It succeeded, we don't need the file.
105
- end
106
- end
107
- end