masterview 0.2.5 → 0.3.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.
Files changed (155) hide show
  1. data/CHANGELOG +31 -1
  2. data/README +70 -69
  3. data/RELEASE_NOTES +70 -64
  4. data/Rakefile +26 -27
  5. data/TODO +13 -29
  6. data/doc/about.html +246 -0
  7. data/doc/configuration.html +49 -36
  8. data/doc/developer.html +423 -41
  9. data/doc/directives.html +139 -51
  10. data/doc/guide.html +19 -9
  11. data/doc/index.html +90 -224
  12. data/doc/installation.html +36 -28
  13. data/doc/media_list.html +30 -20
  14. data/doc/simple_diagram.html +3 -5
  15. data/doc/stylesheets/masterview.css +16 -1
  16. data/examples/rails_app_config/masterview/settings.rb +2 -1
  17. data/init.rb +1 -1
  18. data/lib/#ChangeLog# +6 -0
  19. data/lib/masterview/analyzer.rb +48 -34
  20. data/lib/masterview/attr_string_parser.rb +5 -1
  21. data/lib/masterview/case_insensitive_hash.rb +69 -0
  22. data/lib/masterview/{pathname_extensions.rb → core_ext/pathname.rb} +0 -0
  23. data/lib/masterview/{string_extensions.rb → core_ext/string.rb} +0 -0
  24. data/lib/masterview/deprecated/directive_base.rb +362 -0
  25. data/lib/masterview/directive_base.rb +201 -179
  26. data/lib/masterview/directive_dsl.rb +457 -0
  27. data/lib/masterview/directive_helpers.rb +28 -141
  28. data/lib/masterview/directive_load_path.rb +388 -0
  29. data/lib/masterview/directive_metadata.rb +377 -0
  30. data/lib/masterview/directive_registry.rb +259 -69
  31. data/lib/masterview/directives/.metadata +16 -0
  32. data/lib/masterview/directives/attr.rb +9 -8
  33. data/lib/masterview/directives/block.rb +11 -14
  34. data/lib/masterview/directives/check_box.rb +13 -18
  35. data/lib/masterview/directives/collection_select.rb +15 -29
  36. data/lib/masterview/directives/content.rb +9 -3
  37. data/lib/masterview/directives/else.rb +15 -13
  38. data/lib/masterview/directives/elsif.rb +14 -13
  39. data/lib/masterview/directives/eval.rb +20 -0
  40. data/lib/masterview/directives/form.rb +56 -9
  41. data/lib/masterview/directives/form_remote.rb +26 -0
  42. data/lib/masterview/directives/global_inline_erb.rb +10 -14
  43. data/lib/masterview/directives/hidden_field.rb +11 -20
  44. data/lib/masterview/directives/if.rb +13 -12
  45. data/lib/masterview/directives/image_tag.rb +20 -28
  46. data/lib/masterview/directives/import.rb +5 -12
  47. data/lib/masterview/directives/import_render.rb +7 -19
  48. data/lib/masterview/directives/insert_generated_comment.rb +8 -11
  49. data/lib/masterview/directives/javascript_include.rb +21 -12
  50. data/lib/masterview/directives/link_to.rb +14 -8
  51. data/lib/masterview/directives/link_to_function.rb +22 -0
  52. data/lib/masterview/directives/link_to_if.rb +15 -13
  53. data/lib/masterview/directives/link_to_remote.rb +13 -8
  54. data/lib/masterview/directives/omit_tag.rb +32 -16
  55. data/lib/masterview/directives/password_field.rb +10 -22
  56. data/lib/masterview/directives/radio_button.rb +11 -22
  57. data/lib/masterview/directives/replace.rb +7 -8
  58. data/lib/masterview/directives/select.rb +11 -24
  59. data/lib/masterview/directives/stylesheet_link.rb +20 -12
  60. data/lib/masterview/directives/submit.rb +11 -5
  61. data/lib/masterview/directives/text_area.rb +10 -23
  62. data/lib/masterview/directives/text_field.rb +10 -22
  63. data/lib/masterview/exceptions.rb +21 -0
  64. data/lib/masterview/extras/app/controllers/masterview_controller.rb +102 -75
  65. data/lib/masterview/extras/app/views/layouts/masterview_admin.rhtml +24 -23
  66. data/lib/masterview/extras/app/views/layouts/masterview_admin_config.rhtml +81 -0
  67. data/lib/masterview/extras/app/views/masterview/admin/configuration.rhtml +5 -1
  68. data/lib/masterview/extras/app/views/masterview/admin/create.rhtml +2 -2
  69. data/lib/masterview/extras/app/views/masterview/admin/directives.rhtml +5 -0
  70. data/lib/masterview/extras/app/views/masterview/admin/features.rhtml +5 -79
  71. data/lib/masterview/extras/app/views/masterview/admin/interact.rhtml +5 -0
  72. data/lib/masterview/extras/app/views/masterview/admin/list.rhtml +3 -71
  73. data/lib/masterview/extras/init_mv_admin_pages.rb +42 -23
  74. data/lib/masterview/filter_helpers.rb +26 -0
  75. data/lib/masterview/initializer.rb +99 -53
  76. data/lib/masterview/io.rb +19 -15
  77. data/lib/masterview/keyword_expander.rb +7 -2
  78. data/lib/masterview/masterview_info.rb +229 -23
  79. data/lib/masterview/masterview_version.rb +2 -2
  80. data/lib/masterview/parser.rb +275 -105
  81. data/lib/masterview/parser_helpers.rb +54 -0
  82. data/lib/masterview/rails_ext/action_controller_erb_direct.rb +29 -0
  83. data/lib/masterview/rails_ext/action_controller_reparse_checking.rb +27 -0
  84. data/lib/masterview/{extras/init_rails_erb_mv_direct.rb → rails_ext/action_view_erb_direct.rb} +12 -59
  85. data/lib/masterview/template_spec.rb +3 -2
  86. data/lib/masterview.rb +21 -12
  87. data/lib/rexml/parsers/baseparser_with_doctype_fix.rb +473 -0
  88. data/lib/rexml/parsers/sax2parser_with_doctype_fix.rb +243 -0
  89. data/test/directive_test_helper.rb +135 -0
  90. data/test/fixtures/directives/id_check.rb +18 -0
  91. data/test/fixtures/directives/test_directive_events.rb +70 -0
  92. data/test/test_helper.rb +18 -5
  93. data/test/tmp/views/layouts/product.rhtml +10 -10
  94. data/test/tmp/views/product/_form.rhtml +4 -4
  95. data/test/tmp/views/product/_product.rhtml +3 -3
  96. data/test/tmp/views/product/destroy.rhtml +5 -5
  97. data/test/tmp/views/product/edit.rhtml +4 -4
  98. data/test/tmp/views/product/list.rhtml +3 -3
  99. data/test/tmp/views/product/new.rhtml +4 -4
  100. data/test/tmp/views/product/show.rhtml +2 -2
  101. data/test/unit/attr_string_parser_test.rb +105 -0
  102. data/test/unit/case_insensitive_hash_mod_test.rb +104 -0
  103. data/test/unit/config_settings_test.rb +13 -1
  104. data/test/unit/default_generate_mio_filter_test.rb +3 -3
  105. data/test/unit/deprecated_directive_base_test.rb +30 -0
  106. data/test/unit/directive_attr_test.rb +111 -35
  107. data/test/unit/directive_base_test.rb +520 -1
  108. data/test/unit/directive_block_test.rb +30 -22
  109. data/test/unit/directive_content_test.rb +24 -11
  110. data/test/unit/directive_else_test.rb +18 -15
  111. data/test/unit/directive_elsif_test.rb +17 -15
  112. data/test/unit/directive_form_remote_test.rb +59 -0
  113. data/test/unit/directive_form_test.rb +31 -39
  114. data/test/unit/directive_global_inline_erb_test.rb +28 -17
  115. data/test/unit/directive_grid_test_notready.rb +38 -0
  116. data/test/unit/directive_helpers_test.rb +39 -0
  117. data/test/unit/directive_hidden_field_test.rb +44 -29
  118. data/test/unit/directive_if_test.rb +10 -7
  119. data/test/unit/directive_image_tag_test.rb +69 -61
  120. data/test/unit/directive_import_render_test.rb +28 -38
  121. data/test/unit/directive_import_test.rb +16 -14
  122. data/test/unit/directive_insert_generated_comment_test.rb +32 -0
  123. data/test/unit/directive_javascript_include_test.rb +40 -43
  124. data/test/unit/directive_link_to_function_test.rb +40 -0
  125. data/test/unit/directive_link_to_if_test.rb +52 -12
  126. data/test/unit/directive_link_to_remote_test.rb +58 -0
  127. data/test/unit/directive_link_to_test.rb +46 -31
  128. data/test/unit/directive_load_path_test.rb +257 -0
  129. data/test/unit/directive_metadata_test.rb +313 -0
  130. data/test/unit/directive_omit_tag_test.rb +73 -21
  131. data/test/unit/directive_password_field_test.rb +44 -38
  132. data/test/unit/directive_registry_test.rb +44 -0
  133. data/test/unit/directive_replace_test.rb +28 -12
  134. data/test/unit/directive_stylesheet_link_test.rb +43 -36
  135. data/test/unit/directive_submit_test.rb +29 -30
  136. data/test/unit/directive_text_area_test.rb +40 -36
  137. data/test/unit/directive_text_field_test.rb +44 -38
  138. data/test/unit/example_directive_child_events_test.rb +41 -0
  139. data/test/unit/example_test.rb +31 -4
  140. data/test/unit/file_mio_test.rb +18 -13
  141. data/test/unit/filter_helpers_test.rb +10 -8
  142. data/test/unit/find_directive_parent_test.rb +174 -0
  143. data/test/unit/keyword_expander_test.rb +4 -2
  144. data/test/unit/mio_test.rb +18 -11
  145. data/test/unit/mtime_string_hash_mio_tree_test.rb +5 -1
  146. data/test/unit/parser_test.rb +41 -29
  147. data/test/unit/pathname_extensions_test.rb +1 -1
  148. data/test/unit/run_parser_test.rb +2 -2
  149. data/test/unit/simplified_directive_base_test.rb +256 -0
  150. data/test/unit/string_hash_mio_test.rb +5 -1
  151. data/test/unit/template_file_watcher_test.rb +2 -2
  152. data/test/unit/template_test.rb +221 -46
  153. metadata +86 -45
  154. data/lib/masterview/directives/testfilter.rb +0 -55
  155. data/lib/masterview/extras/init_rails_reparse_checking.rb +0 -62
@@ -3,50 +3,65 @@
3
3
  require 'test/unit'
4
4
  currentPath = File.dirname(__FILE__)
5
5
  require File.join( currentPath, '../../lib/masterview' )
6
- require File.join( currentPath, '../../lib/masterview/directives/link_to')
6
+ #require File.join( currentPath, '../../lib/masterview/directives/link_to')
7
+ require File.join( currentPath, '../directive_test_helper' )
8
+ DirectiveTestHelpers.load_masterview_directive('link_to')
7
9
 
8
10
  class TestLinkTo < Test::Unit::TestCase
9
- include MasterView::Directives
11
+ include DirectiveTestHelpers
10
12
 
11
- def setup
12
- @directives = MasterView::DirectiveSet.new
13
+ LinkTo = MasterView::Directives::LinkTo # test subject
14
+
15
+ ELEMENT_TAG = 'a'
16
+
17
+ def test_metadata
18
+ assert_equal MasterView::ConfigSettings.namespace_prefix, LinkTo.namespace_prefix
19
+ assert_equal 'link_to', LinkTo.attribute_name
13
20
  end
14
21
 
15
22
  def test_default
16
- tag = MasterView::Tag.new(@directives, 'foo', {}, :normal, nil)
17
- @directives.directives = []
23
+ link_tag = create_template_element ELEMENT_TAG, :content => 'Show Details'
18
24
  attr_value = ":action => 'show', :id => @product"
19
- @directives << Link_to.new(attr_value)
20
- assert_equal nil, @directives.determine_dcs(:stag).render
21
- dcs = @directives.determine_dcs(:etag)
22
- dcs.context = tag.create_context
23
- dcs.context[:tag].content = "bar"
24
- assert_equal "<%= link_to 'bar', :action => 'show', :id => @product %>", dcs.render
25
+ create_directive LinkTo, attr_value
26
+ assert_equal '', render_element_event(:stag)
27
+ expected_content = "<%= link_to( 'Show Details', :action => 'show', :id => @product ) %>"
28
+ assert_equal expected_content, render_element_event(:etag)
25
29
  end
26
30
 
27
31
  def test_junk_name
28
- tag = MasterView::Tag.new(@directives, 'foo', {}, :normal, nil)
29
- @directives.directives = []
30
- attr_value = "'dont use', :action => 'show', :id => @product"
31
- @directives << Link_to.new(attr_value)
32
- assert_equal nil, @directives.determine_dcs(:stag).render
33
- dcs = @directives.determine_dcs(:etag)
34
- dcs.context = tag.create_context
35
- dcs.context[:tag].content = "bar"
36
- assert_equal "<%= link_to 'bar', :action => 'show', :id => @product %>", dcs.render
37
- end
32
+ link_tag = create_template_element ELEMENT_TAG, :content => 'Show Details'
33
+ attr_value = "'do not use (ignored)', :action => 'show', :id => @product"
34
+ create_directive LinkTo, attr_value
35
+ assert_equal '', render_element_event(:stag)
36
+ expected_content = "<%= link_to( 'Show Details', :action => 'show', :id => @product ) %>"
37
+ assert_equal expected_content, render_element_event(:etag)
38
+ end
38
39
 
39
40
  def test_junk_plus
40
- tag = MasterView::Tag.new(@directives, 'foo', {}, :normal, nil)
41
- @directives.directives = []
42
- attr_value = "'dont use', 'nor this', :action => 'show', :id => @product"
43
- @directives << Link_to.new(attr_value)
44
- assert_equal nil, @directives.determine_dcs(:stag).render
45
- dcs = @directives.determine_dcs(:etag)
46
- dcs.context = tag.create_context
47
- dcs.context[:tag].content = "bar"
48
- assert_equal "<%= link_to 'bar', :action => 'show', :id => @product %>", dcs.render
41
+ link_tag = create_template_element ELEMENT_TAG, :content => 'Show Details'
42
+ attr_value = "'do not use (ignored)', :action => 'show', :id => @product"
43
+ create_directive LinkTo, attr_value
44
+ assert_equal '', render_element_event(:stag)
45
+ expected_content = "<%= link_to( 'Show Details', :action => 'show', :id => @product ) %>"
46
+ assert_equal expected_content, render_element_event(:etag)
49
47
  end
50
48
 
49
+ def test_html
50
+ link_tag = create_template_element ELEMENT_TAG, :content => 'Show Details'
51
+ attr_value = ":action => 'show', {:id => @product}, :class => 'red'"
52
+ create_directive LinkTo, attr_value
53
+ assert_equal '', render_element_event(:stag)
54
+ expected_content = "<%= link_to( 'Show Details', :action => 'show', {:id => @product}, :class => 'red' ) %>"
55
+ assert_equal expected_content, render_element_event(:etag)
56
+ end
57
+
58
+ def test_params
59
+ link_tag = create_template_element ELEMENT_TAG, :content => 'Show Details'
60
+ attr_value = ":action => 'show', {:id => @product}, {:class => 'red'}, 'foo', 1, 2"
61
+ create_directive LinkTo, attr_value
62
+ assert_equal '', render_element_event(:stag)
63
+ expected_content = "<%= link_to( 'Show Details', :action => 'show', {:id => @product}, {:class => 'red'}, 'foo', 1, 2 ) %>"
64
+ assert_equal expected_content, render_element_event(:etag)
65
+ end
51
66
 
52
67
  end
@@ -0,0 +1,257 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ currentPath = File.dirname(__FILE__)
5
+ require File.join( currentPath, '../../lib/masterview/exceptions' )
6
+ require File.join( currentPath, '../../lib/masterview/directive_metadata' )
7
+ require File.join( currentPath, '../../lib/masterview/directive_load_path' )
8
+
9
+ DEBUG_TRACE = false #test dev hack
10
+
11
+ class TestDirectiveLoadPath < Test::Unit::TestCase
12
+
13
+ CurrentPath = File.dirname(__FILE__)
14
+ MVTestDir = File.expand_path( File.join(CurrentPath, '..' ) )
15
+ TestFixturesDir = "#{MVTestDir}/fixtures"
16
+ TestDirectivesDir = "#{MVTestDir}/fixtures/directives"
17
+ MVInstallDir = File.expand_path( File.join(CurrentPath, '../../lib/masterview' ) )
18
+ BuiltinDirectivesDir = "#{MVInstallDir}/directives"
19
+
20
+ PathOptionsMasterviewDirectivesAbbrev = { :use_masterview_namespace => true }
21
+ PathOptionsMasterviewDirectivesFull = { :default => {:namespace => 'mv',}, :use_masterview_namespace => true }
22
+
23
+ PathOptionsExtensionsDirectivesAbbrev = { :default => { :namespace => 'mvx'}, }
24
+ PathOptionsExtensionsDirectivesFull = { :default => { :namespace => 'mvx'}, :use_masterview_namespace=>false }
25
+
26
+ # test subjects
27
+ PathEntry = MasterView::DirectiveLoadPath::PathEntry
28
+ Path = MasterView::DirectiveLoadPath::Path
29
+
30
+ SingletonValueClasses = [ Symbol, TrueClass, FalseClass, NilClass ] # we don't care what options deep_copy did on these
31
+
32
+ def check_options_copy(original, copy)
33
+ assert_not_same original, copy, "Options copy not different: original=#{original.object_id}, copy=#{copy.object_id}"
34
+ original.each_pair { | key, originalValue |
35
+ copied_value = copy[key]
36
+ if originalValue.is_a?(Hash)
37
+ assert_not_same originalValue, copied_value, "Options copy not different for key #{key}: original=#{originalValue.object_id}, copy=#{copied_value.object_id}"
38
+ check_options_copy(originalValue, copied_value)
39
+ else
40
+ assert_equal originalValue, copied_value
41
+ if ! SingletonValueClasses.include?( originalValue.class)
42
+ assert_not_same originalValue, copied_value, "Options copy not different for key #{key}: original=#{originalValue.object_id}, copy=#{copied_value.object_id}"
43
+ end
44
+ end
45
+ }
46
+ end
47
+
48
+ def check_path_copy(original, copy)
49
+ assert_not_same original, copy, "Path copy not different: original=#{original.object_id}, copy=#{copy.object_id}"
50
+ original.each_index { | index |
51
+ dpe_original = original[index]
52
+ dpe_copy = copy[index]
53
+ assert_not_same dpe_original, dpe_copy
54
+ assert_equal dpe_original.dir_path, dpe_copy.dir_path, 'path dir should be equal'
55
+ assert_not_same dpe_original.dir_path, dpe_copy.dir_path, 'path dir should not be the same object'
56
+ check_options_copy(dpe_original.options, dpe_copy.options)
57
+ }
58
+
59
+ end
60
+
61
+ def test_path_entry_construction
62
+
63
+ STDOUT.puts "\n------- test_path_entry --------" if DEBUG_TRACE
64
+
65
+ dir_path = BuiltinDirectivesDir
66
+ dpe = PathEntry.new(dir_path)
67
+ STDOUT.puts "...#{dpe.inspect}" if DEBUG_TRACE
68
+ assert_equal BuiltinDirectivesDir, dpe.dir_path
69
+ assert dpe.options.empty?, 'Default is empty options'
70
+ assert ! dpe.use_masterview_namespace, 'Only builtin MV directives use mv: namespace'
71
+ assert dpe.use_extensions_namespace, 'Addond MV directives use mvx: namespace by default'
72
+ assert dpe.metadata_defaults.empty?, 'Default is empty metadata defaults'
73
+
74
+ options = PathOptionsMasterviewDirectivesAbbrev
75
+ dpe = PathEntry.new(dir_path, options)
76
+ STDOUT.puts "...#{dpe.inspect}" if DEBUG_TRACE
77
+ assert_equal options.size, dpe.options.size
78
+ check_options_copy( options, dpe.options ) # 'PathEntry should always keep its own copy of options'
79
+ assert dpe.use_masterview_namespace, 'Builtin MV directives use mv: namespace'
80
+
81
+ dir_path = 'foo'
82
+ options = {:default=>{}, }
83
+ dpe = PathEntry.new(dir_path, options)
84
+ STDOUT.puts "...#{dpe.inspect}" if DEBUG_TRACE
85
+ assert_equal dir_path, dpe.dir_path
86
+ assert_equal options.size, dpe.options.size
87
+ check_options_copy( options, dpe.options ) # 'PathEntry should always keep its own copy of options'
88
+ assert ! dpe.use_masterview_namespace, 'Only builtin MV directives use mv: namespace'
89
+ assert dpe.use_extensions_namespace, 'Addond MV directives use mvx: namespace by default'
90
+ assert dpe.metadata_defaults.empty?, 'Default is empty metadata defaults'
91
+
92
+ dir_path = TestDirectivesDir
93
+ options = {:default=>{ :namespace => 'mvx'},:use_masterview_namespace=>false }
94
+ dpe = PathEntry.new(dir_path, options)
95
+ STDOUT.puts "...#{dpe.inspect}" if DEBUG_TRACE
96
+ assert_equal dir_path, dpe.dir_path
97
+ assert_equal options.size, dpe.options.size
98
+ check_options_copy( options, dpe.options ) # 'PathEntry should always keep its own copy of options'
99
+ assert ! dpe.use_masterview_namespace, 'Only builtin MV directives use mv: namespace'
100
+ assert dpe.use_extensions_namespace, 'Addon MV directives use mvx: namespace by default'
101
+ assert_equal 1, dpe.metadata_defaults.size, "Unexpected metadata defaults: #{dpe.options.inspect}"
102
+
103
+ end
104
+
105
+ def test_path_entry_validation
106
+
107
+ STDOUT.puts "\n------- test_path_entry_validation --------" if DEBUG_TRACE
108
+
109
+ dir_path = BuiltinDirectivesDir
110
+ dpe = PathEntry.new(dir_path)
111
+ dpe.validate
112
+
113
+ dir_path = 'foo'
114
+ dpe = PathEntry.new(dir_path)
115
+
116
+ #assert_raise( MasterView::InvalidPathError ) { dpe.validate } #, 'Nonexistent path should cause error'
117
+ assert_raise( MasterView::InvalidDirectivePathError ) { dpe.validate } #, 'Nonexistent path should cause error'
118
+
119
+ begin
120
+ dpe.validate
121
+ rescue MasterView::InvalidDirectivePathError => ex
122
+ assert_same dpe.dir_path, ex.path # MasterView::InvalidPathError info
123
+ assert_same dpe, ex.path_entry # MasterView::InvalidDirectivePathError info
124
+ assert_not_nil ex.message
125
+ end
126
+
127
+ end
128
+
129
+ def test_path_entry_copy
130
+
131
+ STDOUT.puts "\n------- test_path_entry_copy --------" if DEBUG_TRACE
132
+
133
+ dir_path = 'foo'
134
+ options = {
135
+ :default => { :namespace => 'mvx', :description => 'TEST'},
136
+ :use_masterview_namespace=>false }
137
+
138
+ dpe = PathEntry.new(dir_path, options)
139
+ copy = dpe.deep_copy
140
+ assert_not_same dpe, copy
141
+ check_options_copy( options, dpe.options ) # 'PathEntry should always keep its own copy of options'
142
+ check_options_copy( options, copy.options ) # not what we started with
143
+ check_options_copy( dpe.options, copy.options ) # and not the copied guy
144
+
145
+ #test the test checker itself - verify that the checker detects non-copies
146
+ assert_raise( Test::Unit::AssertionFailedError ) { check_options_copy( options, options) }
147
+ # verify that un-doing the nested copy gets caught
148
+ copy.options[:default] = dpe.options[:default]
149
+ assert_raise( Test::Unit::AssertionFailedError ) { check_options_copy( copy.options, dpe.options ) }
150
+
151
+ end
152
+
153
+ def test_path_ops
154
+
155
+ STDOUT.puts "\n------- test_path_ops --------" if DEBUG_TRACE
156
+
157
+ path = Path.new
158
+ dir_paths = []
159
+
160
+ assert path.empty?
161
+ assert_equal 0, path.size
162
+
163
+ # verify that we can append a PathEntry
164
+ dir_path1 = 'foo'
165
+ dir_paths << dir_path1
166
+ dpe1 = PathEntry.new(dir_path1)
167
+ path << dpe1
168
+ assert_equal dir_paths.size, path.size
169
+ assert_same dpe1, path[0]
170
+
171
+ # verify that we can append a string
172
+ dir_path2 = 'bar'
173
+ dir_paths << dir_path2
174
+ path << dir_path2
175
+ assert_equal dir_paths.size, path.size
176
+ assert_equal dir_path2, path[-1].dir_path
177
+
178
+ # verify obscure compat support that probably never left Deb's machine
179
+ dir_path3 = 'wingding'
180
+ options3 = { :default => { :namespace => 'test' } }
181
+ dir_paths << dir_path3
182
+ path << [dir_path3, options3]
183
+ assert_equal dir_paths.size, path.size
184
+ assert_equal dir_path3, path[-1].dir_path
185
+ assert_equal options3, path[-1].options
186
+ assert_not_same options3, path[-1].options
187
+
188
+ # verify enumerating
189
+ count = 0
190
+ path.each { | dpe |
191
+ assert dir_paths.include?( dpe.dir_path )
192
+ dpe.normalize # set this up for the following test
193
+ count += 1
194
+ }
195
+ assert_equal dir_paths.size, count
196
+
197
+ # we did normalization on the entries in the preceding
198
+ assert path.include?(path[-1].dir_path), 'Expanded path should be found'
199
+ assert path.include?(dir_path3), 'Original rel path should also be matched'
200
+
201
+ # verify (deep) copy
202
+ path_copy = path.copy
203
+ check_path_copy(path, path_copy)
204
+
205
+ end
206
+
207
+ def test_path_registry
208
+
209
+ STDOUT.puts "\n------- test_path_registry --------" if DEBUG_TRACE
210
+
211
+ # normal sequence is for client app to append entries, then MV::Initializer cleans up
212
+ path = Path.new
213
+ path << PathEntry.new(BuiltinDirectivesDir, PathOptionsMasterviewDirectivesAbbrev)
214
+ path[-1].validate # this is a legit entry
215
+ path << PathEntry.new('bar')
216
+ assert_raise( MasterView::InvalidDirectivePathError ) { path[1].validate } #, 'Nonexistent path should cause error'
217
+
218
+ # oh, just give up - this works standalone, but screws up the system state when we run entire suite
219
+ if true
220
+ return
221
+ end
222
+
223
+ # Masterview::Initializer cleans up the path, validates and normalizes, and registers
224
+ # But if we run this during test suite execution we don't know the state of the system, so be careful here
225
+ real_load_path_values = MasterView::DirectiveLoadPath.path_registry
226
+ if ! real_load_path_values.empty?
227
+ assert real_load_path_values.include?(:default) # the default_load_path specs
228
+ assert real_load_path_values.include?(:current) # the current load path
229
+ end
230
+ STDOUT.puts "...DirectiveLoadPath.default_path_specs=#{MasterView::DirectiveLoadPath.default_path_specs.inspect}" if DEBUG_TRACE
231
+ #assert_nil MasterView::DirectiveLoadPath.default_path_specs, 'this is what we'd expect at initial load time'
232
+ STDOUT.puts "...DirectiveLoadPath.current=#{MasterView::DirectiveLoadPath.current.inspect}" if DEBUG_TRACE
233
+ #assert_nil MasterView::DirectiveLoadPath.current
234
+ begin
235
+
236
+ MasterView::DirectiveLoadPath.default_path_specs = path
237
+ STDOUT.puts "...DirectiveLoadPath.default_path_specs=#{MasterView::DirectiveLoadPath.default_path_specs.object_id}" if DEBUG_TRACE
238
+ STDOUT.puts "...DirectiveLoadPath.current=#{MasterView::DirectiveLoadPath.current.object_id}" if DEBUG_TRACE
239
+
240
+ STDOUT.puts "...DirectiveLoadPath.default_path_specs=#{MasterView::DirectiveLoadPath.default_path_specs.inspect}" if DEBUG_TRACE
241
+ assert_not_nil MasterView::DirectiveLoadPath.default_path_specs
242
+ assert_not_same path, MasterView::DirectiveLoadPath.default_path_specs
243
+ STDOUT.puts "...DirectiveLoadPath.current=#{MasterView::DirectiveLoadPath.current.inspect}" if DEBUG_TRACE
244
+ assert_not_nil MasterView::DirectiveLoadPath.current
245
+ assert_not_same path, MasterView::DirectiveLoadPath.current
246
+ assert_not_same MasterView::DirectiveLoadPath.current, MasterView::DirectiveLoadPath.default_path_specs
247
+
248
+ ensure
249
+ # make sure we put the system back into whatever state it was in
250
+ real_load_path_values.each_pair { | key, real_value |
251
+ MasterView::DirectiveLoadPath.path_registry[key] = real_value
252
+ }
253
+ end
254
+
255
+ end
256
+
257
+ end
@@ -0,0 +1,313 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'test/unit'
4
+ currentPath = File.dirname(__FILE__)
5
+ require File.join( currentPath, '../../lib/masterview' )
6
+
7
+ DEBUG_TRACE = false
8
+
9
+ # test on correctness of managing separate metadata_values map for each class
10
+ MetadataValuesIdentityMap = {} # directive_class => directive_class.metadata_values.object_id
11
+ def record_metadata_values_var(directive_class)
12
+ MetadataValuesIdentityMap[directive_class] = directive_class.metadata_values.object_id
13
+ end
14
+
15
+ module MasterView
16
+ module DirectiveMetadataTests
17
+
18
+ # directive implementation with simple class name
19
+ class Test1
20
+ include MasterView::DirectiveMetadata
21
+ end
22
+ record_metadata_values_var(Test1)
23
+
24
+ if DEBUG_TRACE ### DEBUG ###
25
+ STDOUT.puts "\n------- Directive test fixture class Test1 -------"
26
+ STDOUT.puts "Instance variables: #{Test1.instance_variables}"
27
+ STDOUT.puts "Instance methods: #{Test1.instance_methods(include_super=false).inspect}"
28
+ STDOUT.puts "Class variables: #{Test1.class_variables}"
29
+ #STDOUT.puts "Class methods: #{Test1.class.instance_methods(include_super=false).inspect}"
30
+ foo = Test1.new
31
+ STDOUT.puts "foo=#{foo.inspect}"
32
+ STDOUT.puts "foo.instance_variables=#{foo.instance_variables.inspect}"
33
+ STDOUT.puts "foo.class.class_variables=#{foo.class.class_variables.inspect}"
34
+ STDOUT.puts "Test1.metadata_values=#{Test1.metadata_values.inspect} (id=#{Test1.metadata_values.object_id})"
35
+ class Test1
36
+ STDOUT.puts "Test1 @@metadata_values=#{class_variable_get(:@@metadata_values).inspect} (id=#{class_variable_get(:@@metadata_values).object_id})"
37
+ end
38
+ STDOUT.puts "----------------------------------\n"
39
+ end ### END DEBUG ###
40
+
41
+ # directive implementation with complex class name
42
+ class TestFoo
43
+ include MasterView::DirectiveMetadata
44
+ end
45
+ record_metadata_values_var(TestFoo)
46
+
47
+ if DEBUG_TRACE ### DEBUG ###
48
+ STDOUT.puts "\n------- Directive test fixture class TestFoo -------"
49
+ STDOUT.puts "Instance variables: #{TestFoo.instance_variables}"
50
+ STDOUT.puts "Instance methods: #{TestFoo.instance_methods(include_super=false).inspect}"
51
+ STDOUT.puts "Class variables: #{TestFoo.class_variables}"
52
+ #STDOUT.puts "Class methods: #{TestFoo.class.instance_methods(include_super=false).inspect}"
53
+ foo = TestFoo.new
54
+ STDOUT.puts "foo=#{foo.inspect}"
55
+ STDOUT.puts "foo.instance_variables=#{foo.instance_variables.inspect}"
56
+ STDOUT.puts "foo.class.class_variables=#{foo.class.class_variables.inspect}"
57
+ STDOUT.puts "TestFoo.metadata_values=#{TestFoo.metadata_values.inspect} (id=#{TestFoo.metadata_values.object_id})"
58
+ class TestFoo
59
+ STDOUT.puts "TestFoo @@metadata_values=#{class_variable_get(:@@metadata_values).inspect} (id=#{class_variable_get(:@@metadata_values).object_id})"
60
+ end
61
+ STDOUT.puts "----------------------------------\n"
62
+ end ### END DEBUG ###
63
+
64
+ class Test3
65
+ include MasterView::DirectiveMetadata
66
+ end
67
+ record_metadata_values_var(Test3)
68
+
69
+ class Test4
70
+ include MasterView::DirectiveMetadata
71
+ STDOUT.puts "\n####LOADING #{self.name} DIRECTIVE TEST FIXTURE" if DEBUG_TRACE
72
+ metadata :attribute_name => 'test4zz', :namespace => 'mvzz',
73
+ :description => 'test directive',
74
+ :priority => MasterView::DirectiveMetadata::DirectivePriorities::High
75
+ STDOUT.puts "...metadata_values: #{metadata_values.inspect}\n" if DEBUG_TRACE
76
+ end
77
+ record_metadata_values_var(Test4)
78
+
79
+ # test setting priority in various forms
80
+ class Test5
81
+ include MasterView::DirectiveMetadata
82
+ end
83
+ record_metadata_values_var(Test5)
84
+
85
+ end
86
+ end
87
+
88
+ class TestDirectiveMetadata < Test::Unit::TestCase
89
+
90
+ include MasterView::DirectiveMetadataTests # test fixtures
91
+
92
+ DirectiveMetadata = MasterView::DirectiveMetadata #test subject
93
+ DirectivePriorities = MasterView::DirectiveMetadata::DirectivePriorities
94
+
95
+ DefaultDirectivePriority = DirectivePriorities::Default
96
+
97
+ # we expect our test cases to belong in the mvx namespace
98
+ DefaultNamespacePrefix = MasterView::ConfigSettings.namespace_prefix_extensions
99
+
100
+ def check_standard_metadata(directive_class, directive, expected_ns_prefix=DefaultNamespacePrefix)
101
+ expected_ns = expected_ns_prefix[0...-1]
102
+ expected_attr_name = directive_class.default_directive_name
103
+ expected_qname = "#{expected_ns}:#{expected_attr_name}"
104
+ assert_equal expected_ns_prefix, directive_class.default_namespace_prefix, "Bad #{directive_class.name}.default_namespace_prefix"
105
+ [ directive_class, directive ].each { | testSubject |
106
+ STDOUT.puts "##CHECKING #{testSubject}" if DEBUG_TRACE
107
+ assert_equal expected_attr_name, testSubject.attribute_name, "#{testSubject.inspect} metadata problem (attr name)"
108
+ assert_equal expected_ns_prefix, testSubject.namespace_prefix, "#{testSubject.inspect} metadata problem (ns_prefix)"
109
+ assert_equal expected_ns, testSubject.namespace_name, "#{testSubject.inspect} metadata problem (ns_name)"
110
+ assert_equal expected_qname, testSubject.attribute_qname, "#{testSubject.inspect} metadata problem (attr qname)"
111
+ assert_equal "#{testSubject.namespace}:#{testSubject.attribute_name}", testSubject.attribute_qname, "#{testSubject.inspect} metadata problem (attr qname)"
112
+ assert_equal "#{testSubject.namespace_prefix}#{testSubject.attribute_name}", testSubject.attribute_qname, "#{testSubject.inspect} metadata problem (attr qname)"
113
+ assert_equal DefaultDirectivePriority, testSubject.priority, "#{testSubject.inspect} metadata problem (priority)"
114
+ }
115
+ assert_equal DirectivePriorities::Medium, DirectivePriorities::Default
116
+ end
117
+
118
+ def check_metadata_values_var(directive_class)
119
+ expected_obj_id = MetadataValuesIdentityMap[directive_class]
120
+ actual_obj_id = directive_class.metadata_values.object_id
121
+ msg = "#{directive_class.name}.metadata_values=#{directive_class.metadata_values.inspect} (id=#{actual_obj_id})"
122
+ STDOUT.puts msg if DEBUG_TRACE
123
+ assert_equal expected_obj_id, actual_obj_id, msg
124
+ end
125
+
126
+ def check_required_metadata_props_defined(directive_class)
127
+ expected_props = Set.new.merge DirectiveMetadata::HARDENED_PROPERTY_NAMES
128
+ actual_props = Set.new.merge directive_class.metadata_values.keys
129
+ assert_equal expected_props, actual_props
130
+ end
131
+
132
+ def test_directive_test1
133
+
134
+ directive_class = Test1
135
+ directive = directive_class.new
136
+
137
+ assert_equal 'test1', directive_class.default_directive_name
138
+ check_metadata_values_var(directive_class)
139
+
140
+ assert directive_class.metadata_values.empty?
141
+ check_standard_metadata(directive_class, directive)
142
+
143
+ directive_class.harden_metadata
144
+ check_required_metadata_props_defined(directive_class)
145
+ check_standard_metadata(directive_class, directive)
146
+
147
+ end
148
+
149
+ def test_directive_test_foo
150
+
151
+ directive_class = TestFoo
152
+ directive = directive_class.new
153
+
154
+ assert_equal 'test_foo', directive_class.default_directive_name, 'observe CamelCase -> snake_case'
155
+ check_metadata_values_var(directive_class)
156
+
157
+ assert directive_class.metadata_values.empty?
158
+ check_standard_metadata(directive_class, directive)
159
+
160
+ directive_class.harden_metadata
161
+ check_required_metadata_props_defined(directive_class)
162
+ check_standard_metadata(directive_class, directive)
163
+
164
+ end
165
+
166
+ def test_set_explicit_metadata
167
+
168
+ directive_class = Test3
169
+ directive = directive_class.new
170
+
171
+ assert_equal 'test3', directive_class.default_directive_name
172
+ check_metadata_values_var(directive_class)
173
+
174
+ assert directive_class.metadata_values.empty?
175
+ check_standard_metadata(directive_class, directive)
176
+
177
+ attr_name = 'test3xx'
178
+ default_namespace_prefix = DefaultNamespacePrefix
179
+ md_specs = "metadata :attribute_name => '#{attr_name}'"
180
+ directive_class.class_eval md_specs
181
+ check_metadata_values_var(directive_class)
182
+ assert_equal attr_name, directive_class.attribute_name
183
+ assert attr_name != directive_class.default_directive_name
184
+ assert_equal directive_class.attribute_qname, "#{default_namespace_prefix}#{attr_name}"
185
+
186
+ ns_name = 'mvx'
187
+ md_specs = "metadata :namespace => '#{ns_name}'"
188
+ directive_class.class_eval md_specs
189
+ check_metadata_values_var(directive_class)
190
+ assert_equal ns_name, directive_class.namespace_name
191
+ assert_equal "#{ns_name}:", directive_class.namespace_prefix, 'automatically synched with ns change'
192
+ assert_equal "#{ns_name}:#{directive_class.default_directive_name}", directive_class.attribute_qname
193
+
194
+ attr_name = 'test3yy'
195
+ ns_name = 'mvy'
196
+ md_specs = "metadata :attribute_name => '#{attr_name}', :namespace => '#{ns_name}'"
197
+ directive_class.class_eval md_specs
198
+ check_metadata_values_var(directive_class)
199
+ assert_equal attr_name, directive_class.attribute_name
200
+ assert attr_name != directive_class.default_directive_name
201
+ assert_equal ns_name, directive_class.namespace_name
202
+ assert_equal "#{ns_name}:", directive_class.namespace_prefix, 'automatically synched with ns change'
203
+ assert_equal "#{ns_name}:#{attr_name}", directive_class.attribute_qname
204
+
205
+ end
206
+
207
+ def test_declared_metadata
208
+
209
+ directive_class = Test4
210
+ directive = directive_class.new
211
+
212
+ attr_name = 'test4zz'
213
+ ns_name = 'mvzz'
214
+
215
+ assert_equal 'test4', directive_class.default_directive_name
216
+ check_metadata_values_var(directive_class)
217
+
218
+ assert ! directive_class.metadata_values.empty?
219
+ assert_equal attr_name, directive_class.attribute_name
220
+ assert attr_name != directive_class.default_directive_name
221
+ assert_equal ns_name, directive_class.namespace_name
222
+ assert_equal "#{ns_name}:", directive_class.namespace_prefix, 'automatically synched with ns change'
223
+ assert_equal "#{ns_name}:#{attr_name}", directive_class.attribute_qname
224
+
225
+ assert_not_nil directive_class.metadata_values[:description]
226
+ assert DefaultDirectivePriority != directive_class.priority
227
+ assert_equal DirectivePriorities::High, directive_class.priority
228
+
229
+ end
230
+
231
+ def test_validation_checking
232
+
233
+ assert_nothing_raised { DirectiveMetadata.validate_xml_identifier 'foo' }
234
+ assert_nothing_raised { DirectiveMetadata.validate_xml_identifier 'foo-bar' }
235
+ assert_nothing_raised { DirectiveMetadata.validate_xml_identifier 'foo_bar' }
236
+ assert_nothing_raised { DirectiveMetadata.validate_xml_identifier 'foo99' }
237
+ assert_nothing_raised { DirectiveMetadata.validate_xml_identifier 'Foo' }
238
+ assert_nothing_raised { DirectiveMetadata.validate_xml_identifier 'FooBar' }
239
+
240
+ ###TODO: need to install checking for illegal ids per xml name syntax
241
+ #assert_raise( ArgumentError ) { DirectiveMetadata.validate_xml_identifier 'foo bar' }
242
+ assert_nothing_raised { DirectiveMetadata.validate_xml_identifier 'foo bar' }
243
+
244
+ end
245
+
246
+ def test_consistency_checking
247
+
248
+ md_props = { :namespace => 'foo' }
249
+ DirectiveMetadata.validate_metadata_props! md_props
250
+ assert_equal 2, md_props.size, ':namespace_prefix added'
251
+ assert_equal 'foo:', md_props[:namespace_prefix]
252
+
253
+ md_props = { :namespace_name => 'foo' } # synonym, use should be discouraged
254
+ DirectiveMetadata.validate_metadata_props! md_props
255
+ assert_equal 2, md_props.size, ':namespace_prefix added'
256
+ assert_equal 'foo:', md_props[:namespace_prefix]
257
+
258
+ md_props = { :namespace_prefix => 'bar:' }
259
+ DirectiveMetadata.validate_metadata_props! md_props
260
+ assert_equal 2, md_props.size, ':namespace added'
261
+ assert_equal 'bar', md_props[:namespace]
262
+ assert_equal 'bar:', md_props[:namespace_prefix]
263
+
264
+ end
265
+
266
+ def test_priority_services
267
+ DirectiveMetadata::PriorityNames.each{ | level_name |
268
+ priority = DirectivePriorities.const_get(level_name)
269
+ assert_equal level_name, DirectiveMetadata.get_priority_name(priority)
270
+ }
271
+ end
272
+
273
+ def test_priority
274
+
275
+ directive_class = Test5
276
+
277
+ check_metadata_values_var(directive_class)
278
+
279
+ assert_equal DirectivePriorities::Medium, DirectivePriorities::Default
280
+
281
+ assert_equal DefaultDirectivePriority, directive_class.priority
282
+
283
+ directive_class.metadata :priority => DirectivePriorities::Lowest
284
+ assert_equal DirectivePriorities::Lowest, directive_class.priority
285
+
286
+ directive_class.metadata :priority => 'VeryLow'
287
+ assert_equal DirectivePriorities::VeryLow, directive_class.priority
288
+
289
+ directive_class.metadata :priority => :VeryHigh
290
+ assert_equal DirectivePriorities::VeryHigh, directive_class.priority
291
+
292
+ directive_class.metadata :priority => 'Highest'
293
+ assert_equal DirectivePriorities::Highest, directive_class.priority
294
+
295
+ # check the synonyms
296
+ [ 'Default', 'default', :default ].each { |level_name|
297
+ # first set the value to a known state
298
+ directive_class.metadata :priority => 'Highest'
299
+ assert_equal DirectivePriorities::Highest, directive_class.priority
300
+ # now verify that all the synonyms for default priority level work
301
+ directive_class.metadata :priority => level_name
302
+ assert_equal DirectivePriorities::Default, directive_class.priority
303
+ }
304
+
305
+ # error conditions
306
+ assert_raise( ArgumentError ) { directive_class.metadata :priority => -1 }
307
+ assert_raise( ArgumentError ) { directive_class.metadata :priority => DirectivePriorities::Lowest + 1 }
308
+ assert_raise( ArgumentError ) { directive_class.metadata :priority => 'nonesuch' }
309
+ assert_raise( ArgumentError ) { directive_class.metadata :priority => nil }
310
+
311
+ end
312
+
313
+ end