Skip to content

Commit

Permalink
Merge #565
Browse files Browse the repository at this point in the history
565: feat: fixed for the issue (#556) r=myConsciousness a=myConsciousness

# 1. Description

<!-- Provide a description of what this PR is doing.
If you're modifying existing behavior, describe the existing behavior, how this PR is changing it,
and what motivated the change. If this is a breaking change, specify explicitly which APIs have been
changed. -->

## 1.1. Checklist

<!-- Before you create this PR confirm that it meets all requirements listed below by checking the
relevant checkboxes (`[x]`). This will ensure a smooth and quick review process. -->

- [x] The title of my PR starts with a [Conventional Commit] prefix (`fix:`, `feat:`, `docs:` etc).
- [x] I have read the [Contributor Guide] and followed the process outlined for submitting PRs.
- [x] I have updated/added tests for ALL new/updated/fixed functionality.
- [x] I have updated/added relevant documentation in `docs` and added dartdoc comments with `///`.
- [x] I have updated/added relevant examples in `examples`.

## 1.2. Breaking Change

<!-- Does your PR require users to manually update their apps to accommodate your change?

If the PR is a breaking change this should be indicated with suffix "!"  (for example, `feat!:`, `fix!:`). See [Conventional Commit] for details.
-->

- [ ] Yes, this is a breaking change.
- [x] No, this is _not_ a breaking change.

## 1.3. Related Issues

<!-- Provide a list of issues related to this PR from the [issue database].
Indicate which of these issues are resolved or fixed by this PR, i.e. Fixes #xxxx* !-->

<!-- Links -->

[issue database]: https://github.com/twitter-dart/twitter-api-v2/issues
[contributor guide]: https://github.com/twitter-dart/twitter-api-v2/blob/main/CONTRIBUTING.md
[style guide]: https://github.com/twitter-dart/twitter-api-v2/blob/main/STYLEGUIDE.md
[conventional commit]: https://conventionalcommits.org


Co-authored-by: myConsciousness <[email protected]>
  • Loading branch information
bors[bot] and myConsciousness authored Nov 22, 2022
2 parents 386c0de + b6ff2be commit e83e11a
Show file tree
Hide file tree
Showing 7 changed files with 157 additions and 0 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@
- Supported `entity:` filtering rule operator. You can use this operator with following methods. ([#557](https://github.com/twitter-dart/twitter-api-v2/issues/557))
- `matchEntity`
- `notMatchEntity`
- Supported `context:` filtering rule operator. You can use this operator with following methods. ([#556](https://github.com/twitter-dart/twitter-api-v2/issues/556))
- `matchContext`
- `notMatchContext`

## v4.4.1

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import '../../../common/range.dart';
import '../../distance_unit.dart';
import '../operator/standalone/bounding_box.dart';
import '../operator/standalone/cashtag.dart';
import '../operator/standalone/context.dart';
import '../operator/standalone/conversation.dart';
import '../operator/standalone/country.dart';
import '../operator/standalone/entity.dart';
Expand Down Expand Up @@ -88,6 +89,12 @@ class StandaloneOperation {
RetweetedBy createNegatedRetweetedBy(final String user) =>
RetweetedBy.negated(user);

/// Returns the new instance of [Context] based on [value].
Context createContext(final String value) => Context(value);

/// Returns the new instance of negated [Context] based on [value].
Context createNegatedContext(final String value) => Context.negated(value);

/// Returns the new instance of [Entity] based on [value].
Entity createEntity(final String value) => Entity(value);

Expand Down
34 changes: 34 additions & 0 deletions lib/src/service/tweets/filtering/operator/standalone/context.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2022 Kato Shinya. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided the conditions.

// Project imports:
import '../operator.dart';
import '../validation_result.dart';

class Context extends Operator {
/// Returns the new instance of [Context].
const Context(
this.value, {
bool negated = false,
}) : super(negated);

factory Context.negated(final String value) => Context(value, negated: true);

/// The value
final String value;

@override
ValidationResult validate() {
if (value.isEmpty) {
return ValidationResult.failed(
'The context must not be an empty string.',
);
}

return ValidationResult.succeeded();
}

@override
String format() => 'context:$value';
}
28 changes: 28 additions & 0 deletions lib/src/service/tweets/filtering/syntax/standalone_syntax.dart
Original file line number Diff line number Diff line change
Expand Up @@ -264,6 +264,34 @@ abstract class StandaloneSyntax extends GroupSyntax {
_standaloneOperation.createNegatedRetweetedBy(user),
);

/// Matches Tweets with a specific domain id and/or domain id,
/// entity id pair where * represents a wildcard.
///
/// To learn more about this operator, please visit
/// [page on Tweet annotations](https://developer.twitter.com/en/docs/twitter-api/annotations/overview).
///
/// You can only pass a single domain/entity per this operator.
///
/// ## Parameters
///
/// - [value]: Context value to be matched.
///
/// ## Type
///
/// - [Standalone](https://developer.twitter.com/en/docs/twitter-api/tweets/filtered-stream/integrate/build-a-rule#types)
///
/// ## Availability
///
/// - Essential
LogicalChannel matchContext(final String value) => _buffer.appendOperator(
_standaloneOperation.createContext(value),
);

/// The negated representation of [matchEntity].
LogicalChannel notMatchContext(final String value) => _buffer.appendOperator(
_standaloneOperation.createNegatedContext(value),
);

/// Matches Tweets with a specific entity string value.
///
/// To learn more about this operator, please visit
Expand Down
15 changes: 15 additions & 0 deletions test/src/service/tweets/filtering/filtering_rule_test.dart
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,21 @@ void main() {
expect(actual.build(), '-retweets_of:test');
});

test('.matchContext', () {
final actual = FilteringRule.of().matchContext('domain_id.*');

expect(actual, isA<LogicalChannel>());
expect(actual.build(), 'context:domain_id.*');
});

test('.notMatchContext', () {
final actual =
FilteringRule.of().notMatchContext('10.799022225751871488');

expect(actual, isA<LogicalChannel>());
expect(actual.build(), '-context:10.799022225751871488');
});

test('.matchEntity', () {
final actual = FilteringRule.of().matchEntity('test aaa');

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@ import 'package:twitter_api_v2/src/service/tweets/distance_unit.dart';
import 'package:twitter_api_v2/src/service/tweets/filtering/operation/standalone_operation.dart';
import 'package:twitter_api_v2/src/service/tweets/filtering/operator/standalone/bounding_box.dart';
import 'package:twitter_api_v2/src/service/tweets/filtering/operator/standalone/cashtag.dart';
import 'package:twitter_api_v2/src/service/tweets/filtering/operator/standalone/context.dart';
import 'package:twitter_api_v2/src/service/tweets/filtering/operator/standalone/conversation.dart';
import 'package:twitter_api_v2/src/service/tweets/filtering/operator/standalone/country.dart';
import 'package:twitter_api_v2/src/service/tweets/filtering/operator/standalone/entity.dart';
import 'package:twitter_api_v2/src/service/tweets/filtering/operator/standalone/hashtag.dart';
import 'package:twitter_api_v2/src/service/tweets/filtering/operator/standalone/keyword.dart';
import 'package:twitter_api_v2/src/service/tweets/filtering/operator/standalone/place.dart';
Expand Down Expand Up @@ -147,6 +149,34 @@ void main() {
expect(actual.negated, isTrue);
});

test('.createContext', () {
final actual = StandaloneOperation().createContext('test');

expect(actual, isA<Context>());
expect(actual.negated, isFalse);
});

test('.createNegatedContext', () {
final actual = StandaloneOperation().createNegatedContext('test');

expect(actual, isA<Context>());
expect(actual.negated, isTrue);
});

test('.createEntity', () {
final actual = StandaloneOperation().createEntity('test');

expect(actual, isA<Entity>());
expect(actual.negated, isFalse);
});

test('.createNegatedEntity', () {
final actual = StandaloneOperation().createNegatedEntity('test');

expect(actual, isA<Entity>());
expect(actual.negated, isTrue);
});

test('.createConversation', () {
final actual = StandaloneOperation().createConversation('test');

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
// Copyright 2022 Kato Shinya. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided the conditions.

// Package imports:
import 'package:test/test.dart';
import 'package:twitter_api_v2/src/service/tweets/filtering/operator/standalone/context.dart';

void main() {
group('.toString', () {
test('with string value', () {
final actual = Context('10.799022225751871488');

expect(actual.toString(), 'context:10.799022225751871488');
});

test('when negated', () {
final actual = Context.negated('domain_id.*');

expect(actual.toString(), '-context:domain_id.*');
});

test('when value is empty', () {
final actual = Context('');

expect(
() => actual.toString(),
throwsA(
allOf(
isA<ArgumentError>(),
predicate(
(dynamic e) =>
e.message == 'The context must not be an empty string.',
),
),
),
);
});
});
}

0 comments on commit e83e11a

Please sign in to comment.