expressir 1.2.5-x64-mingw-ucrt

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 (142) hide show
  1. checksums.yaml +7 -0
  2. data/.cross_rubies +15 -0
  3. data/.github/workflows/rake.yml +300 -0
  4. data/.github/workflows/release.yml +120 -0
  5. data/.gitignore +23 -0
  6. data/.gitmodules +6 -0
  7. data/.hound.yml +3 -0
  8. data/.rspec +2 -0
  9. data/.rubocop.yml +17 -0
  10. data/.yardopts +11 -0
  11. data/Gemfile +4 -0
  12. data/README.adoc +147 -0
  13. data/Rakefile +17 -0
  14. data/bin/console +11 -0
  15. data/bin/rspec +29 -0
  16. data/bin/setup +8 -0
  17. data/docs/development.md +90 -0
  18. data/exe/expressir +22 -0
  19. data/exe/format +18 -0
  20. data/exe/format-test +81 -0
  21. data/exe/generate-parser +51 -0
  22. data/expressir.gemspec +48 -0
  23. data/lib/expressir/cli/ui.rb +36 -0
  24. data/lib/expressir/cli.rb +21 -0
  25. data/lib/expressir/config.rb +23 -0
  26. data/lib/expressir/express/3.1/express_parser.so +0 -0
  27. data/lib/expressir/express/cache.rb +51 -0
  28. data/lib/expressir/express/formatter.rb +1608 -0
  29. data/lib/expressir/express/hyperlink_formatter.rb +36 -0
  30. data/lib/expressir/express/model_visitor.rb +24 -0
  31. data/lib/expressir/express/parser.rb +84 -0
  32. data/lib/expressir/express/resolve_references_model_visitor.rb +31 -0
  33. data/lib/expressir/express/schema_head_formatter.rb +23 -0
  34. data/lib/expressir/express/visitor.rb +2578 -0
  35. data/lib/expressir/model/cache.rb +17 -0
  36. data/lib/expressir/model/data_type.rb +9 -0
  37. data/lib/expressir/model/data_types/aggregate.rb +31 -0
  38. data/lib/expressir/model/data_types/array.rb +31 -0
  39. data/lib/expressir/model/data_types/bag.rb +25 -0
  40. data/lib/expressir/model/data_types/binary.rb +22 -0
  41. data/lib/expressir/model/data_types/boolean.rb +10 -0
  42. data/lib/expressir/model/data_types/enumeration.rb +25 -0
  43. data/lib/expressir/model/data_types/enumeration_item.rb +26 -0
  44. data/lib/expressir/model/data_types/generic.rb +26 -0
  45. data/lib/expressir/model/data_types/generic_entity.rb +26 -0
  46. data/lib/expressir/model/data_types/integer.rb +10 -0
  47. data/lib/expressir/model/data_types/list.rb +28 -0
  48. data/lib/expressir/model/data_types/logical.rb +10 -0
  49. data/lib/expressir/model/data_types/number.rb +10 -0
  50. data/lib/expressir/model/data_types/real.rb +19 -0
  51. data/lib/expressir/model/data_types/select.rb +28 -0
  52. data/lib/expressir/model/data_types/set.rb +25 -0
  53. data/lib/expressir/model/data_types/string.rb +22 -0
  54. data/lib/expressir/model/declaration.rb +9 -0
  55. data/lib/expressir/model/declarations/attribute.rb +47 -0
  56. data/lib/expressir/model/declarations/constant.rb +34 -0
  57. data/lib/expressir/model/declarations/entity.rb +53 -0
  58. data/lib/expressir/model/declarations/function.rb +67 -0
  59. data/lib/expressir/model/declarations/interface.rb +28 -0
  60. data/lib/expressir/model/declarations/interface_item.rb +23 -0
  61. data/lib/expressir/model/declarations/interfaced_item.rb +37 -0
  62. data/lib/expressir/model/declarations/parameter.rb +34 -0
  63. data/lib/expressir/model/declarations/procedure.rb +64 -0
  64. data/lib/expressir/model/declarations/remark_item.rb +21 -0
  65. data/lib/expressir/model/declarations/rule.rb +71 -0
  66. data/lib/expressir/model/declarations/schema.rb +117 -0
  67. data/lib/expressir/model/declarations/schema_version.rb +22 -0
  68. data/lib/expressir/model/declarations/schema_version_item.rb +22 -0
  69. data/lib/expressir/model/declarations/subtype_constraint.rb +40 -0
  70. data/lib/expressir/model/declarations/type.rb +45 -0
  71. data/lib/expressir/model/declarations/unique_rule.rb +31 -0
  72. data/lib/expressir/model/declarations/variable.rb +34 -0
  73. data/lib/expressir/model/declarations/where_rule.rb +31 -0
  74. data/lib/expressir/model/expression.rb +9 -0
  75. data/lib/expressir/model/expressions/aggregate_initializer.rb +19 -0
  76. data/lib/expressir/model/expressions/aggregate_initializer_item.rb +22 -0
  77. data/lib/expressir/model/expressions/binary_expression.rb +53 -0
  78. data/lib/expressir/model/expressions/entity_constructor.rb +22 -0
  79. data/lib/expressir/model/expressions/function_call.rb +22 -0
  80. data/lib/expressir/model/expressions/interval.rb +34 -0
  81. data/lib/expressir/model/expressions/query_expression.rb +35 -0
  82. data/lib/expressir/model/expressions/unary_expression.rb +27 -0
  83. data/lib/expressir/model/identifier.rb +34 -0
  84. data/lib/expressir/model/literal.rb +9 -0
  85. data/lib/expressir/model/literals/binary.rb +19 -0
  86. data/lib/expressir/model/literals/integer.rb +19 -0
  87. data/lib/expressir/model/literals/logical.rb +23 -0
  88. data/lib/expressir/model/literals/real.rb +19 -0
  89. data/lib/expressir/model/literals/string.rb +22 -0
  90. data/lib/expressir/model/model_element.rb +208 -0
  91. data/lib/expressir/model/reference.rb +9 -0
  92. data/lib/expressir/model/references/attribute_reference.rb +22 -0
  93. data/lib/expressir/model/references/group_reference.rb +22 -0
  94. data/lib/expressir/model/references/index_reference.rb +27 -0
  95. data/lib/expressir/model/references/simple_reference.rb +24 -0
  96. data/lib/expressir/model/repository.rb +23 -0
  97. data/lib/expressir/model/statement.rb +9 -0
  98. data/lib/expressir/model/statements/alias.rb +35 -0
  99. data/lib/expressir/model/statements/assignment.rb +22 -0
  100. data/lib/expressir/model/statements/case.rb +25 -0
  101. data/lib/expressir/model/statements/case_action.rb +22 -0
  102. data/lib/expressir/model/statements/compound.rb +19 -0
  103. data/lib/expressir/model/statements/escape.rb +10 -0
  104. data/lib/expressir/model/statements/if.rb +25 -0
  105. data/lib/expressir/model/statements/null.rb +10 -0
  106. data/lib/expressir/model/statements/procedure_call.rb +22 -0
  107. data/lib/expressir/model/statements/repeat.rb +47 -0
  108. data/lib/expressir/model/statements/return.rb +19 -0
  109. data/lib/expressir/model/statements/skip.rb +10 -0
  110. data/lib/expressir/model/supertype_expression.rb +9 -0
  111. data/lib/expressir/model/supertype_expressions/binary_supertype_expression.rb +29 -0
  112. data/lib/expressir/model/supertype_expressions/oneof_supertype_expression.rb +19 -0
  113. data/lib/expressir/model.rb +79 -0
  114. data/lib/expressir/version.rb +3 -0
  115. data/lib/expressir.rb +20 -0
  116. data/rakelib/antlr4-native.rake +63 -0
  117. data/rakelib/cross-ruby.rake +367 -0
  118. data/spec/acceptance/version_spec.rb +17 -0
  119. data/spec/expressir/express/cache_spec.rb +67 -0
  120. data/spec/expressir/express/formatter_spec.rb +135 -0
  121. data/spec/expressir/express/parser_spec.rb +104 -0
  122. data/spec/expressir/model/model_element_spec.rb +274 -0
  123. data/spec/spec_helper.rb +17 -0
  124. data/spec/support/console_helper.rb +29 -0
  125. data/spec/syntax/multiple.exp +23 -0
  126. data/spec/syntax/multiple.yaml +198 -0
  127. data/spec/syntax/multiple_formatted.exp +71 -0
  128. data/spec/syntax/multiple_hyperlink_formatted.exp +71 -0
  129. data/spec/syntax/multiple_schema_head_hyperlink_formatted.exp +13 -0
  130. data/spec/syntax/remark.exp +191 -0
  131. data/spec/syntax/remark.yaml +466 -0
  132. data/spec/syntax/remark_formatted.exp +227 -0
  133. data/spec/syntax/single.exp +4 -0
  134. data/spec/syntax/single.yaml +18 -0
  135. data/spec/syntax/single_formatted.exp +10 -0
  136. data/spec/syntax/single_formatted.yaml +36 -0
  137. data/spec/syntax/syntax.exp +333 -0
  138. data/spec/syntax/syntax.yaml +3509 -0
  139. data/spec/syntax/syntax_formatted.exp +902 -0
  140. data/spec/syntax/syntax_hyperlink_formatted.exp +902 -0
  141. data/spec/syntax/syntax_schema_head_formatted.exp +18 -0
  142. metadata +387 -0
@@ -0,0 +1,367 @@
1
+ require "rbconfig"
2
+ require "shellwords"
3
+
4
+ WINDOWS_PLATFORM_REGEX = /mingw|mswin/.freeze
5
+ LINUX_PLATFORM_REGEX = /linux/.freeze
6
+ DARWIN_PLATFORM_REGEX = /darwin/.freeze
7
+ GLIBC_MIN_VERSION = "2.17".freeze
8
+
9
+ CrossRuby = Struct.new(:version, :host) do
10
+ def dll_staging_path
11
+ "tmp/#{platform}/stage/lib/expressir/express/#{minor_ver}/express_parser.#{dll_ext}"
12
+ end
13
+
14
+ def windows?
15
+ !!(platform =~ WINDOWS_PLATFORM_REGEX)
16
+ end
17
+
18
+ def linux?
19
+ !!(platform =~ LINUX_PLATFORM_REGEX)
20
+ end
21
+
22
+ def darwin?
23
+ !!(platform =~ DARWIN_PLATFORM_REGEX)
24
+ end
25
+
26
+ def ver
27
+ @ver ||= version[/\A[^-]+/]
28
+ end
29
+
30
+ def minor_ver
31
+ @minor_ver ||= ver[/\A\d\.\d(?=\.)/]
32
+ end
33
+
34
+ def minor_ver_digi
35
+ @minor_ver_digi = minor_ver.delete(".").to_i
36
+ end
37
+
38
+ def ucrt?
39
+ minor_ver_digi >= 31
40
+ end
41
+
42
+ def api_ver_suffix
43
+ case minor_ver
44
+ when nil
45
+ raise "CrossRuby.api_ver_suffix: unsupported version: #{ver}"
46
+ else
47
+ minor_ver.delete(".") << "0"
48
+ end
49
+ end
50
+
51
+ # rubocop:disable Metrics/MethodLength
52
+ # rubocop:disable Metrics/CyclomaticComplexity
53
+ def platform
54
+ @platform ||=
55
+ case host
56
+ when /\Ax86_64.*mingw32/
57
+ if ucrt?
58
+ "x64-mingw-ucrt"
59
+ else
60
+ "x64-mingw32"
61
+ end
62
+ when /\Ax86_64.*linux/
63
+ "x86_64-linux"
64
+ when /\A(arm64|aarch64).*linux/
65
+ "aarch64-linux"
66
+ when /\Ax86_64-darwin/
67
+ "x86_64-darwin"
68
+ when /\Aarm64-darwin/
69
+ "arm64-darwin"
70
+ else
71
+ raise "CrossRuby.platform: unsupported host: #{host}"
72
+ end
73
+ end
74
+
75
+ def tool(name)
76
+ (@binutils_prefix ||=
77
+ case platform
78
+ when /x64-mingw(32|-ucrt)/
79
+ "x86_64-w64-mingw32-"
80
+ when /(x86_64|aarch64)-linux/
81
+ # We do believe that we are on Linux and can use native tools
82
+ ""
83
+ when /x86_64.*darwin/
84
+ "x86_64-apple-darwin-"
85
+ when /a.*64.*darwin/
86
+ "aarch64-apple-darwin-"
87
+ else
88
+ raise "CrossRuby.tool: unmatched platform: #{platform}"
89
+ end) + name
90
+ end
91
+
92
+ def target_file_format
93
+ case platform
94
+ when /64-mingw(32|-ucrt)/
95
+ "pei-x86-64"
96
+ when "x86_64-linux"
97
+ "elf64-x86-64"
98
+ when "aarch64-linux"
99
+ "elf64-little"
100
+ when "x86_64-darwin"
101
+ "Mach-O 64-bit x86-64"
102
+ when "arm64-darwin"
103
+ "Mach-O arm64"
104
+ else
105
+ raise "CrossRuby.target_file_format: unmatched platform: #{platform}"
106
+ end
107
+ end
108
+ # rubocop:enable Metrics/MethodLength
109
+ # rubocop:enable Metrics/CyclomaticComplexity
110
+
111
+ def dll_ext
112
+ darwin? ? "bundle" : "so"
113
+ end
114
+
115
+ def verify_format(dump, dll)
116
+ format_match = (/file format #{Regexp.quote(target_file_format)}\s/ === dump)
117
+ format_error = "Unexpected file format for '#{dll}', '#{target_file_format}' required"
118
+ raise format_error unless format_match
119
+ end
120
+
121
+ def verify_entry_windows(dump, dll)
122
+ unless /Table.*\sInit_express_parser\s/mi === dump
123
+ raise "Export function Init_express_parser not in dll #{dll}"
124
+ end
125
+ end
126
+
127
+ def verify_entry_linux(dll)
128
+ nm = `#{["env", "LANG=C", tool("nm"), "-D", dll].shelljoin}`
129
+ unless / T Init_express_parser/.match?(nm)
130
+ raise "Export function Init_express_parser not in dll #{dll}"
131
+ end
132
+ end
133
+
134
+ def verify_entry_darwin(dll)
135
+ nm = `#{["env", "LANG=C", tool("nm"), "-g", dll].shelljoin}`
136
+ unless / T _?Init_express_parser/.match?(nm)
137
+ raise "Export function Init_express_parser not in dll #{dll}"
138
+ end
139
+ end
140
+
141
+ def verify_entry(dump, dll)
142
+ case platform
143
+ when WINDOWS_PLATFORM_REGEX
144
+ verify_entry_windows(dump, dll)
145
+ when LINUX_PLATFORM_REGEX
146
+ verify_entry_linux(dll)
147
+ when DARWIN_PLATFORM_REGEX
148
+ verify_entry_darwin(dll)
149
+ else
150
+ raise "CrossRuby.verify_entry: unmatched platform: #{platform}"
151
+ end
152
+ end
153
+
154
+ # rubocop:disable Metrics/MethodLength
155
+ def allowed_dlls_ucrt
156
+ ["kernel32.dll",
157
+ "api-ms-win-crt-convert-l1-1-0.dll",
158
+ "api-ms-win-crt-environment-l1-1-0.dll",
159
+ "api-ms-win-crt-heap-l1-1-0.dll",
160
+ "api-ms-win-crt-locale-l1-1-0.dll",
161
+ "api-ms-win-crt-private-l1-1-0.dll",
162
+ "api-ms-win-crt-runtime-l1-1-0.dll",
163
+ "api-ms-win-crt-stdio-l1-1-0.dll",
164
+ "api-ms-win-crt-string-l1-1-0.dll",
165
+ "api-ms-win-crt-time-l1-1-0.dll",
166
+ "api-ms-win-crt-filesystem-l1-1-0.dll",
167
+ "api-ms-win-crt-math-l1-1-0.dll",
168
+ "libwinpthread-1.dll",
169
+ "x64-ucrt-ruby310.dll"]
170
+ end
171
+ # rubocop:enable Metrics/MethodLength
172
+
173
+ def allowed_dlls_mingw
174
+ [
175
+ "kernel32.dll",
176
+ "msvcrt.dll",
177
+ "libwinpthread-1.dll",
178
+ "x64-msvcrt-ruby#{api_ver_suffix}.dll",
179
+ ]
180
+ end
181
+
182
+ def allowed_dlls_windows
183
+ if ucrt?
184
+ allowed_dlls_ucrt
185
+ else
186
+ allowed_dlls_mingw
187
+ end
188
+ end
189
+
190
+ def allowed_dlls_linux
191
+ suffix = (platform == "x86_64-linux" ? "x86-64" : "aarch64")
192
+ [
193
+ "ld-linux-#{suffix}.so",
194
+ "libc.so",
195
+ "libm.so",
196
+ "libstdc++.so",
197
+ "libgcc_s.so",
198
+ ]
199
+ end
200
+
201
+ def allowed_dlls_darwin
202
+ [
203
+ "/usr/lib/libSystem.B.dylib",
204
+ "/usr/lib/libc++.1.dylib",
205
+ ]
206
+ end
207
+
208
+ def allowed_dlls
209
+ case platform
210
+ when WINDOWS_PLATFORM_REGEX
211
+ allowed_dlls_windows
212
+ when LINUX_PLATFORM_REGEX
213
+ allowed_dlls_linux
214
+ when DARWIN_PLATFORM_REGEX
215
+ allowed_dlls_darwin
216
+ else
217
+ raise "CrossRuby.allowed_dlls: unmatched platform: #{platform}"
218
+ end
219
+ end
220
+
221
+ def actual_dlls_linux(dump)
222
+ dump.scan(/NEEDED\s+(.*)/).map(&:first).uniq
223
+ end
224
+
225
+ def actual_dlls_windows(dump)
226
+ dump.scan(/DLL Name: (.*)$/).map(&:first).map(&:downcase).uniq
227
+ end
228
+
229
+ def actual_dlls_darwin(dll)
230
+ ldd = `#{[tool("otool"), "-L", dll].shelljoin}`
231
+ ldd.scan(/^\t([^ ]+) /).map(&:first).uniq
232
+ end
233
+
234
+ def actual_dlls(dump, dll)
235
+ case platform
236
+ when DARWIN_PLATFORM_REGEX
237
+ actual_dlls_darwin(dll)
238
+ when LINUX_PLATFORM_REGEX
239
+ actual_dlls_linux(dump)
240
+ when WINDOWS_PLATFORM_REGEX
241
+ actual_dlls_windows(dump)
242
+ else
243
+ raise "CrossRuby.actual_dlls: unmatched platform: #{platform}"
244
+ end
245
+ end
246
+
247
+ def verify_imports(dump, dll)
248
+ l = actual_dlls(dump, dll)
249
+ libs = allowed_dlls
250
+ l.delete_if { |ln| libs.any? { |lib| ln.include?(lib) } }
251
+ unless l.empty?
252
+ raise "Unexpected references in '#{dll}' : #{l}"
253
+ end
254
+ end
255
+
256
+ def lib_ref_versions(data)
257
+ # Build a hash of library versions like {"LIBUDEV"=>"183", "GLIBC"=>"2.17"}
258
+ data.each.with_object({}) do |(lib, ver), h|
259
+ if !h[lib] || ver.split(".").map(&:to_i).pack("C*") > h[lib].split(".").map(&:to_i).pack("C*")
260
+ h[lib] = ver
261
+ end
262
+ end
263
+ end
264
+
265
+ def verify_glibc_version(dump, dll)
266
+ ref_versions_data = dump.scan(/0x[\da-f]+ 0x[\da-f]+ \d+ (\w+)_([\d.]+)$/i)
267
+ ref_ver = lib_ref_versions(ref_versions_data)
268
+
269
+ unless ref_ver["GLIBC"].delete(".").to_i <= GLIBC_MIN_VERSION.delete(".").to_i
270
+ raise "Unexpected GLIBC version #{ref_ver['GLIBC']} for #{dll}, #{GLIBC_MIN_VERSION} or lower is expected"
271
+ end
272
+ end
273
+ end
274
+
275
+ CROSS_RUBIES = File.read(".cross_rubies").split("\n").map do |line|
276
+ case line
277
+ when /\A([^#]+):([^#]+)/
278
+ CrossRuby.new($1, $2)
279
+ end
280
+ end.compact
281
+
282
+ ENV["RUBY_CC_VERSION"] = CROSS_RUBIES.map(&:ver).uniq.join(":")
283
+
284
+ require "rake_compiler_dock"
285
+
286
+ def verify_dll(dll, cross_ruby)
287
+ dump = `#{["env", "LANG=C", cross_ruby.tool("objdump"), "-p", dll].shelljoin}`
288
+ cross_ruby.verify_format(dump, dll)
289
+ cross_ruby.verify_entry(dump, dll)
290
+ cross_ruby.verify_imports(dump, dll)
291
+ # Not sure if it is required, probably not
292
+ # I am keeping related code as a reference for future advances
293
+ # cross_ruby.verify_glibc_version(dump, dll) if cross_ruby.linux?
294
+
295
+ puts "#{dll}: passed shared library sanity checks"
296
+ end
297
+
298
+ CROSS_RUBIES.each do |cross_ruby|
299
+ unless Rake::Task.task_defined?(cross_ruby.dll_staging_path)
300
+ task cross_ruby.dll_staging_path do |t|
301
+ verify_dll t.name, cross_ruby
302
+ end
303
+ end
304
+ end
305
+
306
+ def gem_builder(plat)
307
+ # use Task#invoke because the pkg/*gem task is defined at runtime
308
+ Rake::Task["native:#{plat}"].invoke
309
+ Rake::Task["pkg/#{GEMSPEC.full_name}-#{Gem::Platform.new(plat)}.gem"].invoke
310
+ end
311
+
312
+ REDHAT_PREREQ = "sudo yum install -y git".freeze
313
+ UBUNTU_PREREQ = "sudo apt-get update -y && sudo apt-get install -y automake autoconf libtool build-essential".freeze
314
+
315
+ def pre_req(plat)
316
+ case plat
317
+ when /\linux/
318
+ "if [[ $(awk -F= '/^NAME/{print $2}' /etc/os-release) == '\"Ubuntu\"' ]]; then #{UBUNTU_PREREQ}; else #{REDHAT_PREREQ}; fi"
319
+ else
320
+ UBUNTU_PREREQ.to_s
321
+ end
322
+ end
323
+
324
+ namespace "gem" do
325
+ CROSS_RUBIES.find_all { |cr| cr.windows? || cr.linux? || cr.darwin? }.map(&:platform).uniq.each do |plat|
326
+ desc "build native gem for #{plat} platform"
327
+ task plat do
328
+ RakeCompilerDock.sh <<~RCD, platform: plat
329
+ #{pre_req(plat)} &&
330
+ gem install bundler --no-document &&
331
+ bundle &&
332
+ bundle exec rake gem:#{plat}:builder MAKE='nice make -j`nproc`'
333
+ RCD
334
+ end
335
+
336
+ namespace plat do
337
+ desc "build native gem for #{plat} platform (guest container)"
338
+ task "builder" do
339
+ gem_builder(plat)
340
+ end
341
+ end
342
+ end
343
+
344
+ desc "build native gems for windows"
345
+ multitask "windows" => CROSS_RUBIES.find_all(&:windows?).map(&:platform).uniq
346
+
347
+ desc "build native gems for linux"
348
+ multitask "linux" => CROSS_RUBIES.find_all(&:linux?).map(&:platform).uniq
349
+
350
+ desc "build native gems for darwin"
351
+ multitask "darwin" => CROSS_RUBIES.find_all(&:darwin?).map(&:platform).uniq
352
+ end
353
+
354
+ require "rake/extensiontask"
355
+
356
+ Rake::ExtensionTask.new("express_parser", GEMSPEC) do |ext|
357
+ ext.ext_dir = "ext/express-parser"
358
+ ext.lib_dir = File.join(*["lib", "expressir", "express", ENV.fetch("FAT_DIR", nil)].compact)
359
+ ext.config_options << ENV.fetch("EXTOPTS", nil)
360
+ ext.cross_compile = true
361
+ ext.cross_platform = CROSS_RUBIES.map(&:platform).uniq
362
+ ext.cross_config_options << "--enable-cross-build"
363
+ ext.cross_compiling do |spec|
364
+ spec.files.reject! { |path| File.fnmatch?("ext/*", path) }
365
+ spec.dependencies.reject! { |dep| dep.name == "rice" }
366
+ end
367
+ end
@@ -0,0 +1,17 @@
1
+ require "spec_helper"
2
+
3
+ RSpec.describe "Expressir" do
4
+ describe "version" do
5
+ it "has a version number" do |example|
6
+ print "\n[#{example.description}] "
7
+ expect(Expressir::VERSION).not_to be nil
8
+ end
9
+
10
+ it "displays the current verison" do |example|
11
+ print "\n[#{example.description}] "
12
+ command = %w(version)
13
+ output = capture_stdout { Expressir::Cli.start(command) }
14
+ expect(output).to include("Version #{Expressir::VERSION}")
15
+ end
16
+ end
17
+ end
@@ -0,0 +1,67 @@
1
+ require "yaml"
2
+ require "tempfile"
3
+ require "spec_helper"
4
+ require "expressir/express/parser"
5
+ require "expressir/express/cache"
6
+
7
+ TEST_VERSION = "0.0.0".freeze
8
+
9
+ RSpec.describe Expressir::Express::Cache do
10
+ describe ".to_file" do
11
+ it "exports an object" do |example|
12
+ print "\n[#{example.description}] "
13
+ temp_file = Tempfile.new
14
+
15
+ repository = Expressir::Model::Repository.new
16
+
17
+ begin
18
+ Expressir::Express::Cache.to_file(temp_file, repository, test_overwrite_version: TEST_VERSION)
19
+
20
+ size = File.size(temp_file)
21
+
22
+ expect(size).to be > 0
23
+ ensure
24
+ temp_file.close
25
+ temp_file.unlink
26
+ end
27
+ end
28
+ end
29
+
30
+ describe ".from_file" do
31
+ it "parses a file" do |example|
32
+ print "\n[#{example.description}] "
33
+ temp_file = Tempfile.new
34
+
35
+ repository = Expressir::Model::Repository.new
36
+
37
+ begin
38
+ Expressir::Express::Cache.to_file(temp_file, repository, test_overwrite_version: TEST_VERSION)
39
+
40
+ result = Expressir::Express::Cache.from_file(temp_file, test_overwrite_version: TEST_VERSION)
41
+
42
+ expect(result).to be_instance_of(Expressir::Model::Repository)
43
+ ensure
44
+ temp_file.close
45
+ temp_file.unlink
46
+ end
47
+ end
48
+
49
+ it "fails parsing a file from a different Expressir version" do |example|
50
+ print "\n[#{example.description}] "
51
+ temp_file = Tempfile.new
52
+
53
+ repository = Expressir::Model::Repository.new
54
+
55
+ begin
56
+ Expressir::Express::Cache.to_file(temp_file, repository, test_overwrite_version: TEST_VERSION)
57
+
58
+ expect do
59
+ Expressir::Express::Cache.from_file(temp_file)
60
+ end.to raise_error(Expressir::Error)
61
+ ensure
62
+ temp_file.close
63
+ temp_file.unlink
64
+ end
65
+ end
66
+ end
67
+ end
@@ -0,0 +1,135 @@
1
+ require "yaml"
2
+ require "spec_helper"
3
+ require "expressir/express/parser"
4
+ require "expressir/express/formatter"
5
+ require "expressir/express/schema_head_formatter"
6
+ require "expressir/express/hyperlink_formatter"
7
+
8
+ RSpec.describe Expressir::Express::Formatter do
9
+ describe ".format" do
10
+ it "exports an object (single.exp)" do |example|
11
+ print "\n[#{example.description}] "
12
+ exp_file = Expressir.root_path.join("spec", "syntax", "single.exp")
13
+ formatted_exp_file = Expressir.root_path.join("spec", "syntax", "single_formatted.exp")
14
+
15
+ repo = Expressir::Express::Parser.from_file(exp_file)
16
+
17
+ result = Expressir::Express::Formatter.format(repo)
18
+ # File.write(formatted_exp_file, result)
19
+ expected_result = File.read(formatted_exp_file)
20
+
21
+ expect(result).to eq(expected_result)
22
+ end
23
+
24
+ it "exports an object (multiple.exp)" do |example|
25
+ print "\n[#{example.description}] "
26
+ exp_file = Expressir.root_path.join("spec", "syntax", "multiple.exp")
27
+ formatted_exp_file = Expressir.root_path.join("spec", "syntax", "multiple_formatted.exp")
28
+
29
+ repo = Expressir::Express::Parser.from_file(exp_file)
30
+
31
+ result = Expressir::Express::Formatter.format(repo)
32
+ # File.write(formatted_exp_file, result)
33
+ expected_result = File.read(formatted_exp_file)
34
+
35
+ expect(result).to eq(expected_result)
36
+ end
37
+
38
+ it "exports an object (remark.exp)" do |example|
39
+ print "\n[#{example.description}] "
40
+ exp_file = Expressir.root_path.join("spec", "syntax", "remark.exp")
41
+ formatted_exp_file = Expressir.root_path.join("spec", "syntax", "remark_formatted.exp")
42
+
43
+ repo = Expressir::Express::Parser.from_file(exp_file)
44
+
45
+ result = Expressir::Express::Formatter.format(repo)
46
+ # File.write(formatted_exp_file, result)
47
+ expected_result = File.read(formatted_exp_file)
48
+
49
+ expect(result).to eq(expected_result)
50
+ end
51
+
52
+ it "exports an object (syntax.exp)" do |example|
53
+ print "\n[#{example.description}] "
54
+ exp_file = Expressir.root_path.join("spec", "syntax", "syntax.exp")
55
+ formatted_exp_file = Expressir.root_path.join("spec", "syntax", "syntax_formatted.exp")
56
+
57
+ repo = Expressir::Express::Parser.from_file(exp_file)
58
+
59
+ result = Expressir::Express::Formatter.format(repo)
60
+ # File.write(formatted_exp_file, result)
61
+ expected_result = File.read(formatted_exp_file)
62
+
63
+ expect(result).to eq(expected_result)
64
+ end
65
+
66
+ it "exports an object with schema head formatter (syntax.exp)" do |example|
67
+ print "\n[#{example.description}] "
68
+ exp_file = Expressir.root_path.join("spec", "syntax", "syntax.exp")
69
+ formatted_exp_file = Expressir.root_path.join("spec", "syntax", "syntax_schema_head_formatted.exp")
70
+
71
+ repo = Expressir::Express::Parser.from_file(exp_file)
72
+
73
+ formatter = Class.new(Expressir::Express::Formatter) do
74
+ include Expressir::Express::SchemaHeadFormatter
75
+ end
76
+ result = formatter.format(repo)
77
+ # File.write(formatted_exp_file, result)
78
+ expected_result = File.read(formatted_exp_file)
79
+
80
+ expect(result).to eq(expected_result)
81
+ end
82
+
83
+ it "exports an object with hyperlink formatter (syntax.exp)" do |example|
84
+ print "\n[#{example.description}] "
85
+ exp_file = Expressir.root_path.join("spec", "syntax", "syntax.exp")
86
+ formatted_exp_file = Expressir.root_path.join("spec", "syntax", "syntax_hyperlink_formatted.exp")
87
+
88
+ repo = Expressir::Express::Parser.from_file(exp_file)
89
+
90
+ formatter = Class.new(Expressir::Express::Formatter) do
91
+ include Expressir::Express::HyperlinkFormatter
92
+ end
93
+ result = formatter.format(repo)
94
+ # File.write(formatted_exp_file, result)
95
+ expected_result = File.read(formatted_exp_file)
96
+
97
+ expect(result).to eq(expected_result)
98
+ end
99
+
100
+ it "exports an object with hyperlink formatter (multiple.exp)" do |example|
101
+ print "\n[#{example.description}] "
102
+ exp_file = Expressir.root_path.join("spec", "syntax", "multiple.exp")
103
+ formatted_exp_file = Expressir.root_path.join("spec", "syntax", "multiple_hyperlink_formatted.exp")
104
+
105
+ repo = Expressir::Express::Parser.from_file(exp_file)
106
+
107
+ formatter = Class.new(Expressir::Express::Formatter) do
108
+ include Expressir::Express::HyperlinkFormatter
109
+ end
110
+ result = formatter.format(repo)
111
+ # File.write(formatted_exp_file, result)
112
+ expected_result = File.read(formatted_exp_file)
113
+
114
+ expect(result).to eq(expected_result)
115
+ end
116
+
117
+ it "exports an object with schema head and hyperlink formatter (multiple.exp)" do |example|
118
+ print "\n[#{example.description}] "
119
+ exp_file = Expressir.root_path.join("spec", "syntax", "multiple.exp")
120
+ formatted_exp_file = Expressir.root_path.join("spec", "syntax", "multiple_schema_head_hyperlink_formatted.exp")
121
+
122
+ repo = Expressir::Express::Parser.from_file(exp_file)
123
+
124
+ formatter = Class.new(Expressir::Express::Formatter) do
125
+ include Expressir::Express::SchemaHeadFormatter
126
+ include Expressir::Express::HyperlinkFormatter
127
+ end
128
+ result = formatter.format(repo)
129
+ # File.write(formatted_exp_file, result)
130
+ expected_result = File.read(formatted_exp_file)
131
+
132
+ expect(result).to eq(expected_result)
133
+ end
134
+ end
135
+ end
@@ -0,0 +1,104 @@
1
+ require "yaml"
2
+ require "spec_helper"
3
+ require "expressir/express/parser"
4
+
5
+ RSpec.describe Expressir::Express::Parser do
6
+ describe ".from_file" do
7
+ it "parses a file (single.exp)" do |example|
8
+ print "\n[#{example.description}] "
9
+ exp_file = Expressir.root_path.join("spec", "syntax", "single.exp")
10
+ yaml_file = Expressir.root_path.join("spec", "syntax", "single.yaml")
11
+
12
+ repo = Expressir::Express::Parser.from_file(exp_file)
13
+ result = YAML.dump(repo.to_hash(root_path: Expressir.root_path))
14
+ # File.write(yaml_file, result)
15
+ expected_result = File.read(yaml_file)
16
+
17
+ expect(result).to eq(expected_result)
18
+ end
19
+
20
+ it "parses a file (multiple.exp)" do |example|
21
+ print "\n[#{example.description}] "
22
+ exp_file = Expressir.root_path.join("spec", "syntax", "multiple.exp")
23
+ yaml_file = Expressir.root_path.join("spec", "syntax", "multiple.yaml")
24
+
25
+ repo = Expressir::Express::Parser.from_file(exp_file)
26
+ result = YAML.dump(repo.to_hash(root_path: Expressir.root_path))
27
+ # File.write(yaml_file, result)
28
+ expected_result = File.read(yaml_file)
29
+
30
+ expect(result).to eq(expected_result)
31
+ end
32
+
33
+ it "parses a file (syntax.exp)" do |example|
34
+ print "\n[#{example.description}] "
35
+ exp_file = Expressir.root_path.join("spec", "syntax", "syntax.exp")
36
+ yaml_file = Expressir.root_path.join("spec", "syntax", "syntax.yaml")
37
+
38
+ repo = Expressir::Express::Parser.from_file(exp_file)
39
+ result = YAML.dump(repo.to_hash(root_path: Expressir.root_path))
40
+ # File.write(yaml_file, result)
41
+ expected_result = File.read(yaml_file)
42
+
43
+ expect(result).to eq(expected_result)
44
+ end
45
+
46
+ it "parses a file (remark.exp)" do |example|
47
+ print "\n[#{example.description}] "
48
+ exp_file = Expressir.root_path.join("spec", "syntax", "remark.exp")
49
+ yaml_file = Expressir.root_path.join("spec", "syntax", "remark.yaml")
50
+
51
+ repo = Expressir::Express::Parser.from_file(exp_file)
52
+ result = YAML.dump(repo.to_hash(root_path: Expressir.root_path))
53
+ # File.write(yaml_file, result)
54
+ expected_result = File.read(yaml_file)
55
+
56
+ expect(result).to eq(expected_result)
57
+ end
58
+
59
+ it "parses a file including original source (multiple.exp)" do |example|
60
+ print "\n[#{example.description}] "
61
+ exp_file = Expressir.root_path.join("spec", "syntax", "multiple.exp")
62
+
63
+ input = File.read(exp_file)
64
+ repo = Expressir::Express::Parser.from_file(exp_file, include_source: true)
65
+
66
+ schema = repo.schemas.first
67
+ start_index = input.index("SCHEMA")
68
+ stop_index = input.index("END_SCHEMA;") + "END_SCHEMA;".length - 1
69
+ expected_result = input[start_index..stop_index]
70
+ expect(schema.source).to eq(expected_result)
71
+
72
+ entity = schema.entities.first
73
+ start_index = input.index("ENTITY")
74
+ stop_index = input.index("END_ENTITY;") + "END_ENTITY;".length - 1
75
+ expected_result = input[start_index..stop_index]
76
+ expect(entity.source).to eq(expected_result)
77
+ end
78
+ end
79
+
80
+ describe ".from_files" do
81
+ it "parses multiple files (single.exp, multiple.exp)" do |example|
82
+ print "\n[#{example.description}] "
83
+ exp_files = [
84
+ Expressir.root_path.join("spec", "syntax", "single.exp"),
85
+ Expressir.root_path.join("spec", "syntax", "multiple.exp"),
86
+ ]
87
+
88
+ repo = Expressir::Express::Parser.from_files(exp_files)
89
+
90
+ schemas = repo.schemas
91
+ expect(schemas.count).to eq(5)
92
+ expect(schemas[0].file).to eq(exp_files[0].to_s)
93
+ expect(schemas[0].id).to eq("single_schema")
94
+ expect(schemas[1].file).to eq(exp_files[1].to_s)
95
+ expect(schemas[1].id).to eq("multiple_schema")
96
+ expect(schemas[2].file).to eq(exp_files[1].to_s)
97
+ expect(schemas[2].id).to eq("multiple_schema2")
98
+ expect(schemas[3].file).to eq(exp_files[1].to_s)
99
+ expect(schemas[3].id).to eq("multiple_schema3")
100
+ expect(schemas[4].file).to eq(exp_files[1].to_s)
101
+ expect(schemas[4].id).to eq("multiple_schema4")
102
+ end
103
+ end
104
+ end