activefacts 1.6.0 → 1.7.1

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 (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