line-message-builder 0.3.0 → 0.4.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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: aa7a2c0c112ef20086d81a2c1cf4b1c430ffe291c07ccfc92dfe8d81db1ea980
4
- data.tar.gz: 163eb284640eeec1e5a035492ebca95b34d703d372f5d472e4330a762d7b2ceb
3
+ metadata.gz: 3bbeb0eeec944a0886b6e6dec3b171c88182c0097ad31c03cc16d7270f1eb471
4
+ data.tar.gz: 8f08afeab2e40b152e8e4218b00f03f725be5f3cfa70b687ebaf20e7d1dd2d7e
5
5
  SHA512:
6
- metadata.gz: bcadb195ad72f851fcc648f6641ab547fc2a1885583f64be97f08288f43025246d2a14dd311103a5c64521e636dfb2bd0f89f61deccedec75ebe8bebdc528d2c
7
- data.tar.gz: 1d612904e46b6e3e87590edf414b7839fa18412fe1c4734cdb961aacc8c1ed2e87a87a425b3cf563cc1eff4ec7337deaf0ff81592b75520dabba78363ec67629
6
+ metadata.gz: 0afd2ab03e4bbe7df364ebc27764380e48b9fd00a0a78ba345655f9227b7ff1cac00831024fd4ca923d2df1fb195c7e3c4947e6290f530a3466d002b325af4f3
7
+ data.tar.gz: 91455d81ccc9d6aa646e5a5851ad55baa19e89d4c427b4c9e4fa951676f6cf5d6e8005983d5a76610c05ced666a353d06f54ef7020516ad67250000cb4379ba7
@@ -1 +1 @@
1
- {".":"0.3.0"}
1
+ {".":"0.4.0"}
data/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.4.0](https://github.com/elct9620/line-message-builder/compare/v0.3.0...v0.4.0) (2025-04-06)
4
+
5
+
6
+ ### Features
7
+
8
+ * Add flex and margin options to Line Flex Button with improved error handling ([c8cd142](https://github.com/elct9620/line-message-builder/commit/c8cd1427528d5495d13bf93898da4638588065ae))
9
+ * Add flex box options and validation for LINE message builder ([133f87d](https://github.com/elct9620/line-message-builder/commit/133f87ddb3fd2a093947db0aef6363cd4c150701))
10
+ * Add flex bubble options and RSpec matcher for Line message builder ([605ad89](https://github.com/elct9620/line-message-builder/commit/605ad89870a53c55182f96db5f2738b5c347f0dc))
11
+ * Add margin option to flex text builder ([1d44522](https://github.com/elct9620/line-message-builder/commit/1d44522a44218bedab3d2009ef483ed112784248))
12
+ * Add quote token support for Line text messages ([7871999](https://github.com/elct9620/line-message-builder/commit/7871999dfc7032e75e5407c8b16bed7ef7dd28b8))
13
+ * Add support for flex, margin, and align options in Flex image builder ([693d0ab](https://github.com/elct9620/line-message-builder/commit/693d0abf5ef524b2e6d075f3c7e65eca49cf7f27))
14
+
3
15
  ## [0.3.0](https://github.com/elct9620/line-message-builder/compare/v0.2.0...v0.3.0) (2025-04-05)
4
16
 
5
17
 
data/README.md CHANGED
@@ -95,6 +95,7 @@ end
95
95
  | --------------------------- | ------------------------------------ |
96
96
  | `have_line_text_message` | Match a text message |
97
97
  | `have_line_flex_message` | Match a flex message |
98
+ | `have_line_flex_bubble` | Match a flex message with bubble |
98
99
  | `have_line_flex_text` | Match a flex message with text |
99
100
  | `have_line_flex_image` | Match a flex message with image |
100
101
  | `have_line_flex_button` | Match a flex message with button |
@@ -154,7 +155,7 @@ end
154
155
 
155
156
  | Type | Supported |
156
157
  | ---- | --------- |
157
- | Text | |
158
+ | Text | 🚧 |
158
159
  | Text v2 | ❌ |
159
160
  | Sticker | ❌ |
160
161
  | Sticker | ❌ |
@@ -189,19 +190,19 @@ end
189
190
 
190
191
  ### Flex Components
191
192
 
192
- | Component | Supported |
193
- | --------- | --------- |
194
- | Bubble | 🚧 |
195
- | Carousel | ❌ |
196
- | Box | 🚧 |
197
- | Button | 🚧 |
198
- | Image | 🚧 |
199
- | Video | ❌ |
200
- | Icon | ❌ |
201
- | Text | 🚧 |
202
- | Span | ❌ |
203
- | Separator | ❌ |
204
- | Filler | ❌ |
193
+ | Component | Supported |
194
+ | --------- | --------- |
195
+ | Bubble | 🚧 |
196
+ | Carousel | ❌ |
197
+ | Box | 🚧 |
198
+ | Button | 🚧 |
199
+ | Image | 🚧 |
200
+ | Video | ❌ |
201
+ | Icon | ❌ |
202
+ | Text | 🚧 |
203
+ | Span | ❌ |
204
+ | Separator | ❌ |
205
+ | Filler | ❌ Deprecated |
205
206
 
206
207
  ## Development
207
208
 
@@ -6,7 +6,7 @@ module Line
6
6
  module Actions
7
7
  # The Message class is used to build message actions for quick replies.
8
8
  class Message < Line::Message::Builder::Base
9
- def initialize(text: nil, label: nil, context: nil, &)
9
+ def initialize(text, label: nil, context: nil, &)
10
10
  @text = text
11
11
  @label = label
12
12
 
@@ -6,7 +6,7 @@ module Line
6
6
  module Actions
7
7
  # The Postback class is used to build postback actions for quick replies.
8
8
  class Postback < Line::Message::Builder::Base
9
- def initialize(data: nil, label: nil, display_text: nil, context: nil, &)
9
+ def initialize(data, label: nil, display_text: nil, context: nil, &)
10
10
  @data = data
11
11
  @label = label
12
12
  @display_text = display_text
@@ -13,12 +13,12 @@ module Line
13
13
  super
14
14
  end
15
15
 
16
- def text(text, &)
17
- @messages << Text.new(text, context: context, &)
16
+ def text(text, **options, &)
17
+ @messages << Text.new(text, context: context, **options, &)
18
18
  end
19
19
 
20
- def flex(**args, &)
21
- @messages << Flex::Builder.new(**args, context: context, &)
20
+ def flex(**options, &)
21
+ @messages << Flex::Builder.new(context: context, **options, &)
22
22
  end
23
23
 
24
24
  def build
@@ -6,7 +6,11 @@ module Line
6
6
  module Flex
7
7
  # The box is a component for the Flex message.
8
8
  class Box < Line::Message::Builder::Base
9
+ attr_reader :contents
10
+
9
11
  option :layout, default: :horizontal
12
+ option :spacing, default: nil
13
+ option :flex, default: nil
10
14
 
11
15
  def initialize(context: nil, **options, &)
12
16
  @contents = []
@@ -31,10 +35,15 @@ module Line
31
35
  end
32
36
 
33
37
  def to_h
38
+ raise RequiredError, "layout is required" if layout.nil?
39
+ raise RequiredError, "contents is required" if contents.empty?
40
+
34
41
  {
35
42
  type: "box",
36
- layout: @layout,
37
- contents: @contents.map(&:to_h)
43
+ layout: layout,
44
+ spacing: spacing,
45
+ flex: flex,
46
+ contents: contents.map(&:to_h)
38
47
  }.compact
39
48
  end
40
49
  end
@@ -6,7 +6,10 @@ module Line
6
6
  module Flex
7
7
  # The bubble is container for the Flex message.
8
8
  class Bubble < Line::Message::Builder::Base
9
- def initialize(context: nil, &)
9
+ option :size, default: nil
10
+ option :styles, default: nil
11
+
12
+ def initialize(context: nil, **options, &)
10
13
  @header = nil
11
14
  @hero = nil
12
15
  @body = nil
@@ -41,7 +44,9 @@ module Line
41
44
  header: @header&.to_h,
42
45
  hero: @hero&.to_h,
43
46
  body: @body&.to_h,
44
- footer: @footer&.to_h
47
+ footer: @footer&.to_h,
48
+ size: size,
49
+ styles: styles
45
50
  }.compact
46
51
  end
47
52
  end
@@ -14,8 +14,8 @@ module Line
14
14
  super
15
15
  end
16
16
 
17
- def bubble(&)
18
- @contents = Line::Message::Builder::Flex::Bubble.new(context: context, &)
17
+ def bubble(**options, &)
18
+ @contents = Line::Message::Builder::Flex::Bubble.new(context: context, **options, &)
19
19
  end
20
20
 
21
21
  def to_h
@@ -6,6 +6,10 @@ module Line
6
6
  module Flex
7
7
  # The button is a component of the Flex message.
8
8
  class Button < Line::Message::Builder::Base
9
+ attr_reader :action
10
+
11
+ option :flex, default: nil
12
+ option :margin, default: nil
9
13
  option :style, default: :link
10
14
  option :height, default: :md
11
15
 
@@ -16,21 +20,23 @@ module Line
16
20
  end
17
21
 
18
22
  def message(text, label:, display_text: nil, &)
19
- @action = Actions::Message.new(text: text, label: label, display_text: display_text, &)
23
+ @action = Actions::Message.new(text, label: label, display_text: display_text, &)
20
24
  end
21
25
 
22
26
  def postback(data, label: nil, display_text: nil, &)
23
- @action = Actions::Postback.new(data: data, label: label, display_text: display_text, &)
27
+ @action = Actions::Postback.new(data, label: label, display_text: display_text, &)
24
28
  end
25
29
 
26
30
  def to_h
27
- raise Error, "Action is required" unless @action
31
+ raise RequiredError, "action is required" if action.nil?
28
32
 
29
33
  {
30
34
  type: "button",
31
- action: @action.to_h,
32
- style: @style,
33
- height: @height
35
+ action: action.to_h,
36
+ flex: flex,
37
+ margin: margin,
38
+ style: style,
39
+ height: height
34
40
  }.compact
35
41
  end
36
42
  end
@@ -6,9 +6,14 @@ module Line
6
6
  module Flex
7
7
  # The image is a component for the Flex message.
8
8
  class Image < Line::Message::Builder::Base
9
+ attr_reader :url
10
+
9
11
  option :size, default: nil
10
12
  option :aspect_ratio, default: nil
11
13
  option :aspect_mode, default: nil
14
+ option :flex, default: nil
15
+ option :margin, default: nil
16
+ option :align, default: nil
12
17
 
13
18
  def initialize(url, context: nil, **options, &)
14
19
  @url = url
@@ -16,25 +21,18 @@ module Line
16
21
  super(context: context, **options, &)
17
22
  end
18
23
 
19
- def size(size)
20
- @size = size
21
- end
22
-
23
- def aspect_ratio(aspect_ratio)
24
- @aspect_ratio = aspect_ratio
25
- end
26
-
27
- def aspect_mode(aspect_mode)
28
- @aspect_mode = aspect_mode
29
- end
24
+ def to_h # rubocop:disable Metrics/MethodLength
25
+ raise RequiredError, "url is required" if url.nil?
30
26
 
31
- def to_h
32
27
  {
33
28
  type: "image",
34
- url: @url,
35
- size: @size,
36
- aspectRatio: @aspect_ratio,
37
- aspectMode: @aspect_mode
29
+ url: url,
30
+ size: size,
31
+ flex: flex,
32
+ margin: margin,
33
+ align: align,
34
+ aspectRatio: aspect_ratio,
35
+ aspectMode: aspect_mode
38
36
  }.compact
39
37
  end
40
38
  end
@@ -6,12 +6,15 @@ module Line
6
6
  module Flex
7
7
  # The text is a component of the Flex message.
8
8
  class Text < Line::Message::Builder::Base
9
+ attr_reader :text
10
+
11
+ option :size, default: nil
9
12
  option :wrap, default: false
10
13
  option :line_spacing, default: nil
11
14
  option :color, default: nil
12
- option :size, default: nil
13
15
  option :align, default: nil
14
16
  option :flex, default: nil
17
+ option :margin, default: nil
15
18
 
16
19
  def initialize(text, context: nil, **options, &)
17
20
  @text = text
@@ -23,16 +26,19 @@ module Line
23
26
  @wrap = true
24
27
  end
25
28
 
26
- def to_h
29
+ def to_h # rubocop:disable Metrics/MethodLength
30
+ raise RequiredError, "text is required" if text.nil?
31
+
27
32
  {
28
33
  type: "text",
29
- text: @text,
30
- wrap: @wrap,
31
- lineSpacing: @line_spacing,
32
- color: @color,
33
- size: @size,
34
- align: @align,
35
- flex: @flex
34
+ text: text,
35
+ wrap: wrap,
36
+ lineSpacing: line_spacing,
37
+ color: color,
38
+ size: size,
39
+ align: align,
40
+ margin: margin,
41
+ flex: flex
36
42
  }.compact
37
43
  end
38
44
  end
@@ -13,14 +13,14 @@ module Line
13
13
 
14
14
  def message(text, label:, image_url: nil, &)
15
15
  action(
16
- Actions::Message.new(text: text, label: label, &),
16
+ Actions::Message.new(text, label: label, &),
17
17
  image_url
18
18
  )
19
19
  end
20
20
 
21
21
  def postback(data, label: nil, display_text: nil, image_url: nil, &)
22
22
  action(
23
- Actions::Postback.new(data: data, label: label, display_text: display_text, &),
23
+ Actions::Postback.new(data, label: label, display_text: display_text, &),
24
24
  image_url
25
25
  )
26
26
  end
@@ -5,16 +5,19 @@ module Line
5
5
  module Builder
6
6
  # Text message builder.
7
7
  class Text < Base
8
- def initialize(text, context: nil, &block)
8
+ option :quote_token, default: nil
9
+
10
+ def initialize(text, context: nil, **options, &block)
9
11
  @text = text
10
12
 
11
- super(context: context, &block)
13
+ super(context: context, **options, &block)
12
14
  end
13
15
 
14
16
  def to_h
15
17
  {
16
18
  type: "text",
17
19
  text: @text,
20
+ quoteToken: quote_token,
18
21
  quickReply: @quick_reply&.to_h
19
22
  }.compact
20
23
  end
@@ -3,7 +3,7 @@
3
3
  module Line
4
4
  module Message
5
5
  module Builder
6
- VERSION = "0.3.0"
6
+ VERSION = "0.4.0"
7
7
  end
8
8
  end
9
9
  end
@@ -7,6 +7,7 @@ module Line
7
7
  # The Builder module provides a DSL for building LINE messages.
8
8
  module Builder
9
9
  class Error < StandardError; end
10
+ class RequiredError < Error; end
10
11
 
11
12
  require_relative "builder/base"
12
13
  require_relative "builder/actions"
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Line
4
+ module Message
5
+ module RSpec
6
+ # :nodoc:
7
+ module Matchers
8
+ # The flex component matcher for RSpec to search nested flex components in the message array.
9
+ class HaveFlexBubble
10
+ def initialize(expected)
11
+ @expected = Utils.stringify_keys!(expected || {}, deep: true)
12
+ end
13
+
14
+ def description
15
+ return "have flex bubble" if @expected.empty?
16
+
17
+ "have flex bubble matching #{@expected.inspect}"
18
+ end
19
+
20
+ def matches?(actual)
21
+ @actual = Utils.stringify_keys!(actual, deep: true)
22
+ @actual.any? { |message| match_flex_component?(message) }
23
+ end
24
+ alias == matches?
25
+
26
+ def failure_message
27
+ return "expected to find a flex bubble" if @expected.empty?
28
+
29
+ "expected to find a flex bubble matching #{@expected.inspect}"
30
+ end
31
+
32
+ private
33
+
34
+ def match_flex_component?(message)
35
+ return false unless message["type"] == "flex"
36
+
37
+ match_content?(message["contents"])
38
+ end
39
+
40
+ def match_content?(content)
41
+ return match_options?(content) if content["type"] == "bubble"
42
+ return false unless content["contents"]
43
+
44
+ content["contents"].any? { |nested_content| match_content?(nested_content) }
45
+ end
46
+
47
+ def match_options?(content)
48
+ return false unless content["type"] == "bubble"
49
+
50
+ ::RSpec::Matchers::BuiltIn::Include.new(@expected).matches?(content)
51
+ end
52
+ end
53
+
54
+ def have_line_flex_bubble(expected = nil) # rubocop:disable Naming/PredicateName
55
+ HaveFlexBubble.new(expected)
56
+ end
57
+ end
58
+ end
59
+ end
60
+ end
@@ -8,33 +8,37 @@ module Line
8
8
  # The text message matcher for RSpec to search for text messages in the message array.
9
9
  class HaveTextMessage
10
10
  def initialize(expected)
11
- @expected = expected
11
+ @text, @options = expected
12
+ @options = Utils.stringify_keys!(@options || {})
12
13
  end
13
14
 
14
15
  def description
15
- return "have text message" if @expected.nil?
16
+ return "have text message" if @text.nil?
17
+ return "have text message matching #{@text.inspect}" if @options.empty?
16
18
 
17
- "have text message matching #{@expected.inspect}"
19
+ "have text message matching #{@text.inspect} with options #{@options.inspect}"
18
20
  end
19
21
 
20
22
  def matches?(actual)
21
23
  @actual = Utils.stringify_keys!(actual, deep: true)
22
- @actual.each do |message|
24
+ @actual.any? do |message|
23
25
  next unless message["type"] == "text"
26
+ next true if @text.nil?
24
27
 
25
- return true if message["text"].match?(@expected)
28
+ message["text"].match?(@text) && ::RSpec::Matchers::BuiltIn::Include.new(@options).matches?(message)
26
29
  end
27
-
28
- false
29
30
  end
30
31
  alias == matches?
31
32
 
32
33
  def failure_message
33
- "expected to find a text message matching #{@expected}"
34
+ return "expected to find a text message" if @text.nil?
35
+ return "expected to find a text message matching #{@text.inspect}" if @options.empty?
36
+
37
+ "expected to find a text message matching #{@text.inspect} with options #{@options.inspect}"
34
38
  end
35
39
  end
36
40
 
37
- def have_line_text_message(expected = nil) # rubocop:disable Naming/PredicateName
41
+ def have_line_text_message(*expected) # rubocop:disable Naming/PredicateName
38
42
  HaveTextMessage.new(expected)
39
43
  end
40
44
  end
@@ -4,4 +4,5 @@ require_relative "matchers/utils"
4
4
  require_relative "matchers/have_text_message"
5
5
  require_relative "matchers/have_quick_reply"
6
6
  require_relative "matchers/have_flex_message"
7
+ require_relative "matchers/have_flex_bubble"
7
8
  require_relative "matchers/have_flex_component"
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: line-message-builder
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.0
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aotokitsuruya
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2025-04-05 00:00:00.000000000 Z
11
+ date: 2025-04-06 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: The LINE Messaging API message builder.
14
14
  email:
@@ -43,6 +43,7 @@ files:
43
43
  - lib/line/message/builder/version.rb
44
44
  - lib/line/message/rspec.rb
45
45
  - lib/line/message/rspec/matchers.rb
46
+ - lib/line/message/rspec/matchers/have_flex_bubble.rb
46
47
  - lib/line/message/rspec/matchers/have_flex_component.rb
47
48
  - lib/line/message/rspec/matchers/have_flex_message.rb
48
49
  - lib/line/message/rspec/matchers/have_quick_reply.rb