comment_strip-ruby 0.2.0 → 0.2.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.
@@ -0,0 +1,179 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ $:.unshift File.join(__dir__, '../..', 'lib')
4
+
5
+
6
+ require 'comment_strip'
7
+
8
+ require 'xqsr3/extensions/test/unit'
9
+
10
+ require 'test/unit'
11
+
12
+ # Contractual / line-preserving expectations that currently fail against
13
+ # LanguageFamilies::C. These cases document known defects; do not weaken the
14
+ # expectations to match the buggy output — fix the scanner instead.
15
+ class Test_C_strip_defects < Test::Unit::TestCase
16
+
17
+ include ::CommentStrip
18
+
19
+
20
+ # --- End-of-input / unterminated constructs --------------------------------
21
+
22
+ def test_trailing_slash_at_eof_is_preserved_after_identifier
23
+
24
+ # A lone '/' that never becomes '//' or '/*' must remain in the output.
25
+ assert_equal 'a/', strip('a/', 'C')
26
+ end
27
+
28
+ def test_trailing_slash_at_eof_alone_is_preserved
29
+
30
+ assert_equal '/', strip('/', 'C')
31
+ end
32
+
33
+ def test_trailing_slash_at_eof_after_spaces_is_preserved
34
+
35
+ assert_equal 'x = y /', strip('x = y /', 'C')
36
+ end
37
+
38
+ def test_unterminated_block_comment_preserves_embedded_newlines
39
+
40
+ # Line-preserving policy: newlines inside an open /* … */ that never
41
+ # closes should still appear in the output (as blank lines), matching the
42
+ # behaviour used when the comment *does* close.
43
+ input = "before/*\nline2\nline3"
44
+ expected = "before\n\n"
45
+
46
+ assert_equal expected, strip(input, 'C')
47
+ end
48
+
49
+
50
+ # --- CRLF / line-ending fidelity ------------------------------------------
51
+
52
+ def test_crlf_inside_block_comment_counts_as_one_line_break
53
+
54
+ # One Windows line break inside a block comment must contribute one
55
+ # preserved newline, not one per CR and LF byte.
56
+ input = "a/*\r\nb*/c"
57
+ expected = "a\nc"
58
+
59
+ assert_equal expected, strip(input, 'C')
60
+ end
61
+
62
+ def test_crlf_only_block_comment_body_preserves_single_blank_line
63
+
64
+ input = "/*\r\n*/\r\nint x;\r\n"
65
+ expected = "\n\r\nint x;\r\n"
66
+
67
+ assert_equal expected, strip(input, 'C')
68
+ end
69
+
70
+ def test_multiple_crlf_lines_inside_block_comment
71
+
72
+ input = "start/*\r\none\r\ntwo\r\n*/end"
73
+ expected = "start\n\n\nend"
74
+
75
+ assert_equal expected, strip(input, 'C')
76
+ end
77
+
78
+
79
+ # --- C++ digit separators (apostrophe is not a character literal) ---------
80
+
81
+ def test_cxx14_digit_separator_does_not_swallow_following_line_comment
82
+
83
+ # 1'000 uses '\'' as a digit separator between digits — there is no
84
+ # closing quote. The trailing // comment must still be stripped.
85
+ input = "int x = 1'000; // one thousand\n"
86
+ expected = "int x = 1'000; \n"
87
+
88
+ assert_equal expected, strip(input, 'C')
89
+ end
90
+
91
+ def test_cxx14_digit_separator_does_not_swallow_following_block_comment
92
+
93
+ input = "long y = 1'000; /* million */\n"
94
+ expected = "long y = 1'000; \n"
95
+
96
+ assert_equal expected, strip(input, 'C')
97
+ end
98
+
99
+
100
+ # --- Translation-phase / line-splice fidelity (C family claim) ------------
101
+
102
+ def test_backslash_newline_splices_before_line_comment_recognition
103
+
104
+ # In C/C++, backslash-newline is removed in translation phase 2, before
105
+ # comments are recognised. So the following is one // comment spanning
106
+ # both physical lines; `int x;` must not survive as code.
107
+ input = "// comment continues \\\nint x;\n"
108
+ expected = "\n"
109
+
110
+ assert_equal expected, strip(input, 'C')
111
+ end
112
+
113
+ def test_backslash_newline_inside_block_comment_does_not_invent_extra_lines
114
+
115
+ # After splicing, this is a single-line block comment with no newline.
116
+ input = "a/* foo \\\n bar */b"
117
+ expected = "ab"
118
+
119
+ assert_equal expected, strip(input, 'C')
120
+ end
121
+
122
+
123
+ # --- Documented family breadth (rdoc / README list C#, Go, Java, Rust) ----
124
+
125
+ def test_go_raw_string_backticks_protect_comment_markers
126
+
127
+ # Go raw strings use `…`; // and /* inside them are not comments.
128
+ input = "s := `// not a comment /* nor this */`; // real\n"
129
+ expected = "s := `// not a comment /* nor this */`; \n"
130
+
131
+ assert_equal expected, strip(input, 'C')
132
+ end
133
+
134
+ def test_csharp_verbatim_string_backslash_is_not_an_escape
135
+
136
+ # In C# @"…", backslash is literal. @"\"; ends the string after one
137
+ # backslash character; the following // is a real comment.
138
+ input = "s = @\"\\\"; // real\n"
139
+ expected = "s = @\"\\\"; \n"
140
+
141
+ assert_equal expected, strip(input, 'C')
142
+ end
143
+
144
+ def test_rust_lifetime_then_line_comment
145
+
146
+ # A lone Rust lifetime `'a` is not a C character literal. Stuck in the
147
+ # one-character-literal state, // must still be recognised afterwards.
148
+ input = "fn f<'a>() {} // lifetime\n"
149
+ expected = "fn f<'a>() {} \n"
150
+
151
+ assert_equal expected, strip(input, 'C')
152
+ end
153
+
154
+ def test_cxx_raw_string_embedded_double_quote_does_not_end_string
155
+
156
+ # C++ R"(…)" may contain " without ending the literal.
157
+ input = "s = R\"(\")\"; // real\n"
158
+ expected = "s = R\"(\")\"; \n"
159
+
160
+ assert_equal expected, strip(input, 'C')
161
+ end
162
+
163
+
164
+ # --- Dispatch / diagnostics -----------------------------------------------
165
+
166
+ def test_unrecognised_family_message_has_no_typo
167
+
168
+ begin
169
+ strip('', 'NotAFamily')
170
+ flunk 'expected RuntimeError'
171
+ rescue RuntimeError => x
172
+
173
+ assert_match(/unrecognised or not supported\z/, x.message)
174
+ assert_no_match(/supported1/, x.message)
175
+ end
176
+ end
177
+ end
178
+
179
+ # ############################## end of file ############################# #
@@ -0,0 +1,154 @@
1
+ #! /usr/bin/env ruby
2
+
3
+ $:.unshift File.join(__dir__, '../..', 'lib')
4
+
5
+
6
+ require 'comment_strip'
7
+
8
+ require 'xqsr3/extensions/test/unit'
9
+
10
+ require 'test/unit'
11
+
12
+ # Contractual expectations that currently fail against
13
+ # LanguageFamilies::HashLine. These cases document known defects for the
14
+ # README-claimed Ruby / Python / shell family; do not weaken the expectations
15
+ # to match buggy output — fix the scanner instead.
16
+ class Test_HashLine_strip_defects < Test::Unit::TestCase
17
+
18
+ include ::CommentStrip
19
+
20
+
21
+ # --- Empty and escaped single-quoted strings ------------------------------
22
+ #
23
+ # The scanner reuses the C one-character-literal machine for `'…'`, which
24
+ # is wrong for Ruby / Python / shell string literals.
25
+
26
+ def test_empty_single_quoted_string_then_hash_comment
27
+
28
+ # '' must open and immediately close a string; the following # is a
29
+ # comment.
30
+ input = "x='' # comment\n"
31
+ expected = "x='' \n"
32
+
33
+ assert_equal expected, strip(input, :Hash_Line)
34
+ end
35
+
36
+ def test_empty_single_quoted_string_mid_statement_then_hash_comment
37
+
38
+ input = "a=''; b=2 # comment\n"
39
+ expected = "a=''; b=2 \n"
40
+
41
+ assert_equal expected, strip(input, :Hash_Line)
42
+ end
43
+
44
+ def test_escaped_quote_inside_single_quoted_string_then_hash_comment
45
+
46
+ # Ruby / Python-style escaped quote inside '...'; # after the closing
47
+ # quote is a comment.
48
+ input = "s='it\\'s' # comment\n"
49
+ expected = "s='it\\'s' \n"
50
+
51
+ assert_equal expected, strip(input, :Hash_Line)
52
+ end
53
+
54
+ def test_adjacent_empty_single_quoted_strings_then_hash_comment
55
+
56
+ # ''+'' must be two empty strings; # after them is a comment. The
57
+ # one-character-literal machine treats the second quote of each '' as
58
+ # the character body and never returns to :text for the #.
59
+ input = "x = ''+'' # comment\n"
60
+ expected = "x = ''+'' \n"
61
+
62
+ assert_equal expected, strip(input, :Hash_Line)
63
+ end
64
+
65
+
66
+ # --- Language-specific quoting claimed by README (Ruby / Python / shell) --
67
+
68
+ def test_python_triple_single_quotes_protect_hash
69
+
70
+ input = "s = '''a # b'''\n"
71
+ expected = "s = '''a # b'''\n"
72
+
73
+ assert_equal expected, strip(input, :Hash_Line)
74
+ end
75
+
76
+ def test_python_triple_single_quotes_then_real_comment
77
+
78
+ input = "s = '''a # b''' # real\n"
79
+ expected = "s = '''a # b''' \n"
80
+
81
+ assert_equal expected, strip(input, :Hash_Line)
82
+ end
83
+
84
+ def test_ruby_percent_q_braces_protect_hash
85
+
86
+ input = "s = %q{a # b}\n"
87
+ expected = "s = %q{a # b}\n"
88
+
89
+ assert_equal expected, strip(input, :Hash_Line)
90
+ end
91
+
92
+ def test_ruby_percent_q_braces_then_real_comment
93
+
94
+ input = "s = %q{a # b} # real\n"
95
+ expected = "s = %q{a # b} \n"
96
+
97
+ assert_equal expected, strip(input, :Hash_Line)
98
+ end
99
+
100
+ def test_ruby_percent_w_brackets_protect_hash
101
+
102
+ input = "a = %w[one # two]\n"
103
+ expected = "a = %w[one # two]\n"
104
+
105
+ assert_equal expected, strip(input, :Hash_Line)
106
+ end
107
+
108
+ def test_ruby_percent_q_parentheses_protect_hash
109
+
110
+ input = "s = %q(a # b)\n"
111
+ expected = "s = %q(a # b)\n"
112
+
113
+ assert_equal expected, strip(input, :Hash_Line)
114
+ end
115
+
116
+ def test_ruby_heredoc_protects_hash
117
+
118
+ input = <<-EOF
119
+ s = <<~TXT
120
+ a # not comment
121
+ TXT
122
+ # real comment
123
+ EOF
124
+ expected = <<-EOF
125
+ s = <<~TXT
126
+ a # not comment
127
+ TXT
128
+
129
+ EOF
130
+
131
+ assert_equal expected, strip(input, :Hash_Line)
132
+ end
133
+
134
+ def test_ruby_heredoc_single_quoted_protects_hash
135
+
136
+ input = <<-EOF
137
+ s = <<~'TXT'
138
+ a # not comment
139
+ TXT
140
+ x = 1 # real
141
+ EOF
142
+ expected = [
143
+ "s = <<~'TXT'\n",
144
+ "a # not comment\n",
145
+ "TXT\n",
146
+ "x = 1 ",
147
+ "\n",
148
+ ].join
149
+
150
+ assert_equal expected, strip(input, :Hash_Line)
151
+ end
152
+ end
153
+
154
+ # ############################## end of file ############################# #
metadata CHANGED
@@ -1,39 +1,58 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: comment_strip-ruby
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Wilson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-03-31 00:00:00.000000000 Z
11
+ date: 2026-08-30 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: xqsr3
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '0.38'
19
+ version: 0.39.5
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '1.0'
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 0.39.5
30
+ - - "<"
25
31
  - !ruby/object:Gem::Version
26
- version: '0.38'
32
+ version: '1.0'
27
33
  description: 'Source code comment stripping library
28
34
 
29
35
  '
30
- email: matthew@synesis.com.au
36
+ email:
37
+ - matthew@synesis.com.au
31
38
  executables: []
32
39
  extensions: []
33
40
  extra_rdoc_files: []
34
41
  files:
42
+ - AUTHORS.md
43
+ - CHANGES.md
44
+ - CONTRIBUTING.md
45
+ - EXAMPLES.md
46
+ - FAQ.md
47
+ - INSTALL.md
35
48
  - LICENSE
49
+ - NEWS.md
36
50
  - README.md
51
+ - Rakefile
52
+ - SECURITY.md
53
+ - TODO.md
54
+ - examples/read_c_family_source.rb
55
+ - examples/read_c_family_source_from_stdin.rb
37
56
  - lib/comment_strip.rb
38
57
  - lib/comment_strip/language_families/c.rb
39
58
  - lib/comment_strip/language_families/hash_line.rb
@@ -41,13 +60,19 @@ files:
41
60
  - lib/comment_strip/version.rb
42
61
  - test/scratch/ex1.rb
43
62
  - test/unit/tc_strip_c.rb
63
+ - test/unit/tc_strip_c_defects.rb
44
64
  - test/unit/tc_strip_hash_line.rb
65
+ - test/unit/tc_strip_hash_line_defects.rb
45
66
  - test/unit/tc_version.rb
46
67
  - test/unit/ts_all.rb
47
68
  homepage: https://github.com/synesissoftware/comment_strip.r
48
69
  licenses:
49
70
  - BSD-3-Clause
50
- metadata: {}
71
+ metadata:
72
+ bug_tracker_uri: https://github.com/synesissoftware/comment_strip.r/issues
73
+ changelog_uri: https://github.com/synesissoftware/comment_strip.r/blob/master/CHANGES.md
74
+ homepage_uri: https://github.com/synesissoftware/comment_strip.r
75
+ source_code_uri: https://github.com/synesissoftware/comment_strip.r
51
76
  post_install_message:
52
77
  rdoc_options: []
53
78
  require_paths:
@@ -57,9 +82,6 @@ required_ruby_version: !ruby/object:Gem::Requirement
57
82
  - - ">="
58
83
  - !ruby/object:Gem::Version
59
84
  version: '2.0'
60
- - - "<"
61
- - !ruby/object:Gem::Version
62
- version: '4'
63
85
  required_rubygems_version: !ruby/object:Gem::Requirement
64
86
  requirements:
65
87
  - - ">="
@@ -69,5 +91,5 @@ requirements: []
69
91
  rubygems_version: 3.2.15
70
92
  signing_key:
71
93
  specification_version: 4
72
- summary: comment_strip.r
94
+ summary: Comment Strip, for Ruby
73
95
  test_files: []