line-message-builder 0.8.0 → 0.10.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 (45) hide show
  1. checksums.yaml +4 -4
  2. data/.release-please-manifest.json +1 -1
  3. data/.rubocop.yml +5 -0
  4. data/CHANGELOG.md +41 -0
  5. data/CLAUDE.md +124 -0
  6. data/CONVENTIONS.md +36 -0
  7. data/README.md +61 -43
  8. data/claudekit.json +11 -0
  9. data/docs/rubrics/rdoc.md +169 -0
  10. data/lib/line/message/builder/actions/message.rb +52 -31
  11. data/lib/line/message/builder/actions/postback.rb +63 -33
  12. data/lib/line/message/builder/actions/uri.rb +139 -0
  13. data/lib/line/message/builder/actions.rb +6 -3
  14. data/lib/line/message/builder/base.rb +92 -67
  15. data/lib/line/message/builder/container.rb +64 -69
  16. data/lib/line/message/builder/context.rb +55 -80
  17. data/lib/line/message/builder/flex/actionable.rb +53 -32
  18. data/lib/line/message/builder/flex/box.rb +366 -79
  19. data/lib/line/message/builder/flex/bubble.rb +78 -51
  20. data/lib/line/message/builder/flex/builder.rb +47 -36
  21. data/lib/line/message/builder/flex/button.rb +96 -48
  22. data/lib/line/message/builder/flex/carousel.rb +57 -29
  23. data/lib/line/message/builder/flex/icon.rb +152 -0
  24. data/lib/line/message/builder/flex/image.rb +103 -42
  25. data/lib/line/message/builder/flex/partial.rb +58 -55
  26. data/lib/line/message/builder/flex/position.rb +187 -100
  27. data/lib/line/message/builder/flex/separator.rb +84 -0
  28. data/lib/line/message/builder/flex/size.rb +67 -47
  29. data/lib/line/message/builder/flex/span.rb +184 -0
  30. data/lib/line/message/builder/flex/text.rb +210 -54
  31. data/lib/line/message/builder/flex.rb +31 -26
  32. data/lib/line/message/builder/quick_reply.rb +174 -4
  33. data/lib/line/message/builder/text.rb +70 -3
  34. data/lib/line/message/builder/version.rb +1 -1
  35. data/lib/line/message/builder.rb +16 -13
  36. data/lib/line/message/rspec/matchers/have_flex_bubble.rb +1 -1
  37. data/lib/line/message/rspec/matchers/have_flex_component.rb +26 -5
  38. data/lib/line/message/rspec/matchers/have_flex_message.rb +1 -1
  39. data/lib/line/message/rspec/matchers/have_flex_separator.rb +20 -0
  40. data/lib/line/message/rspec/matchers/have_quick_reply.rb +1 -1
  41. data/lib/line/message/rspec/matchers/have_text_message.rb +1 -1
  42. data/lib/line/message/rspec/matchers.rb +1 -0
  43. data/llm.txt +367 -45
  44. data/release-please-config.json +3 -1
  45. metadata +12 -3
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: c49876bd79a2b1e98639a5e709a41736ebc11e8c7b5bf811ca478c52df762183
4
- data.tar.gz: 65ceed1d2fbef231161bc7eb131269354875c39b202da96bb6fcd42edce4bf86
3
+ metadata.gz: 5da58bf9e4dc340ba666cb7074f3c43c1c1bb71db5fbd9e65229064e414720d5
4
+ data.tar.gz: 0aed8988bdbd8b5273eeedcff427f62f8a4be6a68a9b8935d9cf0792b0b0cdff
5
5
  SHA512:
6
- metadata.gz: bf2111f3470856dc021330c2fa73e3275842596d858e636d198f3dd8dcea7bddf9a60a252e4a80eb5e6297126b0ec3afeeaf143181ef565db06af9cf558c93c6
7
- data.tar.gz: e98ec6e6696268c00f599de55e6b6acb09067c2370c6fc5357f8d1ee7f74b9b6e7d2c9b59a527ae5bc806ca6c685163311648b3a78641bd028d8ba6b71dc3bf1
6
+ metadata.gz: 867683533deec71a69b0019bc40b6abffa81fad98cab36da0c2f6f298f2c80b50f863700b88634a7bc5c66fa62ed53781782e24654aa5f427181ccb2c9dd4929
7
+ data.tar.gz: 8d4e59936aa354b5a2f29d21285dd449cf033ec7b6cc7b7c19fb32b3098b84bb9317a86f2998fa4dc4a5c70e837a2f0ef9a07027fbd57be691eb3e907dc4a8c2
@@ -1 +1 @@
1
- {".":"0.8.0"}
1
+ {".":"0.10.0"}
data/.rubocop.yml CHANGED
@@ -14,3 +14,8 @@ Style/StringLiterals:
14
14
 
15
15
  Style/StringLiteralsInInterpolation:
16
16
  EnforcedStyle: double_quotes
17
+
18
+ # RSpec matchers often return booleans but shouldn't be named with '?'
19
+ Naming/PredicateMethod:
20
+ Exclude:
21
+ - 'lib/line/message/rspec/**/*'
data/CHANGELOG.md CHANGED
@@ -1,5 +1,46 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.10.0](https://github.com/elct9620/line-message-builder/compare/v0.9.0...v0.10.0) (2026-08-18)
4
+
5
+
6
+ ### ⚠ BREAKING CHANGES
7
+
8
+ * **builder:** passing an option a component does not declare now raises ValidationError instead of being ignored.
9
+ * **flex:** Flex buttons no longer accept padding, padding_all, padding_top, padding_bottom, padding_start or padding_end. Apply padding to the surrounding box instead.
10
+
11
+ ### Features
12
+
13
+ * **actions:** add uri action ([d5fdb26](https://github.com/elct9620/line-message-builder/commit/d5fdb261014e927c58b5ae16e29c2b46d934b758))
14
+ * **builder:** reject options a component does not declare ([0e236b3](https://github.com/elct9620/line-message-builder/commit/0e236b35ee9a562d031c474e23dc819055fdea4d))
15
+ * **flex:** add box appearance properties and gradient background ([809e84a](https://github.com/elct9620/line-message-builder/commit/809e84a1faf6d84c15a20964c5fd78ab43907ead))
16
+ * **flex:** add button color and scaling, drop padding ([2ef15fd](https://github.com/elct9620/line-message-builder/commit/2ef15fd09b2a441fb2f17c938497861906570f83))
17
+ * **flex:** add icon component ([cbd1eda](https://github.com/elct9620/line-message-builder/commit/cbd1edacbef8a377b3c7ad72059833915f1ea010))
18
+ * **flex:** add image background_color and animated ([c7f2102](https://github.com/elct9620/line-message-builder/commit/c7f21028640a47d171823e0d047e2c228f5c9844))
19
+ * **flex:** add separator margin and color ([073c039](https://github.com/elct9620/line-message-builder/commit/073c0391d2a1092b0c4886588123491fa260b946))
20
+ * **flex:** add span style ([ef80a4b](https://github.com/elct9620/line-message-builder/commit/ef80a4b8236bef920cc87af7cf051dd3dff5044a))
21
+ * **flex:** add text weight, max_lines, style, decoration and scaling ([d6a83b4](https://github.com/elct9620/line-message-builder/commit/d6a83b41415e95e69cf746d5d628d48dcefb8390))
22
+
23
+ ## [0.9.0](https://github.com/elct9620/line-message-builder/compare/v0.8.0...v0.9.0) (2025-06-03)
24
+
25
+
26
+ ### Features
27
+
28
+ * add flex separator matcher and tests for flex message components ([0d34bc9](https://github.com/elct9620/line-message-builder/commit/0d34bc9fcfeef9d2ca519548f4a83a3de046eb33))
29
+ * add Flex::Span message builder for LINE messaging API ([a8377e9](https://github.com/elct9620/line-message-builder/commit/a8377e93861fa286e95a69d3cb3c9897c1992044))
30
+ * add have_line_flex_span matcher and comprehensive tests for span component ([b9072cd](https://github.com/elct9620/line-message-builder/commit/b9072cd3e4c56c9346bb3d6cf98ee11374029807))
31
+ * add Separator builder for Flex messages ([accb2aa](https://github.com/elct9620/line-message-builder/commit/accb2aa41f9a016445f377f97e93f085734764c4))
32
+ * add separator method to Flex::Box for adding separator elements ([4125ae1](https://github.com/elct9620/line-message-builder/commit/4125ae15fd5666431ec864121cf40d3c4fb0f56f))
33
+ * add Span component for styled text in Flex Messages ([a458d1d](https://github.com/elct9620/line-message-builder/commit/a458d1d2473e0859bc7e1c81254888a8c8fde9a7))
34
+ * add span method to flex box builder and remove related specs ([af8dc8f](https://github.com/elct9620/line-message-builder/commit/af8dc8f9f4b8c8a7a12c15db23a50331dfc102cb))
35
+ * add support for spans within flex text components ([90ab15d](https://github.com/elct9620/line-message-builder/commit/90ab15df7044d15308d23ef864a69f84d71e28e7))
36
+
37
+
38
+ ### Bug Fixes
39
+
40
+ * add Flex::Separator component and require it in flex.rb ([4152c10](https://github.com/elct9620/line-message-builder/commit/4152c1024a7634b526f94fa4e76a518a6ff0787c))
41
+ * ensure matcher finds flex separator in all nested containers ([d289ea1](https://github.com/elct9620/line-message-builder/commit/d289ea178e17d4ca00b796a9f666c527982d82f6))
42
+ * remove duplicate Separator class definition in flex separator.rb ([2c6b6d0](https://github.com/elct9620/line-message-builder/commit/2c6b6d063a2da97a0781591a697cf3034cb135f6))
43
+
3
44
  ## [0.8.0](https://github.com/elct9620/line-message-builder/compare/v0.7.0...v0.8.0) (2025-05-24)
4
45
 
5
46
 
data/CLAUDE.md ADDED
@@ -0,0 +1,124 @@
1
+ # CLAUDE.md
2
+
3
+ This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
4
+
5
+ ## Repository Overview
6
+
7
+ This is a Ruby gem that provides a Domain Specific Language (DSL) for building LINE messaging API messages. The gem allows developers to construct complex Flex Messages, text messages, and quick replies using an intuitive Ruby syntax.
8
+
9
+ ## Development Commands
10
+
11
+ ### Testing
12
+ - `rake spec` or `bundle exec rspec` - Run all tests
13
+ - `bundle exec rspec spec/specific_file_spec.rb` - Run a specific test file
14
+ - `bundle exec rspec spec/specific_file_spec.rb:123` - Run test at specific line
15
+
16
+ ### Code Quality
17
+ - `rake rubocop` or `bundle exec rubocop` - Run RuboCop linter
18
+ - `bundle exec rubocop --autocorrect` - Auto-fix RuboCop violations where possible
19
+ - `rake` - Run both tests and RuboCop (default task)
20
+
21
+ ### Build and Release
22
+ - `bundle exec rake install` - Install gem locally
23
+ - `bundle exec rake build` - Build the gem
24
+ - `bundle exec rake release` - Release new version (creates git tag and pushes to RubyGems)
25
+
26
+ ### Console
27
+ - `bin/console` - Interactive console with the gem loaded
28
+
29
+ ## Architecture
30
+
31
+ ### Core Components
32
+
33
+ **Main Builder (`lib/line/message/builder.rb`)**
34
+ - Entry point for the DSL using `Line::Message::Builder.with`
35
+ - Handles context binding and message collection
36
+ - Supports both regular mode and SDK v2 mode
37
+
38
+ **Base Classes**
39
+ - `Builder::Base` - Foundation for all builder components
40
+ - `Builder::Container` - Base for components that can contain other components
41
+ - `Builder::Context` - Manages variable access and method delegation
42
+
43
+ **Message Types**
44
+ - `Builder::Text` - Simple text messages with quick reply support
45
+ - `Builder::Flex` - Complex flex messages with rich layouts
46
+
47
+ **Flex Components (`lib/line/message/builder/flex/`)**
48
+ - `Bubble` - Main flex container
49
+ - `Carousel` - Collection of bubbles
50
+ - `Box` - Layout container (horizontal/vertical/baseline)
51
+ - `Text` - Text component with span support
52
+ - `Span` - Inline text styling within text components
53
+ - `Button` - Interactive buttons
54
+ - `Image` - Image components
55
+ - `Separator` - Visual separators
56
+
57
+ **Actions (`lib/line/message/builder/actions/`)**
58
+ - `Message` - Send text message action
59
+ - `Postback` - Send postback data action
60
+
61
+ **Quick Replies**
62
+ - `QuickReply` - Container for quick reply buttons
63
+
64
+ **Partials**
65
+ - `Flex::Partial` - Base class for reusable flex components
66
+
67
+ ### Key Patterns
68
+
69
+ **DSL Design**: The gem uses Ruby's block evaluation (`instance_eval`) to create a clean DSL where methods like `text`, `box`, `button` are available directly within builder blocks.
70
+
71
+ **Context Handling**: The builder accepts a context object (like Rails' `view_context`) and delegates unknown methods to it, enabling access to helpers and variables.
72
+
73
+ **Validation**: Components validate their properties using the `validators/` classes to ensure LINE API compatibility.
74
+
75
+ **Testing Strategy**: Uses feature-style tests that build complete messages and verify their structure, rather than unit tests of individual methods.
76
+
77
+ ## Coding Conventions
78
+
79
+ ### DSL Usage
80
+ ```ruby
81
+ # Preferred - clean DSL syntax
82
+ Line::Message::Builder.with do
83
+ flex alt_text: "Hello" do
84
+ bubble do
85
+ body do
86
+ text "Content"
87
+ end
88
+ end
89
+ end
90
+ end
91
+
92
+ # Avoid - explicit block parameters
93
+ Line::Message::Builder.with do |builder|
94
+ builder.flex alt_text: "Hello" do
95
+ # ...
96
+ end
97
+ end
98
+ ```
99
+
100
+ ### RSpec Testing
101
+ - Write feature tests using the full DSL as the test subject
102
+ - Use `subject { builder.build }` pattern
103
+ - Prefer `it { is_expected.to ... }` over `expect(subject)...`
104
+ - One assertion per example
105
+ - Test message structure, not implementation details
106
+
107
+ ### Code Style
108
+ - Follow standard Ruby naming conventions (snake_case, CamelCase, UPPER_SNAKE_CASE)
109
+ - No explanatory comments - code should be self-documenting
110
+ - Use RDoc for API documentation only
111
+
112
+ ## RSpec Matchers
113
+
114
+ The gem provides custom RSpec matchers for testing LINE messages:
115
+ - `have_line_text_message` - Match text messages
116
+ - `have_line_flex_message` - Match flex messages
117
+ - `have_line_flex_bubble` - Match flex bubbles
118
+ - `have_line_flex_component` - Match specific flex components
119
+
120
+ Include with: `require "line/message/rspec"`
121
+
122
+ ## LLM Integration
123
+
124
+ The repository includes `llm.txt` with comprehensive DSL documentation for AI assistants. This file contains detailed examples and API references for all supported LINE message types and components.
data/CONVENTIONS.md CHANGED
@@ -16,6 +16,42 @@ This gem is designed to provide DSL (Domain Specific Language) for building LINE
16
16
 
17
17
  Only use comments for RDoc documentation. Do not use comments to explain anything in the code. The code should be self-explanatory. If you find yourself needing to write a comment to explain something, consider refactoring the code instead.
18
18
 
19
+ ## DSL
20
+
21
+ When using the `Line::Message::Builder` DSL, following is recommended:
22
+
23
+ ```ruby
24
+ Line::Message::Builder.with do
25
+ flex alt_text: "Hello, World!" do
26
+ bubble do
27
+ header do
28
+ text "Welcome to LINE Messaging API"
29
+ end
30
+ body do
31
+ text "This is a sample message."
32
+ end
33
+ end
34
+ end
35
+ end
36
+ ```
37
+
38
+ DO NOT use `do |container|` syntax as following:
39
+
40
+ ```ruby
41
+ Line::Message::Builder.with do |builder|
42
+ builder.flex alt_text: "Hello, World!" do
43
+ builder.bubble do
44
+ builder.header do
45
+ builder.text "Welcome to LINE Messaging API"
46
+ end
47
+ builder.body do
48
+ builder.text "This is a sample message."
49
+ end
50
+ end
51
+ end
52
+ end
53
+ ```
54
+
19
55
  ## RSpec
20
56
 
21
57
  - Write feature tests instead of unit tests, use `Line::Message::Builder` as test subject to verify the behavior of the DSL.
data/README.md CHANGED
@@ -12,7 +12,7 @@ Build LINE messages using DSL (Domain Specific Language) in Ruby.
12
12
  - Build LINE messages using DSL
13
13
  - Validation of properties
14
14
  - RSpec matchers for testing
15
- - LINE Bot SDK v2 support (WIP)
15
+ - LINE Bot SDK v2 support (Experimental)
16
16
 
17
17
  ## Installation
18
18
 
@@ -42,15 +42,23 @@ You can get it from [http://aotoki.me/line-message-builder/llm.txt](http://aotok
42
42
  ### Builder
43
43
 
44
44
  ```ruby
45
- builder = Line::MessageBuilder::Builder.with do
46
- text "Hello, world!"
45
+ builder = Line::Message::Builder.with do
46
+ text "Hello, world!"
47
47
  end
48
48
 
49
49
  pp builder.build
50
50
  # => [{ type: "text", text: "Hello, world!" }]
51
51
 
52
52
  puts builder.to_json
53
- # => {"type":"text","text":"Hello, world!"}
53
+ # => "[{\"type\":\"text\",\"text\":\"Hello, world!\"}]"
54
+ ```
55
+
56
+ To use with [line-bot-sdk-ruby](https://github.com/line/line-bot-sdk-ruby) v2, you can set mode to `sdkv2`:
57
+
58
+ ```ruby
59
+ builder = Line::Message::Builder.with(mode: :sdkv2) do
60
+ text "Hello, world!"
61
+ end
54
62
  ```
55
63
 
56
64
  ### Context
@@ -59,31 +67,31 @@ The context can make `Builder` to access additional methods and variables.
59
67
 
60
68
  ```ruby
61
69
  context = OpenStruct.new(
62
- name: "John Doe",
70
+ name: "John Doe",
63
71
  )
64
72
 
65
- builder = Line::MessageBuilder::Builder.with(context) do
66
- text "Hello, #{name}!"
73
+ builder = Line::Message::Builder.with(context) do
74
+ text "Hello, #{name}!"
67
75
  end
68
76
 
69
77
  pp builder.build
70
78
  # => [{ type: "text", text: "Hello, John Doe!" }]
71
79
 
72
80
  puts builder.to_json
73
- # => {"type":"text","text":"Hello, John Doe!"}
81
+ # => "[{\"type\":\"text\",\"text\":\"Hello, John Doe!\"}]"
74
82
  ```
75
83
 
76
84
  For Rails, you can use `view_context` to make `Builder` to access Rails helpers.
77
85
 
78
86
  ```ruby
79
87
  # app/controllers/line_controller.rb
80
- builder = Line::MessageBuilder::Builder.with(view_context) do
81
- text "Anything you want?" do
82
- quick_reply do
83
- message "Yes", label: "Yes", image_url: image_url("yes.png")
84
- message "No", label: "No", image_url: image_url("no.png")
85
- end
88
+ builder = Line::Message::Builder.with(view_context) do
89
+ text "Anything you want?" do
90
+ quick_reply do
91
+ message "Yes", label: "Yes", image_url: image_url("yes.png")
92
+ message "No", label: "No", image_url: image_url("no.png")
86
93
  end
94
+ end
87
95
  end
88
96
  ```
89
97
 
@@ -92,18 +100,18 @@ If not in controller, you can create a `ActionView::Base` instance and pass it t
92
100
  ```ruby
93
101
  # app/presenters/line_presenter.rb
94
102
  context = ActionView::Base.new(
95
- ActionController::Base.view_paths,
96
- {},
97
- ActionController::Base.new,
103
+ ActionController::Base.view_paths,
104
+ {},
105
+ ActionController::Base.new,
98
106
  )
99
107
 
100
- builder = Line::MessageBuilder::Builder.with(context) do
101
- text "Anything you want?" do
102
- quick_reply do
103
- message "Yes", label: "Yes", image_url: image_url("yes.png")
104
- message "No", label: "No", image_url: image_url("no.png")
105
- end
108
+ builder = Line::Message::Builder.with(context) do
109
+ text "Anything you want?" do
110
+ quick_reply do
111
+ message "Yes", label: "Yes", image_url: image_url("yes.png")
112
+ message "No", label: "No", image_url: image_url("no.png")
106
113
  end
114
+ end
107
115
  end
108
116
  ```
109
117
 
@@ -124,7 +132,7 @@ class CardPartial < Line::Message::Builder::Flex::Partial
124
132
  end
125
133
  end
126
134
 
127
- builder = Line::MessageBuilder::Builder.with do
135
+ builder = Line::Message::Builder.with do
128
136
  carousel do
129
137
  3.times do |i|
130
138
  bubble do
@@ -146,7 +154,7 @@ class CardPartial < Line::Message::Builder::Flex::Partial
146
154
  end
147
155
  end
148
156
 
149
- builder = Line::MessageBuilder::Builder.with do
157
+ builder = Line::Message::Builder.with do
150
158
  carousel do
151
159
  3.times do |i|
152
160
  bubble do
@@ -171,6 +179,8 @@ end
171
179
  | `have_line_flex_image` | Match a flex message with image |
172
180
  | `have_line_flex_button` | Match a flex message with button |
173
181
  | `have_line_flex_box` | Match a flex message with box |
182
+ | `have_line_flex_separator` | Match a flex message with separator |
183
+ | `have_line_flex_icon` | Match a flex message with icon |
174
184
 
175
185
 
176
186
  Add `line/message/rspec` to your `spec_helper.rb` or `rails_helper.rb`:
@@ -183,7 +193,7 @@ Include `Line::Message::RSpec::Matchers` in your RSpec configuration:
183
193
 
184
194
  ```ruby
185
195
  RSpec.configure do |config|
186
- config.include Line::Message::RSpec::Matchers
196
+ config.include Line::Message::RSpec::Matchers
187
197
  end
188
198
  ```
189
199
 
@@ -191,10 +201,10 @@ Then the matchers are available in your specs:
191
201
 
192
202
  ```ruby
193
203
  let(:builder) do
194
- Line::MessageBuilder::Builder.with do
195
- text "Hello, world!"
196
- text "Nice to meet you!"
197
- end
204
+ Line::Message::Builder.with do
205
+ text "Hello, world!"
206
+ text "Nice to meet you!"
207
+ end
198
208
  end
199
209
 
200
210
  subject { builder.build }
@@ -207,12 +217,13 @@ The matchers can work with webmock `a_request`:
207
217
 
208
218
  ```ruby
209
219
  it "reply with message" do
210
- expect(a_request(:post, "https://api.line.me/v2/bot/message/reply")
211
- .with(
212
- body: hash_including({
213
- messages: have_line_text_message(/Hello, world!/),
214
- },
215
- ))).to have_been_made.once
220
+ expect(a_request(:post, "https://api.line.me/v2/bot/message/reply")
221
+ .with(
222
+ body: hash_including({
223
+ messages: have_line_text_message(/Hello, world!/),
224
+ })
225
+ )
226
+ ).to have_been_made.once
216
227
  end
217
228
  ```
218
229
 
@@ -251,7 +262,7 @@ end
251
262
  | ----------- | --------- |
252
263
  | Postback | 🚧 |
253
264
  | Message | ✅ |
254
- | Uri | |
265
+ | Uri | |
255
266
  | Datetime | ❌ |
256
267
  | Camera | ❌ |
257
268
  | CameraRoll | ❌ |
@@ -265,16 +276,23 @@ end
265
276
  | --------- | --------- |
266
277
  | Bubble | 🚧 |
267
278
  | Carousel | ✅ |
268
- | Box | 🚧 |
269
- | Button | 🚧 |
270
- | Image | 🚧 |
279
+ | Box | |
280
+ | Button | |
281
+ | Image | |
271
282
  | Video | ❌ |
272
- | Icon | |
283
+ | Icon | 🚧 |
273
284
  | Text | 🚧 |
274
- | Span | |
275
- | Separator | |
285
+ | Span | 🚧 |
286
+ | Separator | |
276
287
  | Filler | ❌ Deprecated |
277
288
 
289
+ Text, Span and Icon are marked partial only because their `size` option accepts
290
+ the `none`–`xxl` keywords and pixel values, while LINE also defines `xxs` and
291
+ `3xl`–`5xl`. Every other property of these components is supported.
292
+
293
+ Bubble is missing `direction` and a bubble-level action. Postback is missing
294
+ `inputOption` and `fillInText`.
295
+
278
296
  ## Development
279
297
 
280
298
  After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
data/claudekit.json ADDED
@@ -0,0 +1,11 @@
1
+ {
2
+ "rubric": {
3
+ "rules": [
4
+ {
5
+ "name": "RDoc",
6
+ "pattern": "lib/.*\\.rb$",
7
+ "path": "docs/rubrics/rdoc.md"
8
+ }
9
+ ]
10
+ }
11
+ }
@@ -0,0 +1,169 @@
1
+ # RDoc Documentation Rubric
2
+
3
+ This document outlines the criteria for evaluating the quality of RDoc documentation in Ruby code. We assert at least 80% of the criteria must be met to pass.
4
+
5
+ ## Criteria
6
+
7
+ ### Proper RDoc Syntax Usage (1 point)
8
+
9
+ > Enforce correct RDoc markup syntax and avoid YARD-style tags that are not compatible with RDoc
10
+
11
+ ```ruby
12
+ ##
13
+ # The Base class serves as the foundation for all message builder classes
14
+ # within the Line::Message::Builder DSL. It provides core functionality
15
+ # for defining options, handling initialization, and delegating method calls
16
+ # to a context object.
17
+ #
18
+ # == Example
19
+ #
20
+ # class MyBuilder < Base
21
+ # option :color, default: "red"
22
+ # end
23
+ #
24
+ # builder = MyBuilder.new
25
+ # puts builder.color # => "red"
26
+ ```
27
+
28
+ - Use RDoc directives: `:method:`, `:call-seq:`, `:nodoc:`, `:yields:` (not YARD `@param`, `@return`, `@see` tags)
29
+ - Use `==` for major sections (h2), `===` for subsections (h3)
30
+ - Use `[param_name]` for parameter documentation with 2-space indented descriptions
31
+ - Use `+code+` for method names and identifiers, `<code>:symbol</code>` for symbols and string literals
32
+ - Reference external documentation with links: `{Link Text}[URL]`
33
+ - Use `-` for unordered lists
34
+ - Consult [RDoc Markup Reference](https://ruby.github.io/rdoc/RDoc/MarkupReference.html) for details
35
+
36
+ ### Complete Class and Module Documentation (1 point)
37
+
38
+ > Every public class and module must have comprehensive documentation including purpose, usage, and cross-references
39
+
40
+ ```ruby
41
+ # The Text class provides a builder for creating simple text messages
42
+ # in the LINE Messaging API. Text messages are the most basic message type,
43
+ # consisting of plain text content with optional quick reply buttons and
44
+ # quote tokens for replying to specific messages.
45
+ #
46
+ # Text messages support:
47
+ # - Plain text content (up to 5,000 characters)
48
+ # - Quick reply buttons for user interaction
49
+ # - Quote tokens to reply to specific messages in a conversation
50
+ #
51
+ # == Example: Basic text message
52
+ #
53
+ # Line::Message::Builder.with do
54
+ # text "Hello, world!"
55
+ # end
56
+ #
57
+ # See also:
58
+ # - QuickReply
59
+ # - https://developers.line.biz/en/reference/messaging-api/#text-message
60
+ class Text < Base
61
+ ```
62
+
63
+ - Classes must have a purpose statement (what it represents/does)
64
+ - Include feature list using bullet points for complex components
65
+ - Provide at least one complete usage example with proper context
66
+ - Include "See also:" section with related classes and external API documentation links
67
+ - For mixin modules, document what functionality they add to including classes
68
+
69
+ ### Method Documentation with Parameters and Returns (1 point)
70
+
71
+ > All public methods must document their purpose, parameters, and return values clearly
72
+
73
+ ```ruby
74
+ # Defines a new option for the builder class.
75
+ #
76
+ # This method dynamically creates an instance method on the builder class
77
+ # with the given name. When this instance method is called without arguments,
78
+ # it returns the current value; with an argument, it sets the value.
79
+ #
80
+ # [name]
81
+ # The name of the option to define. This will also be the name of the
82
+ # generated instance method.
83
+ # [default]
84
+ # The default value for the option if not explicitly set.
85
+ # [validator]
86
+ # An optional validator object that must respond to +valid!+ method.
87
+ # If the value is invalid, the validator should raise an error.
88
+ #
89
+ # [return]
90
+ # The dynamically created method name as a symbol
91
+ #
92
+ # == Example
93
+ #
94
+ # class MyBuilder < Base
95
+ # option :color, default: "red"
96
+ # option :size, validator: SizeValidator.new
97
+ # end
98
+ def option(name, default: nil, validator: nil)
99
+ ```
100
+
101
+ - Document method purpose in the first paragraph
102
+ - Use `[param_name]` format for each parameter with 2-space indented description
103
+ - Document optional parameters and their default values
104
+ - Include `[block]` documentation if the method accepts a block
105
+ - Use `[return]` label to describe return value for non-obvious returns
106
+ - Use `:nodoc:` directive for private methods and internal implementations
107
+
108
+ ### Dynamic Method Documentation with :method: Directive (1 point)
109
+
110
+ > Dynamically defined methods must be documented using RDoc's :method: and :call-seq: directives
111
+
112
+ ```ruby
113
+ # :method: quote_token
114
+ # :call-seq:
115
+ # quote_token() -> String or nil
116
+ # quote_token(value) -> String
117
+ #
118
+ # Sets or gets the quote token for replying to a specific message.
119
+ #
120
+ # Quote tokens allow your bot to quote and reply to a specific message
121
+ # in the conversation. When set, the original message being replied to
122
+ # will be displayed above the new message.
123
+ #
124
+ # [value]
125
+ # The quote token string obtained from a webhook event
126
+ option :quote_token, default: nil
127
+ ```
128
+
129
+ - Use `:method:` directive to document dynamically defined methods (e.g., from `option`, `attr_accessor`)
130
+ - Use `:call-seq:` to show both getter and setter signatures
131
+ - Show return types using arrow notation: `method_name() -> Type or nil`
132
+ - Document both forms: getter (no arguments) and setter (with argument)
133
+ - Place directive immediately before the line that defines the method
134
+ - Include parameter documentation using `[param_name]` format
135
+
136
+ ### Progressive Examples with Real-World Usage (1 point)
137
+
138
+ > Documentation must include runnable examples that progress from simple to complex use cases
139
+
140
+ ```ruby
141
+ # == Example: Basic text message
142
+ #
143
+ # Line::Message::Builder.with do
144
+ # text "Hello, world!"
145
+ # end
146
+ #
147
+ # === Example: Text with quick reply
148
+ #
149
+ # Line::Message::Builder.with do
150
+ # text "Choose an option:" do
151
+ # quick_reply do
152
+ # button action: :message, label: "Yes", text: "I agree"
153
+ # button action: :message, label: "No", text: "I disagree"
154
+ # end
155
+ # end
156
+ # end
157
+ ```
158
+
159
+ - Provide at least one complete, executable example for public classes
160
+ - Use descriptive example headings: `== Example: Description`
161
+ - Show full DSL context (e.g., `Line::Message::Builder.with do ... end`)
162
+ - Use `===` for sub-examples or variations
163
+ - Include output comments using `# =>` notation where helpful
164
+ - Progress from simple to complex examples
165
+ - Indent code blocks with 2 spaces
166
+
167
+ ## Scoring
168
+
169
+ Each criterion is worth 1 point and is awarded only when fully satisfied. A score below 80% (4 out of 5 points) indicates insufficient documentation quality.