├── .github
├── action
│ └── publish_dart_package
│ │ └── action.yml
└── workflows
│ ├── dart.yml
│ └── publish.yml
├── .gitignore
├── .idea
├── kart.iml
├── libraries
│ ├── Dart_Packages.xml
│ └── Dart_SDK.xml
├── misc.xml
├── modules.xml
└── vcs.xml
├── .pubignore
├── CHANGELOG.md
├── LICENSE
├── README.md
├── analysis_options.yaml
├── example
└── kart_example.dart
├── kart.iml
├── lib
├── kart.dart
└── src
│ └── foundation
│ ├── cast.dart
│ ├── kt
│ ├── collections
│ │ ├── iterables.dart
│ │ ├── lists.dart
│ │ └── maps.dart
│ └── standard
│ │ └── standard.dart
│ ├── pair
│ └── pair.dart
│ └── string
│ └── strings.dart
├── pubspec.yaml
└── test
├── foundation
├── cast_test.dart
└── kt
│ ├── collections
│ ├── iterable_join_to_string_test.dart
│ ├── iterable_map_test.dart
│ ├── iterables_foreach_test.dart
│ ├── iterables_get_elements_test.dart
│ ├── iterables_test.dart
│ ├── list_test.dart
│ └── map
│ │ ├── maps_get_test.dart
│ │ └── nullable_map_test.dart
│ └── standard
│ └── standart_test.dart
├── kart_test.dart
├── pair
└── pair_test.dart
└── test_helper.dart
/.github/action/publish_dart_package/action.yml:
--------------------------------------------------------------------------------
1 | name: Publish Flutter package to pub.dev
2 | description: Publish your Flutter package to pub.dev
3 |
4 | inputs:
5 | working-directory:
6 | description: directory with-in the repository where the package is located (if not in the repository root)
7 | required: false
8 |
9 | runs:
10 | using: "composite"
11 | steps:
12 | - name: 📚 Git Checkout
13 | uses: actions/checkout@v4
14 | - name: 🐦 Setup Dart
15 | uses: dart-lang/setup-dart@v1
16 |
17 | - name: 🪪 Get Id Token
18 | uses: actions/github-script@v6
19 | with:
20 | script: |
21 | let pub_token = await core.getIDToken('https://pub.dev')
22 | core.exportVariable('PUB_TOKEN', pub_token)
23 |
24 | - name: 📢 Authenticate
25 | shell: ${{ inputs.shell }}
26 | run: dart pub token add https://pub.dev --env-var PUB_TOKEN
27 |
28 | - name: 📦 Install dependencies
29 | shell: ${{ inputs.shell }}
30 | run: dart pub get
31 | working-directory: ${{ inputs.working-directory }}
32 |
33 | # - name: 🌵 Dry Run
34 | # shell: ${{ inputs.shell }}
35 | # run: dart pub publish --dry-run
36 | # working-directory: ${{ inputs.working-directory }}
37 |
38 | - name: 📢 Publish
39 | shell: ${{ inputs.shell }}
40 | run: dart pub publish -f
41 | working-directory: ${{ inputs.working-directory }}
42 |
--------------------------------------------------------------------------------
/.github/workflows/dart.yml:
--------------------------------------------------------------------------------
1 | # This workflow uses actions that are not certified by GitHub.
2 | # They are provided by a third-party and are governed by
3 | # separate terms of service, privacy policy, and support
4 | # documentation.
5 |
6 | name: Dart
7 |
8 | on:
9 | push:
10 | branches: [ "main" ]
11 | pull_request:
12 | branches: [ "main" ]
13 |
14 | jobs:
15 | build:
16 | runs-on: ubuntu-latest
17 |
18 | steps:
19 | - uses: actions/checkout@v3
20 |
21 | # Note: This workflow uses the latest stable version of the Dart SDK.
22 | # You can specify other versions if desired, see documentation here:
23 | # https://github.com/dart-lang/setup-dart/blob/main/README.md
24 | # - uses: dart-lang/setup-dart@v1
25 | - uses: dart-lang/setup-dart@9a04e6d73cca37bd455e0608d7e5092f881fd603
26 |
27 | - name: Install dependencies
28 | run: dart pub get
29 |
30 | # Uncomment this step to verify the use of 'dart format' on each commit.
31 | # - name: Verify formatting
32 | # run: dart format --output=none --set-exit-if-changed .
33 |
34 | # Consider passing '--fatal-infos' for slightly stricter analysis.
35 | - name: Analyze project source
36 | run: dart analyze
37 |
38 | # Your project will need to have tests in test/ and a dependency on
39 | # package:test for this step to succeed. Note that Flutter projects will
40 | # want to change this to 'flutter test'.
41 | - name: Run tests
42 | run: dart test
43 |
--------------------------------------------------------------------------------
/.github/workflows/publish.yml:
--------------------------------------------------------------------------------
1 | name: Publish to pub.dev
2 |
3 | on:
4 | push:
5 | tags:
6 | - 'v[0-9]+.[0-9]+.[0-9]+*'
7 |
8 | jobs:
9 | publish:
10 | environment: 'pub.dev'
11 | permissions:
12 | id-token: write # Required for authentication using OIDC
13 | runs-on: ubuntu-latest
14 | steps:
15 | - name: 📚 Git Checkout
16 | uses: actions/checkout@v4
17 | with:
18 | submodules: recursive
19 | - uses: ./.github/action/publish_dart_package
20 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Files and directories created by pub.
2 | .dart_tool/
3 | .packages
4 |
5 | # Conventional directory for build outputs.
6 | build/
7 |
8 | # Omit committing pubspec.lock for library packages; see
9 | # https://dart.dev/guides/libraries/private-files#pubspeclock.
10 | pubspec.lock
11 | .idea/workspace.xml
--------------------------------------------------------------------------------
/.idea/kart.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/.idea/libraries/Dart_Packages.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
328 |
329 |
330 |
331 |
332 |
333 |
334 |
335 |
336 |
337 |
338 |
339 |
340 |
341 |
342 |
343 |
344 |
345 |
346 |
347 |
348 |
349 |
350 |
351 |
352 |
353 |
354 |
355 |
356 |
357 |
358 |
359 |
360 |
361 |
362 |
363 |
364 |
365 |
366 |
367 |
368 |
369 |
370 |
371 |
372 |
373 |
374 |
375 |
376 |
377 |
378 |
379 |
380 |
--------------------------------------------------------------------------------
/.idea/libraries/Dart_SDK.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
--------------------------------------------------------------------------------
/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/.pubignore:
--------------------------------------------------------------------------------
1 | # Files and directories created by pub.
2 | .dart_tool/
3 | .packages
4 |
5 | # Conventional directory for build outputs.
6 | build/
7 |
8 | # Omit committing pubspec.lock for library packages; see
9 | # https://dart.dev/guides/libraries/private-files#pubspeclock.
10 | pubspec.lock
11 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # 1.0.9
2 | * Override toString and `==` for Pair.
3 |
4 | # 1.0.8
5 | * orEmpty for List and Map.
6 |
7 | # 1.0.7
8 | * firstNotNullOfOrNull for iterable.
9 |
10 | ## 1.0.6
11 | * joinToString for iterable.
12 |
13 | ## 1.0.5
14 | * fistOrNullIf, lastOrNullIf for List and Iterable.
15 |
16 | ## 1.0.4+1
17 | * Fix mapNotNull issue.
18 |
19 | ## 1.0.4
20 | * Fix let issue.
21 | * Add takeUnless.
22 |
23 | ## 1.0.3
24 | * Add getOrElse for map.
25 |
26 | ## 1.0.2+1
27 | * Fix mapIndex return -1 issue.
28 |
29 | ## 1.0.2
30 | * support mapIndexed and mapNotNull.
31 |
32 | ## 1.0.1
33 | * support lastIndex, getOrElse and getOrNull for iterables.
34 |
35 | ## 1.0.0
36 |
37 | - Initial version.
38 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [2022] [OpenFlutter]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ### Collection of extensions
2 |
3 | Dart is good but can be better.
4 |
5 | ## Kotlin Style
6 |
7 | > Join QQ Group now: 1003811176
8 |
9 | For objects:
10 |
11 | - `let`
12 | - `run`
13 | - `also`
14 | - `takeIf`
15 | - `takeUnless`
16 |
17 | For strings:
18 |
19 | - `isBlank()`
20 | - `isNotBlank()`
21 | - `isNullOrBlank()`
22 | - `orEmpty()`
23 |
24 | For iterable
25 |
26 | - `firstOrNull()`
27 | - `lastOrNull()`
28 | - `lastIndex`
29 | - `getOrElse(int,defaultValue)`
30 | - `getOrNull(int)`
31 | - `mapIndexed(int,element)`
32 | - `mapNotNull(element)`
33 | - `firstOrNullIf(predicate)`
34 | - `lastOrNullIf(predicate)`
35 | - `forEachIndexed(index,element)`
36 | - `joinToString`
37 |
38 | For List
39 |
40 | - `firstOrNullIf(predicate)`
41 | - `lastOrNullIf(predicate)`
42 |
43 | For map
44 | - `getOrElse(key,defaultValue)`
45 | -
46 | ## Other
47 |
48 |
49 | `Pair`
50 |
--------------------------------------------------------------------------------
/analysis_options.yaml:
--------------------------------------------------------------------------------
1 | # This file configures the static analysis results for your project (errors,
2 | # warnings, and lints).
3 | #
4 | # This enables the 'recommended' set of lints from `package:lints`.
5 | # This set helps identify many issues that may lead to problems when running
6 | # or consuming Dart code, and enforces writing Dart using a single, idiomatic
7 | # style and format.
8 | #
9 | # If you want a smaller set of lints you can change this to specify
10 | # 'package:lints/core.yaml'. These are just the most critical lints
11 | # (the recommended set includes the core lints).
12 | # The core lints are also what is used by pub.dev for scoring packages.
13 |
14 | include: package:lints/recommended.yaml
15 |
16 | # Uncomment the following section to specify additional rules.
17 |
18 | # linter:
19 | # rules:
20 | # - camel_case_types
21 |
22 | # analyzer:
23 | # exclude:
24 | # - path/to/excluded/files/**
25 |
26 | # For more information about the core and recommended set of lints, see
27 | # https://dart.dev/go/core-lints
28 |
29 | # For additional information about configuring this file, see
30 | # https://dart.dev/guides/language/analysis-options
31 |
--------------------------------------------------------------------------------
/example/kart_example.dart:
--------------------------------------------------------------------------------
1 | void main() {
2 |
3 | }
4 |
--------------------------------------------------------------------------------
/kart.iml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
--------------------------------------------------------------------------------
/lib/kart.dart:
--------------------------------------------------------------------------------
1 | /// Support for doing something awesome.
2 | ///
3 | /// More dartdocs go here.
4 | library kart;
5 |
6 | export 'src/foundation/kt/standard/standard.dart';
7 | export 'src/foundation/kt/collections/iterables.dart';
8 | export 'src/foundation/kt/collections/maps.dart';
9 | export 'src/foundation/kt/collections/lists.dart';
10 | export 'src/foundation/cast.dart';
11 | export 'src/foundation/pair/pair.dart';
12 | export 'src/foundation/string/strings.dart';
13 |
--------------------------------------------------------------------------------
/lib/src/foundation/cast.dart:
--------------------------------------------------------------------------------
1 | extension CastExtension on T {
2 | R castTo() {
3 | return this as R;
4 | }
5 |
6 | ///cast object to R.
7 | ///returns R if it is R, otherwise null.
8 | R? safeCastTo() {
9 | if (this is R) {
10 | return this as R;
11 | } else {
12 | return null;
13 | }
14 | }
15 | }
16 |
--------------------------------------------------------------------------------
/lib/src/foundation/kt/collections/iterables.dart:
--------------------------------------------------------------------------------
1 | class IndexedValue {
2 | int index;
3 | T value;
4 |
5 | IndexedValue(this.index, this.value);
6 |
7 | @override
8 | String toString() {
9 | return "[$index]{$value}";
10 | }
11 | }
12 |
13 | extension KtIterableExtension on Iterable {
14 | Iterable whereNot(bool Function(E it) test) => where((it) => !test(it));
15 |
16 | /// returns first element or [null]
17 | ///
18 | /// if `this` is is [null] or empty returns [null].
19 | ///
20 | /// Example:
21 | /// ```dart
22 | /// var result = [].firstOrNull() // null
23 | /// var result = [1,2,3].firstOrNull() // 1
24 | E? firstOrNull() => isEmpty ? null : first;
25 |
26 | ///
27 | /// Returns the first element matching the given [predicate], or null if element was not found.
28 | ///
29 | /// Example:
30 | /// ```dart
31 | /// {"Ada", "James", "Harden", "Bob", "Jane"}.firstOrNullIf((it) => it.length == 9); // null
32 | /// {"Ada", "James", "Harden", "Bob", "Jane"}.firstOrNullIf((it) => it.length == 4); // Jane
33 | /// ```
34 | ///
35 | E? firstOrNullIf(bool Function(E it) predicate) {
36 | for (var item in this) {
37 | if (predicate(item)) {
38 | return item;
39 | }
40 | }
41 |
42 | return null;
43 | }
44 |
45 | /// returns last element or [null]
46 | ///
47 | /// if `this` is is [null] or empty returns [null].
48 | ///
49 | /// Example:
50 | /// ```dart
51 | /// var result = [].lastOrNull() // null
52 | /// var result = [1,2,3].lastOrNull() // 3
53 | /// ```
54 | E? lastOrNull() => isEmpty ? null : last;
55 |
56 | ///
57 | /// Returns the last element matching the given [predicate], or null if element was not found.
58 | ///
59 | /// Example:
60 | /// ```dart
61 | /// {"Ada", "James", "Harden", "Bob", "Jane"}.lastOrNullIf((it) => it.length == 9); // null
62 | /// {"Ada", "James", "Harden", "Bob", "Jane"}.lastOrNullIf((it) => it.length == 3); // Bob
63 | /// ```
64 | ///
65 | E? lastOrNullIf(bool Function(E it) predicate) {
66 | Iterator it = iterator;
67 | if (!it.moveNext()) {
68 | return null;
69 | }
70 | E? result;
71 | do {
72 | if (predicate(it.current)) {
73 | result = it.current;
74 | }
75 | } while (it.moveNext());
76 | return result;
77 | }
78 |
79 | /// Returns the index of the last item in the list or -1 if the list is empty.
80 | ///
81 | /// Example:
82 | ///
83 | /// ```dart
84 | /// var result = [1,2,3].lastIndex // 2
85 | /// var result = [].lastIndex // -1
86 | ///
87 | int get lastIndex => length - 1;
88 | }
89 |
90 | extension KtNullabeIterableExtension on Iterable? {
91 | Iterable orEmpty() => this ?? Iterable.empty();
92 | }
93 |
94 | typedef IterableFallbackElement = T Function(int);
95 |
96 | extension GetElementsForIterable on Iterable {
97 | /// Returns an element at the given index or the result of calling the [defaultValue] function if the index is out of bounds of this list.
98 | ///
99 | /// Example:
100 | /// ```dart
101 | /// Iterable iterables = [1, 2, 3, 4];
102 | /// var result = iterables.getOrElse(6, (index) => 66); // 66
103 | ///
104 | /// Iterable iterables = [1, 2, 3, 4];
105 | /// var result = iterables.getOrElse(1, (index) => 66); // 2
106 | /// ```
107 | E getOrElse(int index, E Function(int) defaultValue) {
108 | if (index >= 0 && index <= lastIndex) {
109 | return elementAt(index);
110 | } else {
111 | return defaultValue(index);
112 | }
113 | }
114 |
115 | /// Returns an element at the given index or null if the index is out of bounds of this list.
116 | ///
117 | /// Example:
118 | /// ```dart
119 | /// Iterable iterables = [1, 2, 3, 4];
120 | /// var result = iterables.getOrNull(6); // null
121 | ///
122 | /// Iterable iterables = [1, 2, 3, 4];
123 | /// var result = iterables.getOrNull(1); // 2
124 | /// ```
125 | ///
126 | E? getOrNull(int index) {
127 | if (index >= 0 && index <= lastIndex) {
128 | return elementAt(index);
129 | } else {
130 | return null;
131 | }
132 | }
133 |
134 | /// Returns the first non-null value produced by [transform] function being applied to elements of this
135 | /// collection in iteration order, or null if no non-null value was produced.
136 | /// Example:
137 | /// ```dart
138 | /// Iterable iterables = ["Ada", "John", "James", "Linda"];
139 | /// var result = iterables.firstNotNullOfOrNull(transform: (e) {
140 | /// if (e == "James") {
141 | /// return 1;
142 | /// } else {
143 | /// return null;
144 | /// }
145 | /// }); // result is 1
146 | ///
147 | /// int? result = iterables.firstNotNullOfOrNull(transform: (e) {
148 | /// if (e == "Arthur") {
149 | /// return 2;
150 | /// } else {
151 | /// return null;
152 | /// }
153 | /// }); //result is null
154 | ///
155 | R? firstNotNullOfOrNull(
156 | {required R? Function(E e) transform}) {
157 | for (var element in this) {
158 | var result = transform(element);
159 | if (result != null) {
160 | return result;
161 | }
162 | }
163 |
164 | return null;
165 | }
166 | }
167 |
168 | extension MapForIterable on Iterable {
169 | ///Returns a list containing the results of applying the given transform function to each element and its index in the original collection.
170 | /// Params:
171 | /// [transform] - function that takes the index of an element and the element itself and returns the result of the transform applied to the element.
172 | ///
173 | /// Example:
174 | ///```dart
175 | /// Iterable iterables = [1, 2, 3, 4];
176 | /// var result = iterables.mapIndexed((index, element) => "$index$element"); // ["01", "12", "23", "34"]
177 | ///
178 | /// Set iterables = {1, 2, 3, 4};
179 | /// var result = iterables.mapIndexed((index, element) => "$index$element"); // ["01", "12", "23", "34"]
180 | /// ```
181 | Iterable mapIndexed(R Function(int index, E e) transform) {
182 | if (this is List) {
183 | List list = this as List;
184 | return map((e) => transform(list.indexOf(e), e));
185 | }
186 | var tempList = toList();
187 | return tempList.map((e) => transform(tempList.indexOf(e), e));
188 | }
189 |
190 | ///Returns a list containing only the non-null results of applying the given transform function to each element in the original collection.
191 | ///
192 | /// Example:
193 | ///
194 | /// ```dart
195 | /// [1, 2, null, 3, 4, null].mapNotNull((e) => e?.toString()) // ["1", "2", "3", "4"]
196 | ///
197 | /// [1, 5, 3, 4].mapNotNull((e) => "$e") // ["1", "5", "3", "4"]
198 | ///```
199 | ///
200 | Iterable mapNotNull(R? Function(E? e) transform) {
201 | var resultList = [];
202 | forEach((element) {
203 | final item = transform(element);
204 | if (item != null) {
205 | resultList.add(item);
206 | }
207 | });
208 |
209 | return resultList;
210 | }
211 | }
212 |
213 | extension ForEachOnIterable on Iterable {
214 | ///
215 | /// Performs the given [action] on each element, providing sequential index with the element.
216 | /// Params:
217 | /// [action] - function that takes the index of an element and the element itself and performs the action on the element.
218 | ///
219 | /// Example:
220 | ///
221 | /// ```dart
222 | /// Iterable list = ["James", "Morgan", "Bon"];
223 | /// List result = [];
224 | /// list.forEachIndexed((index, element) => result.add("$index$element")); // ["James", "Morgan", "Bon"]
225 | /// ```
226 | forEachIndexed(Function(int index, E element) action) {
227 | var i = 0;
228 | for (final e in this) {
229 | action(i++, e);
230 | }
231 | }
232 | }
233 |
234 | extension IterableJoinToString on Iterable {
235 | /// Appends the string from all the elements separated using separator and using the given [prefix] and [postfix] if supplied.
236 | /// If the collection could be huge, you can specify a non-negative value of [limit], in which case only the first limit elements will be appended,
237 | /// followed by the [truncated] string (which defaults to "...").
238 | ///
239 | /// Example:
240 | ///
241 | /// ```dart
242 | /// final result = [1, 2, 3, 4, 5].joinToString(); // 1, 2, 3, 4, 5
243 | ///
244 | /// final result = [1, 2, 3, 4, 5].joinToString(
245 | /// separator: ".",
246 | /// prefix: "prefix",
247 | /// postfix: "postfix",
248 | /// transform: (e) => "${e + 1}"); // prefix2.3.4.5.6postfix
249 | ///
250 | /// final result = [1, 2, 3, 4, 5].joinToString(
251 | /// limit: 4,
252 | /// truncated: "^^^"); // 1, 2, 3, 4, ^^^
253 | /// ```
254 |
255 | String joinToString({
256 | String separator = ', ',
257 | String Function(E element)? transform,
258 | String prefix = '',
259 | String postfix = '',
260 | int limit = -1,
261 | String truncated = '...',
262 | }) {
263 | final buffer = StringBuffer();
264 | var count = 0;
265 |
266 | buffer.write(prefix);
267 | for (final element in this) {
268 | if (++count > 1) buffer.write(separator);
269 | if (limit < 0 || count <= limit) {
270 | if (transform != null) {
271 | buffer.write(transform(element));
272 | } else {
273 | buffer.write(element.toString());
274 | }
275 | } else {
276 | break;
277 | }
278 | }
279 |
280 | if (limit >= 0 && count > limit) {
281 | buffer.write(truncated);
282 | }
283 |
284 | buffer.write(postfix);
285 | return buffer.toString();
286 | }
287 | }
288 |
--------------------------------------------------------------------------------
/lib/src/foundation/kt/collections/lists.dart:
--------------------------------------------------------------------------------
1 | extension ElementsOnList on List {
2 | ///
3 | /// Returns the first element matching the given [predicate], or null if element was not found.
4 | ///
5 | /// Example:
6 | /// ```dart
7 | /// {"Ada", "James", "Harden", "Bob", "Jane"}.firstOrNullIf((it) => it.length == 9); // null
8 | /// {"Ada", "James", "Harden", "Bob", "Jane"}.firstOrNullIf((it) => it.length == 4); // Jane
9 | /// ```
10 | ///
11 | E? firstOrNullIf(bool Function(E it) predicate) {
12 | int length = this.length;
13 | for (int i = 0; i < length; i++) {
14 | E element = this[i];
15 | if (predicate(element)) return element;
16 | if (length != this.length) {
17 | throw ConcurrentModificationError(this);
18 | }
19 | }
20 | return null;
21 | }
22 |
23 | ///
24 | /// Returns the last element matching the given [predicate], or null if element was not found.
25 | ///
26 | /// Example:
27 | /// ```dart
28 | /// ["Ada", "James", "Harden", "Bob", "Jane"].lastOrNullIf((it) => it.length == 9); // null
29 | /// ["Ada", "James", "Harden", "Bob", "Jane"].lastOrNullIf((it) => it.length == 3); // Bob
30 | /// ```
31 | ///
32 | E? lastOrNullIf(bool Function(E it) predicate) {
33 | int length = this.length;
34 | for (int i = length - 1; i >= 0; i--) {
35 | E element = this[i];
36 | if (predicate(element)) return element;
37 | if (length != this.length) {
38 | throw ConcurrentModificationError(this);
39 | }
40 | }
41 | return null;
42 | }
43 | }
44 |
45 | extension KtNullableListExtension on List? {
46 | /// Returns this List if it's not null and the empty list otherwise.
47 | ///
48 | /// Example:
49 | /// ```dart
50 | /// List? list;
51 | /// var result = list.orEmpty(); // []
52 | /// List? list = ["Ada"];
53 | /// var result = list.orEmpty(); // ["Ada"]
54 | /// ```
55 | List orEmpty() => this ?? [];
56 | }
57 |
--------------------------------------------------------------------------------
/lib/src/foundation/kt/collections/maps.dart:
--------------------------------------------------------------------------------
1 | extension KtMapGetExtension on Map {
2 | ///Returns the value for the given key, or the result of the [defaultValue] function if there was no entry for the given key.
3 | ///
4 | /// Example:
5 | ///
6 | /// ```dart
7 | /// var map = {
8 | /// "test1": 1,
9 | /// "test2": 2,
10 | /// };
11 | /// var result = map.getOrElse("test3", () => 3); // 3
12 | ///
13 | /// var map = {
14 | /// "test1": 1,
15 | /// "test2": 2,
16 | /// };
17 | /// var result = map.getOrElse("test1", () => 3); // 1
18 | ///
19 | /// ```
20 | V getOrElse(K key, V Function() defaultValue) {
21 | return this[key] ?? defaultValue();
22 | }
23 | }
24 |
25 | extension KtNullableMapExtension on Map? {
26 | /// Returns the Map if its not null, or the empty Map otherwise.
27 | ///
28 | /// Example:
29 | /// ```dart
30 | /// Map? map ;
31 | /// var result = map.orEmpty(); // {}
32 | /// Map? map = {
33 | /// "lan":"dart"
34 | /// };
35 | /// var result = map.orEmpty(); // {"lan":"dart"}
36 | /// ```
37 | Map orEmpty() => this ?? {};
38 | }
39 |
--------------------------------------------------------------------------------
/lib/src/foundation/kt/standard/standard.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022. OpenFlutter Project
3 | *
4 | * Licensed to the Apache Software Foundation (ASF) under one or more contributor
5 | * license agreements. See the NOTICE file distributed with this work for
6 | * additional information regarding copyright ownership. The ASF licenses this
7 | * file to you under the Apache License, Version 2.0 (the "License"); you may not
8 | * use this file except in compliance with the License. You may obtain a copy of
9 | * the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16 | * License for the specific language governing permissions and limitations under
17 | * the License.
18 | */
19 |
20 | extension KtStandardExtension on T {
21 | /// Calls the specified function [block] with this value as its argument and returns its result.
22 | /// Example:
23 | ///
24 | /// ```dart
25 | /// String? str;
26 | /// var result = str?.let((self) {
27 | /// return self.isNotEmpty;
28 | /// }); // null
29 | /// ```
30 | ///
31 | R let(R Function(T self) block) {
32 | return block(this);
33 | }
34 |
35 | T apply(void Function() block) {
36 | block();
37 | return this;
38 | }
39 |
40 | R also(R Function(T self) func) {
41 | return func(this);
42 | }
43 |
44 | R run(R Function() func) {
45 | return func();
46 | }
47 |
48 | T? takeIf(bool Function(T self) predicate) {
49 | if (predicate(this)) {
50 | return this;
51 | } else {
52 | return null;
53 | }
54 | }
55 |
56 | /// Returns this value if it does not satisfy the given predicate or null, if it does.
57 | ///
58 | /// Example:
59 | ///
60 | /// ```dart
61 | /// "James".takeUnless((self) => self == "Tom"); // James
62 | /// "James".takeUnless((self) => self == "James"); // null
63 | ///
64 | /// ```
65 | T? takeUnless(bool Function(T self) predicate) {
66 | if (!predicate(this)) {
67 | return this;
68 | } else {
69 | return null;
70 | }
71 | }
72 | }
73 |
74 | extension KtStandardExtension2 on T {}
75 |
76 | ///Executes the given function action specified number of times.
77 | /// A zero-based index of current iteration is passed as a parameter to action.
78 | repeat(int times, Function(int index) action) {
79 | for (int index = 0; index < times; index++) {
80 | action(index);
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/lib/src/foundation/pair/pair.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022. OpenFlutter Project
3 | *
4 | * Licensed to the Apache Software Foundation (ASF) under one or more contributor
5 | * license agreements. See the NOTICE file distributed with this work for
6 | * additional information regarding copyright ownership. The ASF licenses this
7 | * file to you under the Apache License, Version 2.0 (the "License"); you may not
8 | * use this file except in compliance with the License. You may obtain a copy of
9 | * the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16 | * License for the specific language governing permissions and limitations under
17 | * the License.
18 | */
19 | class Pair {
20 | final F first;
21 | final S second;
22 |
23 | const Pair(this.first, this.second);
24 | @override
25 | bool operator ==(Object other) =>
26 | identical(this, other) ||
27 | other is Pair &&
28 | runtimeType == other.runtimeType &&
29 | first == other.first &&
30 | second == other.second;
31 |
32 | @override
33 | int get hashCode => first.hashCode ^ second.hashCode;
34 |
35 | @override
36 | String toString() => 'Pair($first, $second)';
37 | }
38 |
39 | /// create pair for given elements first and second.
40 | ///
41 | Pair pairOf(F first, S second) {
42 | return Pair(first, second);
43 | }
44 |
--------------------------------------------------------------------------------
/lib/src/foundation/string/strings.dart:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022. OpenFlutter Project
3 | *
4 | * Licensed to the Apache Software Foundation (ASF) under one or more contributor
5 | * license agreements. See the NOTICE file distributed with this work for
6 | * additional information regarding copyright ownership. The ASF licenses this
7 | * file to you under the Apache License, Version 2.0 (the "License"); you may not
8 | * use this file except in compliance with the License. You may obtain a copy of
9 | * the License at
10 | *
11 | * http://www.apache.org/licenses/LICENSE-2.0
12 | *
13 | * Unless required by applicable law or agreed to in writing, software
14 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16 | * License for the specific language governing permissions and limitations under
17 | * the License.
18 | */
19 |
20 | extension NullableStringExtension on String? {
21 | /// returns true when given string is null or empty.
22 | bool isNullOrBlank() {
23 | return this?.trim().isEmpty ?? true;
24 | }
25 |
26 | /// returns "" if null.
27 | String orEmpty() {
28 | return this ?? "";
29 | }
30 | }
31 |
32 | extension StringExtension on String {
33 | bool isBlank() {
34 | return trim().isEmpty;
35 | }
36 |
37 | bool isNotBlank() => !isBlank();
38 | }
39 |
--------------------------------------------------------------------------------
/pubspec.yaml:
--------------------------------------------------------------------------------
1 | name: kart
2 | description: Taste and smell dart a little like Kotlin. We can feel magic of Kotin even in dart.
3 | version: 1.0.9
4 | homepage: https://github.com/OpenFlutter/kart
5 |
6 | environment:
7 | sdk: '>=2.16.2 <4.0.0'
8 |
9 |
10 | # dependencies:
11 | # path: ^1.8.0
12 |
13 | dev_dependencies:
14 | lints: ^1.0.0
15 | test: ^1.16.0
16 |
--------------------------------------------------------------------------------
/test/foundation/cast_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:kart/kart.dart';
2 | import 'package:test/test.dart';
3 |
4 | void main() {
5 | group('cast test', () {
6 | test("cast", () {
7 | Iterable hi = [""];
8 | List map = hi.castTo();
9 | expect(map.runtimeType, List);
10 | });
11 |
12 | test("safe cast", () {
13 | int a = 1;
14 | expect(a.safeCastTo(), null);
15 | });
16 | });
17 | }
18 |
--------------------------------------------------------------------------------
/test/foundation/kt/collections/iterable_join_to_string_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:kart/kart.dart';
2 | import 'package:test/test.dart';
3 |
4 | void main() {
5 | group('iterable joinToString test', () {
6 | test("joinToString Default", () {
7 | final result = [1, 2, 3, 4, 5].joinToString();
8 | expect(result, "1, 2, 3, 4, 5");
9 | });
10 |
11 | test("joinToString withNullable", () {
12 | final result = [1, 2, 3, 4, 5, null].joinToString();
13 | expect(result, "1, 2, 3, 4, 5, null");
14 | });
15 |
16 | test("joinToString ", () {
17 | final result = [1, 2, 3, 4, 5].joinToString(
18 | separator: ".",
19 | prefix: "prefix",
20 | postfix: "postfix",
21 | transform: (e) => "${e + 1}",
22 | );
23 | expect(result, "prefix2.3.4.5.6postfix");
24 | });
25 |
26 | test("joinToString truncated", () {
27 | final result = [1, 2, 3, 4, 5].joinToString(limit: 4, truncated: "^^^");
28 | expect(result, "1, 2, 3, 4, ^^^");
29 | });
30 | });
31 | }
32 |
--------------------------------------------------------------------------------
/test/foundation/kt/collections/iterable_map_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:kart/kart.dart';
2 | import 'package:test/test.dart';
3 |
4 | void main() {
5 | group('iterable mapIndex test', () {
6 | test("mapIndex List Expected Correct", () {
7 | Iterable<_MapTestObject> iterables = [
8 | _MapTestObject("1"),
9 | _MapTestObject("2"),
10 | _MapTestObject("3"),
11 | _MapTestObject("4"),
12 | ];
13 | var result = iterables
14 | .mapIndexed((index, element) => "$index${element.identifier}");
15 |
16 | expect(result, ["01", "12", "23", "34"]);
17 | });
18 |
19 | test("mapIndex NotList Expected Correct", () {
20 | Set<_MapTestObject> iterables = {
21 | _MapTestObject("1"),
22 | _MapTestObject("2"),
23 | _MapTestObject("3"),
24 | _MapTestObject("4"),
25 | };
26 | var result = iterables
27 | .mapIndexed((index, element) => "$index${element.identifier}");
28 |
29 | expect(result, ["01", "12", "23", "34"]);
30 | });
31 | });
32 |
33 | group('iterable mapNotNull test', () {
34 | test("mapNotNull containsNull Expected Correct", () {
35 | Iterable iterables = [1, 2, null, 3, 4, null];
36 | var result = iterables.mapNotNull((e) => e?.toString());
37 |
38 | expect(result, ["1", "2", "3", "4"]);
39 | });
40 |
41 | test("mapNotNull NotContainsNull Expected Correct", () {
42 | Iterable iterables = [1, 5, 3, 4];
43 | var result = iterables.mapNotNull((e) => "$e");
44 |
45 | expect(result, ["1", "5", "3", "4"]);
46 | });
47 | });
48 | }
49 |
50 | class _MapTestObject {
51 | final String identifier;
52 |
53 | _MapTestObject(this.identifier);
54 | }
55 |
--------------------------------------------------------------------------------
/test/foundation/kt/collections/iterables_foreach_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:kart/kart.dart';
2 | import 'package:test/test.dart';
3 |
4 | void main() {
5 | group('iterable forEach test', () {
6 | test("forEachIndexed SourceEmpty ResultEmpty", () {
7 | Iterable list = [];
8 | List result = [];
9 | list.forEachIndexed((index, element) => result.add("$index$element"));
10 | expect(result, containsAll([]));
11 | });
12 |
13 | test("forEachIndexed HasSource CombinedResult", () {
14 | Iterable list = ["James", "Morgan", "Bon"];
15 | List result = [];
16 | list.forEachIndexed((index, element) => result.add("$index$element"));
17 | expect(result, containsAll(["0James", "1Morgan", "2Bon"]));
18 | });
19 | });
20 | }
21 |
--------------------------------------------------------------------------------
/test/foundation/kt/collections/iterables_get_elements_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:kart/kart.dart';
2 | import 'package:test/test.dart';
3 |
4 | void main() {
5 | group('iterable get elements test', () {
6 | test("getOrElse Expected DefaultValue", () {
7 | Iterable iterables = [1, 2, 3, 4];
8 | var result = iterables.getOrElse(6, (index) => 66);
9 | expect(result, 66);
10 | });
11 |
12 | test("getOrElse Expected CorrectValue", () {
13 | Iterable iterables = [1, 2, 3, 4];
14 | var result = iterables.getOrElse(1, (index) => 66);
15 | expect(result, 2);
16 | });
17 |
18 | test("getOrNull Expected null", () {
19 | Iterable iterables = [1, 2, 3, 4];
20 | var result = iterables.getOrNull(6);
21 | expect(result, null);
22 | });
23 |
24 | test("getOrNull Expected CorrectValue", () {
25 | Iterable iterables = [1, 2, 3, 4];
26 | var result = iterables.getOrNull(1);
27 | expect(result, 2);
28 | });
29 | });
30 |
31 | group("firstNotNullOfOrNull", () {
32 | test("non-null value was produced | return 1", () {
33 | Iterable iterables = ["Ada", "John", "James", "Linda"];
34 |
35 | var result = iterables.firstNotNullOfOrNull(transform: (e) {
36 | if (e == "James") {
37 | return 1;
38 | } else {
39 | return null;
40 | }
41 | });
42 |
43 | expect(result, 1);
44 | });
45 |
46 | test("no non-null value was produced | return null", () {
47 | Iterable iterables = ["Ada", "John", "James", "Linda"];
48 |
49 | int? result = iterables.firstNotNullOfOrNull(transform: (e) {
50 | if (e == "Arthur") {
51 | return null;
52 | } else {
53 | return null;
54 | }
55 | });
56 |
57 | expect(result, null);
58 | });
59 | });
60 | }
61 |
--------------------------------------------------------------------------------
/test/foundation/kt/collections/iterables_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:kart/kart.dart';
2 | import 'package:test/test.dart';
3 |
4 | void main() {
5 | group('iterables test', () {
6 | test("iterables orEmpty not empty", () {
7 | List list = ["test"];
8 | expect(list.orEmpty().isEmpty, false);
9 | });
10 |
11 | test("iterables orEmpty empty", () {
12 | List? list;
13 | expect(list.orEmpty().isEmpty, true);
14 | });
15 | });
16 |
17 | group('no-nullable test firstOrNull', () {
18 | test("first not null", () {
19 | Iterable list = ["test", "test1"];
20 | expect(list.firstOrNull(), "test");
21 | });
22 |
23 | test("first null", () {
24 | Iterable list = [];
25 | expect(list.firstOrNull(), null);
26 | });
27 | });
28 |
29 | group('no-nullable iterables test lastOrNull', () {
30 | test("last not null", () {
31 | Iterable list = ["test", "test1"];
32 | expect(list.lastOrNull(), "test1");
33 | });
34 |
35 | test("last null", () {
36 | Iterable list = [];
37 | expect(list.lastOrNull(), null);
38 | });
39 | });
40 |
41 | group('nullable test firstOrNull', () {
42 | test("not empty nullable-iterable expect first element not null", () {
43 | Iterable? list = ["test", "test1"];
44 | expect(list.firstOrNull(), "test");
45 | });
46 |
47 | test("empty nullable-iterable expect first element null", () {
48 | Iterable? list = [];
49 | expect(list.firstOrNull(), null);
50 | });
51 | });
52 |
53 | group('nullable test lastOrNull', () {
54 | test("not empty null-iterable expect last element not null", () {
55 | Iterable? list = ["test", "test1"];
56 | expect(list.lastOrNull(), "test1");
57 | });
58 |
59 | test("empty nullable-iterable expect last element null", () {
60 | Iterable? list = [];
61 | expect(list.lastOrNull(), null);
62 | });
63 | });
64 |
65 | group('test firstOrNullIf', () {
66 | test("firstOrNullIf nameLengthIs3 ExpectJane", () {
67 | Iterable? names = {"Ada", "James", "Harden", "Bob", "Jane"};
68 | var result = names.firstOrNullIf((it) => it.length == 4);
69 | expect(result, "Jane");
70 | });
71 |
72 | test("firstOrNullIf nameLengthIs8 ExpectNull", () {
73 | Iterable? names = {"Ada", "James", "Harden", "Bob", "Jane"};
74 | var result = names.firstOrNullIf((it) => it.length == 9);
75 | expect(result, null);
76 | });
77 | });
78 |
79 | group('test lastOrNullIf', () {
80 | test("lastOrNullIf nameLengthIs3 ExpectBob", () {
81 | Iterable? names = {"Ada", "Jame", "Harden", "Bob", "Jane"};
82 | var result = names.lastOrNullIf((it) => it.length == 3);
83 | expect(result, "Bob");
84 | });
85 |
86 | test("lastOrNullIf nameLengthIs9 ExpectNull", () {
87 | Iterable? names = {"Ada", "Jame", "Harden", "Bob", "Jane"};
88 | var result = names.lastOrNullIf((it) => it.length == 9);
89 | expect(result, null);
90 | });
91 | });
92 |
93 | group('iterable lastIndex test', () {
94 | test("lastIndex is Correct", () {
95 | Iterable list = ["test", "abc", "dart"];
96 | var result = list.lastIndex;
97 | expect(result, 2);
98 | });
99 |
100 | test("lastIndex is -1", () {
101 | Iterable list = [];
102 | var result = list.lastIndex;
103 | expect(result, -1);
104 | });
105 | });
106 | }
107 |
--------------------------------------------------------------------------------
/test/foundation/kt/collections/list_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:kart/kart.dart';
2 | import 'package:test/test.dart';
3 |
4 | void main() {
5 | group('test firstOrNullIf', () {
6 | test("firstOrNullIf nameLengthIs3 ExpectJane", () {
7 | List? names = ["Ada", "James", "Harden", "Bob", "Jane"];
8 | var result = names.firstOrNullIf((it) => it.length == 4);
9 | expect(result, "Jane");
10 | });
11 |
12 | test("firstOrNullIf nameLengthIs8 ExpectNull", () {
13 | List? names = ["Ada", "James", "Harden", "Bob", "Jane"];
14 | var result = names.firstOrNullIf((it) => it.length == 9);
15 | expect(result, null);
16 | });
17 | });
18 |
19 | group('test lastOrNullIf', () {
20 | test("lastOrNullIf nameLengthIs3 ExpectBob", () {
21 | List? names = ["Ada", "James", "Harden", "Bob", "Jane"];
22 | var result = names.lastOrNullIf((it) => it.length == 3);
23 | expect(result, "Bob");
24 | });
25 |
26 | test("lastOrNullIf nameLengthIs9 ExpectNull", () {
27 | List? names = ["Ada", "James", "Harden", "Bob", "Jane"];
28 | var result = names.lastOrNullIf((it) => it.length == 9);
29 | expect(result, null);
30 | });
31 | });
32 |
33 | group("nullable list", () {
34 | test("orEmpty | given list is null | returns empty", () {
35 | List? list;
36 | var result = list.orEmpty();
37 | expect(result, []);
38 | });
39 |
40 | test("orEmpty | given list is not null | returns self", () {
41 | List? list = ["Ada"];
42 | var result = list.orEmpty();
43 | expect(result, ["Ada"]);
44 | });
45 | });
46 | }
47 |
--------------------------------------------------------------------------------
/test/foundation/kt/collections/map/maps_get_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:kart/kart.dart';
2 | import 'package:test/test.dart';
3 |
4 | void main() {
5 | group('map getOrElse test', () {
6 | test("map getOrElse Expected NotDefaultValue", () {
7 | var map = {
8 | "test1": 1,
9 | "test2": 2,
10 | };
11 | var result = map.getOrElse("test1", () => 3);
12 |
13 | expect(result, 1);
14 | });
15 |
16 | test("map getOrElse Expected defaultValue", () {
17 | var map = {
18 | "test1": 1,
19 | "test2": 2,
20 | };
21 | var result = map.getOrElse("test3", () => 3);
22 |
23 | expect(result, 3);
24 | });
25 | });
26 | }
27 |
--------------------------------------------------------------------------------
/test/foundation/kt/collections/map/nullable_map_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:kart/kart.dart';
2 | import 'package:test/test.dart';
3 |
4 | void main() {
5 | group('orEmpty', () {
6 | test(" given map is null || return empty map", () {
7 | Map? map;
8 | var result = map.orEmpty();
9 |
10 | expect(result, {});
11 | });
12 |
13 | test(" given map is null || return empty map", () {
14 | Map? map = {"lan": "dart"};
15 | var result = map.orEmpty();
16 |
17 | expect(result, {"lan": "dart"});
18 | });
19 | });
20 | }
21 |
--------------------------------------------------------------------------------
/test/foundation/kt/standard/standart_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:kart/kart.dart';
2 | import 'package:test/test.dart';
3 |
4 | void main() {
5 | group('Standard test', () {
6 | test("takeIf", () {
7 | String test = "takIf";
8 |
9 | var result = test.takeIf((self) => self == "takIf");
10 | expect(result, "takIf");
11 |
12 | var result2 = test.takeIf((p0) => p0 == "takeIf2");
13 | expect(result2, null);
14 | });
15 |
16 | test("takeUnless PredicateTrue ExpectString", () {
17 | String test = "James";
18 |
19 | var result = test.takeUnless((self) => self == "Tom");
20 | expect(result, "James");
21 | });
22 |
23 | test("takeUnless PredicateFalse ExpectNull", () {
24 | String test = "James";
25 | var result = test.takeUnless((self) => self == "James");
26 | expect(result, null);
27 | });
28 |
29 | test("repeat", () {
30 | var finalIndex = -1;
31 | repeat(10, (index) => finalIndex = index);
32 | expect(finalIndex, 9);
33 | });
34 |
35 | test("let without?Operator Expect 1", () {
36 | String? str;
37 | var result = str.let((self) {
38 | return 111;
39 | });
40 | expect(result, 111);
41 | });
42 |
43 | test("let notNull", () {
44 | String? str = "mapped";
45 | var result = str.let((self) {
46 | return self.isNotEmpty;
47 | });
48 | expect(result, true);
49 | });
50 | });
51 | }
52 |
--------------------------------------------------------------------------------
/test/kart_test.dart:
--------------------------------------------------------------------------------
1 | void main() {}
2 |
--------------------------------------------------------------------------------
/test/pair/pair_test.dart:
--------------------------------------------------------------------------------
1 | import 'package:kart/kart.dart';
2 | import 'package:test/test.dart';
3 |
4 | void main() {
5 | group('pair test', () {
6 | test("pair element check", () {
7 | var first = "first";
8 | var second = 1;
9 | var result = pairOf(first, second);
10 | expect("first", result.first);
11 | expect(1, result.second);
12 | });
13 |
14 | test("pair equal", () {
15 | var pair1 = pairOf("first", 2);
16 | var pair2 = pairOf("first", 2);
17 |
18 | assert(pair1 == pair2);
19 | });
20 | });
21 | }
22 |
--------------------------------------------------------------------------------
/test/test_helper.dart:
--------------------------------------------------------------------------------
1 | class ClassForTest {
2 | final String name;
3 |
4 | ClassForTest(this.name);
5 | }
6 |
--------------------------------------------------------------------------------