diff --git a/packages/music_repository/.gitignore b/packages/music_repository/.gitignore new file mode 100644 index 0000000..06ef8e6 --- /dev/null +++ b/packages/music_repository/.gitignore @@ -0,0 +1,44 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# VSCode related +.vscode/* + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.packages +.pub-cache/ +.pub/ +/build/ +pubspec.lock + +# Web related +lib/generated_plugin_registrant.dart + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Test related +coverage \ No newline at end of file diff --git a/packages/music_repository/README.md b/packages/music_repository/README.md new file mode 100644 index 0000000..cd4fc71 --- /dev/null +++ b/packages/music_repository/README.md @@ -0,0 +1,67 @@ +# Music Repository + +[![style: very good analysis][very_good_analysis_badge]][very_good_analysis_link] +[![Powered by Mason](https://img.shields.io/endpoint?url=https%3A%2F%2Ftinyurl.com%2Fmason-badge)](https://github.com/felangel/mason) +[![License: MIT][license_badge]][license_link] + +Repository of music tracks + +## Installation ๐Ÿ’ป + +**โ— In order to start using Music Repository you must have the [Flutter SDK][flutter_install_link] installed on your machine.** + +Install via `flutter pub add`: + +```sh +dart pub add music_repository +``` + +--- + +## Continuous Integration ๐Ÿค– + +Music Repository comes with a built-in [GitHub Actions workflow][github_actions_link] powered by [Very Good Workflows][very_good_workflows_link] but you can also add your preferred CI/CD solution. + +Out of the box, on each pull request and push, the CI `formats`, `lints`, and `tests` the code. This ensures the code remains consistent and behaves correctly as you add functionality or make changes. The project uses [Very Good Analysis][very_good_analysis_link] for a strict set of analysis options used by our team. Code coverage is enforced using the [Very Good Workflows][very_good_coverage_link]. + +--- + +## Running Tests ๐Ÿงช + +For first time users, install the [very_good_cli][very_good_cli_link]: + +```sh +dart pub global activate very_good_cli +``` + +To run all unit tests: + +```sh +very_good test --coverage +``` + +To view the generated coverage report you can use [lcov](https://github.com/linux-test-project/lcov). + +```sh +# Generate Coverage Report +genhtml coverage/lcov.info -o coverage/ + +# Open Coverage Report +open coverage/index.html +``` + +[flutter_install_link]: https://docs.flutter.dev/get-started/install +[github_actions_link]: https://docs.github.com/en/actions/learn-github-actions +[license_badge]: https://img.shields.io/badge/license-MIT-blue.svg +[license_link]: https://opensource.org/licenses/MIT +[logo_black]: https://raw.githubusercontent.com/VGVentures/very_good_brand/main/styles/README/vgv_logo_black.png#gh-light-mode-only +[logo_white]: https://raw.githubusercontent.com/VGVentures/very_good_brand/main/styles/README/vgv_logo_white.png#gh-dark-mode-only +[mason_link]: https://github.com/felangel/mason +[very_good_analysis_badge]: https://img.shields.io/badge/style-very_good_analysis-B22C89.svg +[very_good_analysis_link]: https://pub.dev/packages/very_good_analysis +[very_good_cli_link]: https://pub.dev/packages/very_good_cli +[very_good_coverage_link]: https://github.com/marketplace/actions/very-good-coverage +[very_good_ventures_link]: https://verygood.ventures +[very_good_ventures_link_light]: https://verygood.ventures#gh-light-mode-only +[very_good_ventures_link_dark]: https://verygood.ventures#gh-dark-mode-only +[very_good_workflows_link]: https://github.com/VeryGoodOpenSource/very_good_workflows diff --git a/packages/music_repository/analysis_options.yaml b/packages/music_repository/analysis_options.yaml new file mode 100644 index 0000000..bb72091 --- /dev/null +++ b/packages/music_repository/analysis_options.yaml @@ -0,0 +1 @@ +include: package:very_good_analysis/analysis_options.6.0.0.yaml diff --git a/packages/music_repository/coverage_badge.svg b/packages/music_repository/coverage_badge.svg new file mode 100644 index 0000000..499e98c --- /dev/null +++ b/packages/music_repository/coverage_badge.svg @@ -0,0 +1,20 @@ + + + + + + + + + + + + + + + coverage + coverage + 100% + 100% + + diff --git a/packages/music_repository/lib/gen/assets.gen.dart b/packages/music_repository/lib/gen/assets.gen.dart new file mode 100644 index 0000000..6d00ba5 --- /dev/null +++ b/packages/music_repository/lib/gen/assets.gen.dart @@ -0,0 +1,44 @@ +/// GENERATED CODE - DO NOT MODIFY BY HAND +/// ***************************************************** +/// FlutterGen +/// ***************************************************** + +// coverage:ignore-file +// ignore_for_file: type=lint +// ignore_for_file: directives_ordering,unnecessary_import,implicit_dynamic_list_literal,deprecated_member_use + +class $LibGen { + const $LibGen(); + + /// Directory path: lib/tracks + $LibTracksGen get tracks => const $LibTracksGen(); +} + +class $LibTracksGen { + const $LibTracksGen(); + + /// File path: lib/tracks/Arpent.mp3 + String get arpent => 'lib/tracks/Arpent.mp3'; + + /// File path: lib/tracks/Groovin.mp3 + String get groovin => 'lib/tracks/Groovin.mp3'; + + /// File path: lib/tracks/Motions.mp3 + String get motions => 'lib/tracks/Motions.mp3'; + + /// File path: lib/tracks/Trip Up North.mp3 + String get tripUpNorth => 'lib/tracks/Trip Up North.mp3'; + + /// File path: lib/tracks/Windy Old Weather.mp3 + String get windyOldWeather => 'lib/tracks/Windy Old Weather.mp3'; + + /// List of all assets + List get values => + [arpent, groovin, motions, tripUpNorth, windyOldWeather]; +} + +class Assets { + Assets._(); + + static const $LibGen lib = $LibGen(); +} diff --git a/packages/music_repository/lib/music_repository.dart b/packages/music_repository/lib/music_repository.dart new file mode 100644 index 0000000..d217fd1 --- /dev/null +++ b/packages/music_repository/lib/music_repository.dart @@ -0,0 +1,5 @@ +/// Repository of music tracks +library; + +export 'src/model/model.dart'; +export 'src/music_repository.dart'; diff --git a/packages/music_repository/lib/src/model/model.dart b/packages/music_repository/lib/src/model/model.dart new file mode 100644 index 0000000..f193f60 --- /dev/null +++ b/packages/music_repository/lib/src/model/model.dart @@ -0,0 +1 @@ +export 'music_track.dart'; diff --git a/packages/music_repository/lib/src/model/music_track.dart b/packages/music_repository/lib/src/model/music_track.dart new file mode 100644 index 0000000..c82a455 --- /dev/null +++ b/packages/music_repository/lib/src/model/music_track.dart @@ -0,0 +1,29 @@ +import 'package:equatable/equatable.dart'; + +/// {@template music_track} +/// Contains information about a music track. +/// {@endtemplate} +class MusicTrack extends Equatable { + /// {@macro music_track} + const MusicTrack({ + required this.index, + required this.title, + required this.artist, + required this.path, + }); + + /// The index of the track in the playlist. + final int index; + + /// The title of the track. + final String title; + + /// The author of the track. + final String artist; + + /// The path to the track file. + final String path; + + @override + List get props => [index, title, artist, path]; +} diff --git a/packages/music_repository/lib/src/music_repository.dart b/packages/music_repository/lib/src/music_repository.dart new file mode 100644 index 0000000..733e69c --- /dev/null +++ b/packages/music_repository/lib/src/music_repository.dart @@ -0,0 +1,48 @@ +import 'package:music_repository/gen/assets.gen.dart'; +import 'package:music_repository/music_repository.dart'; + +/// {@template music_repository} +/// Repository of music tracks +/// {@endtemplate} +class MusicRepository { + /// {@macro music_repository} + MusicRepository(); + + /// Returns the list of available music tracks. + List getTracks() { + const basePath = 'packages/music_repository/'; + final tracks = Assets.lib.tracks; + return [ + MusicTrack( + index: 0, + title: 'Arpent', + artist: 'Kevin MacLead', + path: basePath + tracks.arpent, + ), + MusicTrack( + index: 1, + title: 'Groovin', + artist: 'Bryan Boyko', + path: basePath + tracks.groovin, + ), + MusicTrack( + index: 2, + title: 'Motions', + artist: 'Rafael Krux', + path: basePath + tracks.motions, + ), + MusicTrack( + index: 3, + title: 'Trip Up North', + artist: 'Bryan Teoh', + path: basePath + tracks.tripUpNorth, + ), + MusicTrack( + index: 4, + title: 'Windy Old Weather', + artist: 'Kevin MacLead', + path: basePath + tracks.windyOldWeather, + ), + ]; + } +} diff --git a/packages/music_repository/lib/tracks/Arpent.mp3 b/packages/music_repository/lib/tracks/Arpent.mp3 new file mode 100644 index 0000000..1da1aec Binary files /dev/null and b/packages/music_repository/lib/tracks/Arpent.mp3 differ diff --git a/packages/music_repository/lib/tracks/Groovin.mp3 b/packages/music_repository/lib/tracks/Groovin.mp3 new file mode 100644 index 0000000..3031bb6 Binary files /dev/null and b/packages/music_repository/lib/tracks/Groovin.mp3 differ diff --git a/packages/music_repository/lib/tracks/Motions.mp3 b/packages/music_repository/lib/tracks/Motions.mp3 new file mode 100644 index 0000000..68a2737 Binary files /dev/null and b/packages/music_repository/lib/tracks/Motions.mp3 differ diff --git a/packages/music_repository/lib/tracks/Trip Up North.mp3 b/packages/music_repository/lib/tracks/Trip Up North.mp3 new file mode 100644 index 0000000..f17f622 Binary files /dev/null and b/packages/music_repository/lib/tracks/Trip Up North.mp3 differ diff --git a/packages/music_repository/lib/tracks/Windy Old Weather.mp3 b/packages/music_repository/lib/tracks/Windy Old Weather.mp3 new file mode 100644 index 0000000..05f0eea Binary files /dev/null and b/packages/music_repository/lib/tracks/Windy Old Weather.mp3 differ diff --git a/packages/music_repository/pubspec.yaml b/packages/music_repository/pubspec.yaml new file mode 100644 index 0000000..384236f --- /dev/null +++ b/packages/music_repository/pubspec.yaml @@ -0,0 +1,26 @@ +name: music_repository +description: Repository of music tracks +version: 0.1.0+1 +publish_to: none + +environment: + sdk: ^3.4.0 + flutter: ^3.22.0 + +dependencies: + equatable: ^2.0.5 + flutter: + sdk: flutter + just_audio: ^0.9.37 + +dev_dependencies: + build_runner: ^2.4.11 + flutter_gen_runner: ^5.6.0 + flutter_test: + sdk: flutter + mocktail: ^1.0.4 + very_good_analysis: ^6.0.0 + +flutter: + assets: + - lib/tracks/ \ No newline at end of file diff --git a/packages/music_repository/test/src/model/music_track_test.dart b/packages/music_repository/test/src/model/music_track_test.dart new file mode 100644 index 0000000..6bc58f6 --- /dev/null +++ b/packages/music_repository/test/src/model/music_track_test.dart @@ -0,0 +1,46 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter_test/flutter_test.dart'; +import 'package:music_repository/music_repository.dart'; + +void main() { + group('MusicTrack', () { + group('supports instance comparison', () { + test('with equal instances', () { + expect( + MusicTrack( + index: 0, + title: 'title', + artist: 'artist', + path: 'path', + ), + MusicTrack( + index: 0, + title: 'title', + artist: 'artist', + path: 'path', + ), + ); + }); + + test('with non-equal instances', () { + expect( + MusicTrack( + index: 0, + title: 'title', + artist: 'artist', + path: 'path', + ), + isNot( + MusicTrack( + index: 1, + title: 'title1', + artist: 'artist1', + path: 'path1', + ), + ), + ); + }); + }); + }); +} diff --git a/packages/music_repository/test/src/music_repository_test.dart b/packages/music_repository/test/src/music_repository_test.dart new file mode 100644 index 0000000..e43152b --- /dev/null +++ b/packages/music_repository/test/src/music_repository_test.dart @@ -0,0 +1,16 @@ +// ignore_for_file: prefer_const_constructors + +import 'package:flutter_test/flutter_test.dart'; +import 'package:music_repository/music_repository.dart'; + +void main() { + group('MusicRepository', () { + test('can be instantiated', () { + expect(MusicRepository(), isNotNull); + }); + + test('getTracks returns a list of [MusicTrack]', () { + expect(MusicRepository().getTracks(), isA>()); + }); + }); +}